Android -暗黙的インテント-
暗黙的インテントの動作原理
暗黙的インテントは、次に遷移するアクティビティやサービスを明確に指定せず、 暗黙的に指定して、別のアクティビティやサービスに連携します。
呼び出される側のアプリケーションの「AndroidManifest.xml」には、インテントフィルタという、 暗黙的インテントで呼び出すための条件をあらかじめ設定しておきます。
呼び出す側のアプリケーションは、インテントに呼び出したいアプリケーションの条件を指定して、 Androidシステムに依頼をかけます。
条件に合うインテントフィルタを持つアプリケーションが複数ある場合は、それらのアプリケーション から選択できるように選択ダイアログをAndroidシステムが表示し、ユーザがその中から、選択すると対象の アプリケーションが起動する仕組みになっています。
インテントフィルタの設定
暗黙インテントで呼び出されるようにするには、呼び出される側のアプリケーションの 「AndroidManifest.xml」にインテントフィルタを設定しておくことが必要です。
呼び出すアプリケーションは、インテントフィルタに設定した条件でインテントを生成して、対象のアプリケーションを 呼び出すことができます。
インテントフィルタの設定は、対象のactivityタグの中にintent-filterタグを設定します。
intent-filterタグの中には、以下の3種類のタグを設定します。
actionタグ
actionタグには、android:name属性に大まかな動作の指定を行います。
通常は、Android標準で用意されているクラスの定数を利用しますが、独自で設定することも可能です。
定数名 | 説明 | actionタグの設定値 |
---|---|---|
ACTION_MAIN | アプリケーション起動時のアクションです。。 通常、最初に起動するアクティビティに対して設定します。 |
android.intent.action.MAIN |
ACTION_VIEW | データの画面に表示するアクションです。 | android.intent.action.VIEW |
ACTION_DEFAULT | ACTION_VIEWの別名 | android.intent.action.VIEW |
ACTION_CALL | データを元に電話をかけるアクションです。 | android.intent.action.CALL |
ACTION_DIAL | 電話をかける画面を表示するアクションです。 | android.intent.action.DIAL |
ACTION_RUN | データを実行するアクションです。 | android.intent.action.RUN |
ACTION_EDIT | ユーザ編集のデータを表示するアクションです。 | android.intent.action.EDIT |
categoryタグ
categoryタグには、android:name属性にアクションの追加情報を指定します。
通常は、Android標準で用意されているクラスの定数を利用しますが、独自で設定することも可能です。
定数名 | 説明 | categoryタグの設定値 |
---|---|---|
CATEGORY_DEFAULT | 標準のカテゴリです。 | android.intent.category .DEFAULT |
CATEGORY_BROWSABLE | ブラウザから安全に起動することが可能であることを示すカテゴリです。 | android.intent.category .BROWSABLE |
CATEGORY_HOME | 端末が起動された時に最初に起動されるものであることを示すカテゴリです。 | android.intent.category .HOME |
CATEGORY_LAUNCHER | ホームのアイコンから起動可能であることを示すカテゴリです。 | android.intent.category .LAUNCHER |
CATEGORY_ALTERNATIVE | ユーザが現在参照している(フォーカスがあたっている)データに対し、代替できる動作が可能であることを示すカテゴリです。 | android.intent.category .ALTERNATIVE |
CATEGORY_SELECTED _ALTERNATIVE |
ユーザがメニュー一覧などから選択したデータに対し、代替できる動作が可能であることを示すカテゴリです。 | android.intent.category .SELECTED_ALTERNATIVE |
dataタグ
dataタグには、URIの設定を行います。
このタグの属性は、複数あり、URIのスキームの部分やホスト名の部分など、それぞれを設定します。
属性名 | 説明 |
---|---|
android:scheme | URIのスキームを指定します。最低限必要な属性です。 |
android:host | URIのホストを指定します。 |
android:port | URIのポート番号を指定します。 android:schemeとandroid:host属性の設定が必須です。 |
android:path | URIのパスの部分 インテントオブジェクトでのフルパスと合致するはフルパスを指定します。 |
android:pathPrefix | URIのパスの部分 インテントオブジェクトでのパスの最初の部分のみに合致するパスの一部を指定します。 |
android:pathPattern | URIのパスの部分 インテントオブジェクトでの完全なパスに合致する完全なパス指定しますが、以下のワイルドカードを含めることができます。 |
android:mimeType | image/jpeg や audio/mpeg4-generic といった MIME メディアタイプを指定します。 |
1.暗黙的インテントサンプル(標準装備のアプリ)
標準で用意されているアプリケーションを呼び出すサンプルです。
Mapを利用するため、作成時のTargetは、Google APIsを 選択します。
インテントを作成・URI指定をして、startActivityメソッドで呼び出します。
IntentEx1
res/layout/main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#ffffff"
android:orientation="vertical">
<Button
android:id="@+id/daial"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="ダイアル" />
<Button
android:id="@+id/contact"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="連絡先" />
<Button
android:id="@+id/map"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="地図" />
<Button
android:id="@+id/internet"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="インターネット" />
</LinearLayout>
IntentEx1.java
import android.app.Activity;
import android.content.ContentUris;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class IntentEx1 extends Activity implements OnClickListener {
public static final int[] BUTTONS = { R.id.daial, R.id.contact, R.id.map,
R.id.internet };
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
for (int btnId : BUTTONS) {
Button btn = (Button) findViewById(btnId);
btn.setOnClickListener(this);
}
}
@Override
public void onClick(View v) {
// ダイアルボタン押下時
if (v.getId() == R.id.daial) {
// インテントの生成
Intent intent = new Intent("android.intent.action.DIAL",
Uri.parse("tel:1234567890"));
/*-------------------------------------------
インテントの生成(定数名で指定する場合)
Intent intent=
new Intent(Intent.ACTION_DIAL,Uri.parse("tel:1234567890"));
--------------------------------------------*/
// 次のアクティビティの起動
startActivity(intent);
// 連絡先ボタン押下時
} else if (v.getId() == R.id.contact) {
// 連絡先の1番
Uri uri = ContentUris.withAppendedId(
ContactsContract.Contacts.CONTENT_URI, 1);
// インテントの生成
Intent intent = new Intent("android.intent.action.EDIT", uri);
/*-------------------------------------------
インテントの生成(定数名で指定する場合)
Intent intent = new Intent(Intent.ACTION_EDIT,uri);
--------------------------------------------*/
// 次のアクティビティの起動
startActivity(intent);
// 地図ボタン押下時
} else if (v.getId() == R.id.map) {
// インテントの生成
Intent intent = new Intent("android.intent.action.VIEW",
Uri.parse("geo:0,0 ?q=Fukuoka"));
/* ------------------------------------------
インテントの生成(定数名で指定する場合)
Intent intent =
new Intent(Intent.ACTION_VIEW,Uri.parse("geo:0,0 ?q=Fukuoka"));
---------------------------------------------*/
// 次のアクティビティの起動
startActivity(intent);
// インターネットボタン押下時
} else if (v.getId() == R.id.internet) {
// インテントの生成
Intent intent = new Intent("android.intent.action.VIEW",
Uri.parse("http://www.google.com/"));
/* ------------------------------------------
インテントの生成(定数名で指定する場合)
Intent intent =
new Intent(Intent.ACTION_VIEW,Uri.parse("http://www.google.com/"));
---------------------------------------------*/
// 次のアクティビティの起動
startActivity(intent);
}
}
}
2.暗黙的インテントサンプル(自作のアプリの呼び出し)
自作アプリケーション(ImageView表示)2つを暗黙的インテントで呼び出すサンプルです。
呼び出されるアプリ1(Rose)
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="info.mito.rose"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="8" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:name=".RoseActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="sample" />
<data android:host="flower_all" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="sample" />
<data android:host="flower" />
<data android:pathPrefix="/rose" />
</intent-filter>
</activity>
</application>
</manifest>
※ ピンクの部分を追加します。
res/layout/rose.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:layout_weight="1"
android:src="@drawable/rose" />
<TextView
android:id="@+id/text_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_weight="1" />
<Button
android:id="@+id/back_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="20dp"
android:text="戻る" />
</LinearLayout>
RoseActivity.java
import android.app.Activity;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class RoseActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.rose);
// URI取得
Uri uri = getIntent().getData();
if (uri != null) {
// URIのQueryString情報取得
String flowerName = uri.getQueryParameter("selection_item");
TextView name = (TextView) findViewById(R.id.text_name);
name.setText(flowerName);
}
Button btn = (Button) findViewById(R.id.back_btn);
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// アクティビティ終了
finish();
}
});
}
}
呼び出されるアプリ2(Tulip)
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="info.mito.tulip"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="8" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:name=".TulipActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="sample" />
<data android:host="flower_all" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="sample" />
<data android:host="flower" />
<data android:pathPrefix="/tulip" />
</intent-filter>
</activity>
</application>
</manifest>
※ ピンクの部分を追加します。
res/layout/tulip.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:layout_weight="1"
android:src="@drawable/tulip" />
<TextView
android:id="@+id/text_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_weight="1" />
<Button
android:id="@+id/back_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="20dp"
android:text="戻る" />
</LinearLayout>
TulipActivity.java
import android.app.Activity;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class TulipActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tulip);
// URI取得
Uri uri = getIntent().getData();
if (uri != null) {
// URIのQueryString情報取得
String flowerName = uri.getQueryParameter("selection_item");
TextView name = (TextView) findViewById(R.id.text_name);
name.setText(flowerName);
}
Button btn = (Button) findViewById(R.id.back_btn);
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// アクティビティ終了
finish();
}
});
}
}
呼び出し元のアプリケーション(IntentEx2)
res/values/string.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Hello World, IntentEx2!</string>
<string name="app_name">IntentEx2</string>
<string-array name="flowers">
<item>Rose</item>
<item>Tulip</item>
<item>All</item>
</string-array>
</resources>
res/layout/main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ListView
android:id="@+id/flower_list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:entries="@array/flowers" >
</ListView>
</LinearLayout>
IntentEx2.java
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
public class IntentEx2 extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// ListViewオブジェクト取得
ListView listView = (ListView) findViewById(R.id.flower_list);
// ListViewオブジェクトにリスナ指定
listView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// ListViewオブジェクトの取得
ListView listView = (ListView) parent;
// 選択された値取得
String item = (String) listView.getItemAtPosition(position);
// インテントの生成
Intent intent = new Intent(Intent.ACTION_VIEW);
// URI設定
String strUri = "";
if (item.equals("Rose")) {
strUri = "sample://flower/rose?selection_item=" + item;
} else if (item.equals("Tulip")) {
strUri = "sample://flower/tulip?selection_item=" + item;
} else {
strUri = "sample://flower_all?selection_item=ALL";
}
Uri uri = Uri.parse(strUri);
// URIをインテントに設定
intent.setData(uri);
// 次のアクティビティ起動
startActivity(intent);
}
});
}
}