[Android その２] Androidのアプリケーションの基本要素

# Androidのアプリケーションの基本要素
Androidアプリケーションは、いくつかの基本要素(コンポーネント)から構成されています。これらのコンポーネントは、アプリの機能を提供し、ユーザーと対話する方法を定義します。以下に、Androidアプリケーションの基本要素を詳しく説明します。

## 1\. アクテビティ(Activity)
アクテビティは、AndroidアプリケーションアプリのUIを構成する基本的なコンポーネントで、アプリの単一の画面を表します。
各アクテビティは独自のライフサイクルを持ち、アプリ内の異なる機能や画面を管理します。
* __役割__ ：アクテビティはユーザーと直接対話し、ユーザーがアプリを使ってタスクを実行するための画面(UI)を提供します。
* __例__ ： メールアプリでは、受信トレイの表示画面が1つのアクテビティであり、メールを作成する画面が別のアクティビティです。
* __ライフサイクル__ ：アクティビティのライフサイクルには、onCreate(), onStart(), onResume(), onPause(), onStop(), onDestroy()などのメソッドが含まれ、アクティビティの生成から破棄までの状態を管理します。

##### 基本的なアクテビティのコード例：
```java
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // レイアウトリソースの設定
        setContentView(R.layout.activity_main);
    }

    @Override
    protected void onStart() {
        super.onStart();
        // アクティビティがユーザーに表示される直前の処理
    }

    @Override
    protected void onResume() {
        super.onResume();
        // アクティビティがユーザーと対話可能になる直前の処理
    }

    @Override
    protected void onPause() {
        super.onPause();
        // アクティビティが部分的に表示されなくなる直前の処理
    }

    @Override
    protected void onStop() {
        super.onStop();
        // アクティビティが完全に表示されなくなる直前の処理
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // アクティビティが破棄される直前の処理
    }
}
```


## 2\. サービス(Service)
サービスは、ユーザーインターフェースを持たず、バックグランドで長時間実行されるコンポーネントです。サービスは、アプリがフォアグランドで動作していない場合でも、バックグランドで継続的に動作を続けます。
* __役割__ ：サービスはバッグランドでの長時間にわたる操作を実行します。例えば、音楽の再生、データの同期、ネットワークリクエストの処理などがあげられます。
* __種類__ ：
    *  __Started Service __: 一度開始されると、バックグランドで動作し続ける。startService()で開始し、必要に応じて、stopSelf()またはstopService()で終了します。
    *  __Bound Service __:他のアプリケーションコンポーネント(通常はアクテビティ)にバインドされ、クライアントがバインドを解除するとサービスは停止します。

##### 基本的なサービスのコード例：
```java
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;

public class MyService extends Service {

    private static final String TAG = "MyService";

    @Override
    public void onCreate() {
        super.onCreate();
        // サービスが最初に作成されたときの処理
        Log.d(TAG, "Service Created");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // サービスが開始されたときの処理
        Log.d(TAG, "Service Started");
        // サービスが強制終了されたときに再起動するように設定
        return START_STICKY;
    }

    @Override
    public IBinder onBind(Intent intent) {
        // バインドサービスの場合の処理。バインドする必要がない場合は null を返す。
        return null;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        // サービスが破棄されるときの処理
        Log.d(TAG, "Service Destroyed");
    }
}

```
サービスを開始するには、以下のようにインテントを使用してサービスを開始します：
```java
Intent intent = new Intent(this, MyService.class);
startService(intent);
```

## 3\. コンテントプロバイダ(Content Provider)
コンテントプロパイダは、他のアプリケーションにデータ提供するためのメカニズムです。アプリ間でデータを共有
するために使用され、データベースやファイルシステム、ネットワークなどのリソースにアクセスします。
* __役割__ ：データの一貫性とセキュリティを保ちながら、複数のアプリが共通のデータにアクセスできるようにします。例えば、連絡先アプリや写真アプリがコンテントプロバイダを使用してデータを提供しています。
* __使用例__ ：連絡先データベースへのアクセス、外部アプリからのデータ共有、検索アプリからのデータ取得など。


##### 基本的なコンテントプロバイダのコード例:
```java
import android.content.ContentProvider;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;

public class MyContentProvider extends ContentProvider {

    @Override
    public boolean onCreate() {
        // コンテントプロバイダが初めて作成されるときの初期化
        return false;  // データベースの初期化が成功したかどうかを返す
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
        // データのクエリ処理
        return null;
    }

    @Override
    public String getType(Uri uri) {
        // URIに基づいてMIMEタイプを返す
        return null;
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        // データの挿入処理
        return null;
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        // データの削除処理
        return 0;
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        // データの更新処理
        return 0;
    }
}

```
このコンテンツプロバイダを使用するには、AndroidManifest.xmlに宣言する必要があります。
```xml
<provider
    android:name=".MyContentProvider"
    android:authorities="com.example.myapp.provider"
    android:exported="true" />
```

