Intentを使ったアクティビティ間の移動
メインアクティビティから他のアクティビティへジャンプ
明示的Intentを使用します。
空のアクティビティを追加し、名前をAddCourseActivityにします。「レイアウトファイルを生成」にチェックを入れます。
ただし、「Launcher Activity」のチェックは外してください。
Intent
IntentはAndroidアプリ内の各コンポーネントがやり取りするための重要な手段です。
現在のコンポーネントが実行したい動作を指定したり、異なるコンポーネント間でデータを渡すこともできます。
Intentには「明示的Intent」と「暗黙的Intent」の2種類があります
Intentには複数のコンストラクタがあります。
メインアクティビティのボタン上でIntentをインスタンス化し、メインから第2のアクティビティへジャンプさせます。
// まずIntentを初期化し、どこからどこへいくかを指定
Intent it = new Intent(FirstActivity.this, AddCourseActivity.class);
startActivity(it);Code language: JavaScript (javascript)
暗黙的Intentの使い方
明示的Intentと比べて、暗黙的Intentはどのアクティビティを起動するかを直接指定する必要はありません。代わりに、より抽象的なactionとcategoryを指定します。
その後、システムがこのIntentを解析し、起動可能なアクティビティを探してくれます。
AndroidManifest.xmlを修正します。
第2のアクティビティにactionとcategoryを追加します。
actionでは、このアクティビティがこのアクションに応答できることを示します。
<activity android:name=".AddCourseActivity">
<intent-filter>
<action android:name="com.foxdevelop.www.activitydemo.ACTION_START" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>Code language: HTML, XML (xml)
Intentがアクティビティのactionとcategoryに一致して初めて、そのアクティビティはIntentに応答できます。
// Intentを初期化し、AndroidManifest.xml内の対応するactionにマッチさせる
Intent it = new Intent("com.foxdevelop.www.activitydemo.ACTION_START");
startActivity(it);Code language: JavaScript (javascript)
なぜcategoryをマッチさせる必要がないのか
このアクティビティはandroid.intent.category.DEFAULTを使用しているからです。
これはデフォルト値です。
startActivityを呼び出すと、自動的にDEFAULTが渡されます。
各Intentは1つのactionしか指定できませんが、複数のcategoryを指定できます。
現在はDEFAULTなので、追加する必要はありません。
他のcategoryを追加する必要がある場合:
// Intentを初期化してactionにマッチさせ、同時にcategoryを追加
Intent it = new Intent("com.foxdevelop.www.activitydemo.ACTION_START");
it.addCategory("com.foxdevelop.www.activitydemo.MY_CATEGORY");
it.addCategory("com.foxdevelop.www.activitydemo.MY_CATEGORY1111111");
startActivity(it);Code language: JavaScript (javascript)
「コース追加」メニューをクリックすると、アプリがエラーで停止しました。
理由は、intentにcategoryを追加したのに、第2のアクティビティ側にそのcategoryが宣言されていないためです。
そのため、このcategoryを追加する必要があります。
<activity android:name=".AddCourseActivity">
<intent-filter>
<action android:name="com.foxdevelop.www.activitydemo.ACTION_START" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="com.foxdevelop.www.activitydemo.MY_CATEGORY" />
</intent-filter>
</activity>Code language: HTML, XML (xml)
注意:
Intentに複数のcategoryがある場合、1つでも一致すればよいというわけではなく、すべてのcategoryが一致しなければなりません。
<activity android:name=".AddCourseActivity">
<intent-filter>
<action android:name="com.foxdevelop.www.activitydemo.ACTION_START" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="com.foxdevelop.www.activitydemo.MY_CATEGORY" />
</intent-filter>
</activity>Code language: HTML, XML (xml)
case R.id.add:
// Intentを初期化してactionにマッチさせ、同時にcategoryを追加
Intent it = new Intent("com.foxdevelop.www.activitydemo.ACTION_START");
it.addCategory("com.foxdevelop.www.activitydemo.MY_CATEGORY2222222");
//it.addCategory("android.intent.category.DEFAULT");
startActivity(it);
break;Code language: JavaScript (javascript)
暗黙的IntentでWebページを開く
暗黙的Intentには他にも多くの機能があります。
同じアプリ内のアクティビティを起動するだけでなく、他のアプリのアクティビティも起動できます。
これにより、複数のアプリ間での機能共有が可能になります。
例えば、WeChatで友達から住所が送られてきたとき、QQブラウザで開くことができます。
以下で試してみましょう:
Intent it = new Intent(Intent.ACTION_VIEW); // システム組み込みのAction
it.setData(Uri.parse("http://www.foxdevelop.com")); // URLを開く
startActivity(it);Code language: JavaScript (javascript)
http://は省略できません。省略するとエラーになります。
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.foxdevelop.www.activitydemo, PID: 8917
android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.VIEW dat=www.foxdevelop.com }
at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1809)
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1523)
at android.app.Activity.startActivityForResult(Activity.java:4224)
at android.support.v4.app.BaseFragmentActivityApi16.startActivityForResult(BaseFragmentActivityApi16.java:54)
at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:68)Code language: PHP (php)
暗黙的Intentで電話をかける
telプロトコルを使って電話をかけることができます
前回の授業ではhttpプロトコルを使ってドメインを開きました。
例えば、以下で10010に電話をかけてみます。

Intent it = new Intent(Intent.ACTION_DIAL); // システム組み込みのAction
it.setData(Uri.parse("tel:10010")); // この番号をダイヤル(ユーザーの確認が必要)
startActivity(it);Code language: JavaScript (javascript)
アクティビティ間でデータを渡す
Intentでデータを渡せます
intent 英[ɪnˈtent] 美[ɪnˈtɛnt] 意図、目的;意味、内容。
putExtraメソッドを使ってデータを渡します。
そして第2のアクティビティで、getStringExtraメソッドを呼び出して渡されたデータを取得できます。
第2のアクティビティではgetIntentメソッドを呼んでIntentを取得します。
もちろん、整数を渡した場合はgetIntExtraメソッドで取得できます。
まず第1のアクティビティで:
Intent it = new Intent(FirstActivity.this, AddCourseActivity.class);
it.putExtra("site", "www.foxdevelop.com");
it.putExtra("name", "FoxDevelop");
startActivity(it);Code language: JavaScript (javascript)
次に第2のアクティビティでIntentオブジェクトを取得し、その中の値を取り出します。
第2のアクティビティのonCreateメソッド内で:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_course_acticity);
Intent it = getIntent();
String site = it.getStringExtra("site");
String name = it.getStringExtra("name");
int version = it.getIntExtra("version", 1);
Log.e(TAG, site);
}Code language: JavaScript (javascript)
前のアクティビティにデータを返す
現在のアクティビティを終了するとき
アクティビティにはstartActivityForResultメソッドがあり、アクティビティが破棄される前に前のアクティビティへ結果を返すことができます。
このメソッドは2つのパラメータを受け取ります。1つ目はIntent、2つ目はリクエストコードで、後でコールバック内でデータの送信元を判別するために使います。
アクティビティが破棄される前に、setResultメソッドを使って前のアクティビティに結果を返します。通常はRESULT_OKまたはRESULT_CANCELEDを使い、2つ目のパラメータにはデータを含んだIntentを渡します。
IntentにputExtraを使って値をセットできます。
前のアクティビティでstartActivityForResultを使って第2のアクティビティを起動したため、第2のアクティビティが破棄されると、第1のアクティビティのonActivityResultメソッドが呼び出されます。ここでIntentと結果コードを取得できます。
ユーザーがボタンを押して戻るのではなく、バックキーで戻った場合は、第2のアクティビティでonBackPressedメソッドをオーバーライドする必要があります。
1. 第1のアクティビティでIntentを起動するとき
Intent it = new Intent(FirstActivity.this, AddCourseActivity.class);
it.putExtra("site", "www.foxdevelop.com");
it.putExtra("name", "FoxDevelop");
it.putExtra("version", 1);
startActivityForResult(it, 1);Code language: JavaScript (javascript)
2. 第1のアクティビティでオーバーライド
public class FirstActivity extends AppCompatActivity {
private static final String TAG = "FirstActivity";
// 第1のアクティビティのメソッドをオーバーライド。第2のアクティビティが終了すると実行される
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
String h = data.getStringExtra("hot");
Log.d(TAG, h);
}
super.onActivityResult(requestCode, resultCode, data);
}Code language: JavaScript (javascript)
3. 第2のアクティビティで
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_course_acticity);
// 前のアクティビティからデータを取得
Intent it = getIntent();
String site = it.getStringExtra("site");
String name = it.getStringExtra("name");
int version = it.getIntExtra("version", 1);
Log.e(TAG, site);
// ボタンに戻るイベントを追加。イベント内でIntentに値をセットし、結果コードを設定して終了する
Button b = findViewById(R.id.button);
b.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent it = getIntent();
it.putExtra("hot", "人気コース");
setResult(RESULT_OK, it);
finish();
}
});
}Code language: JavaScript (javascript)
メインアクティビティに戻ると、イベントが発生してログが出力されます。
05-12 06:17:46.741 12960-12960/com.foxdevelop.www.activitydemo D/FirstActivity: 人気コース
バックキーでもデータを返したい場合
onBackPressedをオーバーライドする必要があります。
第2のアクティビティでオーバーライドします:
// このメソッドはバックキーが押されたときに呼び出される
@Override
public void onBackPressed() {
Intent it = getIntent();
it.putExtra("hot", "最新コース");
setResult(RESULT_OK, it);
finish();
}Code language: JavaScript (javascript)
05-12 06:23:08.654 13209-13209/com.foxdevelop.www.activitydemo D/FirstActivity: 人気コース
05-12 06:23:16.405 13209-13209/com.foxdevelop.www.activitydemo D/FirstActivity: 最新コース
05-12 06:23:35.612 13209-13209/com.foxdevelop.www.activitydemo D/FirstActivity: 最新コース