## 4\. ブロードキャストレシーバ(Broadcast Receiver)
ブロードキャストレシーバは、システム全体で発生するイベント(ブロードキャストメッセージ)をリッスンして受信するためのコンポーネントです。これらのイベントはシステムやほかのアプリケーションから送信されます。

* __役割__ ：システムイベントやカスタムイベントに反応し、適切なアクションを実行します。例えば、デバイスの充電状況の変化、ネットワーク接続の変更、SMSの受信などのイベントに対応できます。
* __例__ ：ブロードキャストレシーバを使って、アプリは充電開始の通知やWi-Fi接続の通知を受け取ることができます。これにより、特定の条件に基づいてアプリの動作を変えることができます。

##### 基本的なブロードキャストレシーバのコード例:
```java
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;

public class MyBroadcastReceiver extends BroadcastReceiver {

    private static final String TAG = "MyBroadcastReceiver";

    @Override
    public void onReceive(Context context, Intent intent) {
        // ブロードキャストを受信したときの処理
        Log.d(TAG, "Broadcast received: " + intent.getAction());
    }
}

```

ブロードキャストレシーバを使用するには、AndroidManifest.xmlに宣言するか、コードで登録します。
##### Manifestに宣言する方法:
```xml
<receiver android:name=".MyBroadcastReceiver">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
    </intent-filter>
</receiver>
```
##### コードで動的に登録する方法:
```java
MyBroadcastReceiver receiver = new MyBroadcastReceiver();
IntentFilter filter = new IntentFilter(Intent.ACTION_BOOT_COMPLETED);
registerReceiver(receiver, filter);
```
## 5\. フラグメント(Fragment)
フラグメントは、アクティビティの一部として動作する再利用可能なUIコンポーネントです。1つのアクティビティに複数のフラグメントを含めることができ、異なるレイアウトを持つことが可能です。フラグメントは、特に大画面(タブレット)で柔軟なＵＩ設計に有用です。
##### フラグメントの基本構造
フラグメントには、独自のライフサイクルメソッドがあります。主なライフサイクルメソッドには、onCreate(), onCreateView(), onActivityCreated(), onStart(), onResume(), onPause(), onStop(), onDestroyView(), onDestroy(), onDetach() があります。

##### 基本的なフラグメントのコード例:
```java
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class MyFragment extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // フラグメントのレイアウトを指定して表示する
        return inflater.inflate(R.layout.fragment_my, container, false);
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        // フラグメントビューの初期化
    }
}
```
フラグメントをアクティビティに追加するには、通常、XMLレイアウトファイルで指定するか、コードで動的に追加します。

##### フラグメントをXMLで追加する方法:
アクティビティのレイアウトXMLでフラグメントを指定することができます。
```xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <fragment
        android:id="@+id/fragment_container"
        android:name="com.example.MyFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</FrameLayout>
```
##### フラグメントをコードで動的に追加する方法:
フラグメントを動的に追加するには、FragmentManagerとFragmentTransactionを使用します。

```java
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

MyFragment fragment = new MyFragment();
fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.commit();

```


## 6\. インテント(Intent)
インテントは、アクティビティやサービスの起動、ブロードキャストの送信など、Androidコンポーネント間の通信を行うためのメッセージオブジェクトです。インテントには、データ（例：URI、アクション、カテゴリなど）を含めることができます。

##### インテントの基本的な使い方
インテントには主に2つの種類があります：
* __明示的インテント (Explicit Intent)__ ：特定のアクティビティやサービスを指定して起動します。
* __暗黙的インテント (Implicit Intent)__ ：実行するアクションを指定し、それに対応するコンポーネントをシステムが選択します。

###### 明示的インテントのコード例:
```java
// 明示的インテントを使用して、他のアクティビティを起動する
Intent intent = new Intent(this, AnotherActivity.class);
intent.putExtra("key", "value"); // データを渡す
startActivity(intent);

```
###### 暗黙的インテントのコード例:
```java
// 暗黙的インテントを使用して、共有アクションを起動する
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_TEXT, "これは共有するテキストです");

// アクティビティがインテントを処理できるか確認
if (intent.resolveActivity(getPackageManager()) != null) {
    startActivity(intent);
}

```
###### インテントを使ったデータの受け取り
起動されたアクティビティがデータを受け取る方法：
```java
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_another);

    // インテントからデータを受け取る
    Intent intent = getIntent();
    String value = intent.getStringExtra("key");
    // 取得したデータを使用
}
```
###### インテントフィルタの設定
インテントフィルタは、どのアクションに応答するかを指定するために使用されます。AndroidManifest.xmlで設定します。
```java
<activity android:name=".AnotherActivity">
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="http" android:host="www.example.com" />
    </intent-filter>
</activity>
```
この設定により、AnotherActivityは指定された条件（ここでは、特定のURLのhttpリクエスト）を処理できるようになります。