marunomaruno-memo

marunomaruno-memo

[Android] インテント (1) - インテントを使ったアクティビティの呼び出し

2012年03月08日 | Android
[Android] インテント (1) - インテントを使ったアクティビティの呼び出し
================================================================================

インテントは、プログラムの実行に関する情報を管理するメッセージである。
プログラムの実行時に、実行に関する情報がインテントというメッセージにまとめられる。
このインテントを発行することで、プログラムを実行させることができる。また、逆に、
プログラムには、自身が受け取れるインテントの種類を記述できる。

インテントは、つぎの主要な情報によって構成している。
・アクション        動作
・カテゴリー        インテントに対する追加のメタデータ
・データ            インテントに与えるデータで、URI として表現
・エクストラ        Bundle 型のインテントに渡されるデータ
・フラグ            アクティビティの起動方法
・タイプ            MIME タイプ(操作したいリソースの種類)
・コンポーネント    インテントを利用するパッケージやクラスを明示的に指定

アクションとカテゴリーは単なる文字列で表現している。
データは Uri オブジェクトで定義する。Uri オブジェクトは、RFC3986 で定義された 
URI である。


インテントには、メッセージの送信先の指定方法によって、次の 2 つの種類がある。

・明示的インテント

メッセージを送る相手のプログラムのクラス名を直接指定する

・暗示的(暗黙的)インテント

相手のプログラムにさせたいこと(アクション)、そのときに必要なデータを指定すること
で、システムが自動的にプログラムを指定する。暗黙的インテントで、アクティビティが
インテントを受け取るためには、つぎの暗黙的なルーティング 3 つの条件をすべて満た
している必要がある。

コンストラクターとしては、以下のようなものがある。
 Intent(String action) 
 Intent(String action, Uri uri) 

また、メソッドで設定するには、以下のものがある。

Intent  setAction(String action) 

Intent  setData(Uri data) 
Intent  setDataAndType(Uri data, String type) 

Intent  setType(String type) 
Intent  putExtra(String name, 型 value) 
Intent  putExtra(String name, 型[] value) 


暗黙的なルーティング
・アクティビティは指定されたアクションをサポートする
・MIME タイプが指定されている場合、アクティビティはそれをサポートする
・アクティビティはインテントで指定されたカテゴリーをすべてサポートする


インテントの起動は、Activity クラスの
    startActivity(インテント)
を使う。また、結果を受け取りたい場合は、
    startActivityForResult(インテント, リクエスト・コード)
を使う。また、結果は、
    onActivityResult(int requestCode, int resultCode, Intent data)
をオーバーライドする。
呼び出された側のアクティビティでは、戻りコードは、
    setResult(戻りコード, インテント);
を使って設定する。


アクションとデータの例
------------------- --------------------------- --------------------------------
アクション          データ                      動作
------------------- --------------------------- --------------------------------
ACTION_VIEW         http://アドレス             ブラウザーで指定するURL
                    content://contacts/people/  内臓の電話帳を表示
                    geo:軽度,緯度               地図を表示
                    geo:0,0?q=住所              地図を表示
ACTION_CALL         tel://電話番号              電話をかける
ACTION_DIAL         tel://電話番号              ダイヤル画面を表示
ACTION_EDIT         URI                         URIで示されるアドレス長を編集
ACTION_WEB_SEARCH   検索文字列                  ブラウザーを開き、Googleで検索
------------------- --------------------------- --------------------------------

Intents and Intent Filters
http://developer.android.com/intl/ja/guide/topics/intents/intents-filters.html

ソフトウェア技術ドキュメントを勝手に翻訳 
Android 開発ガイド > フレームワークトピック > 4. インテントとインテントフィルタ
https://sites.google.com/a/techdoctranslator.com/jp/android/guide/intents-filters


■ 呼び出す側

同じアプリケーション内で、画面を切り替えるサンプル。
画面はアクティビティ・オブジェクトなので、ある画面から別の画面に切り替えるのに、
このインテントを使って行う。


▲ アクティビティ

テキスト・フィールドから取得した文字列を、つぎの画面に渡す。
このとき、つぎの画面の起動方法として、明示的にインテントを指定する方法と、暗黙的
にインテントを指定する 2 つの方法を使っている。

□ Intent01Activity.java
---
package jp.marunomaruno.android.intent;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;

public class Intent01Activity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }

    /**
     * 明示的にインテントを起動する。
     * 
     * @param view
     */
    public void onClickExplisitButton(View view) {
        EditText edit1 = (EditText) findViewById(R.id.editText1);

        Intent intent = new Intent(this, OtherActivity.class);    // (1)
        intent.putExtra("message", edit1.getText());    // (2)
        startActivity(intent);    // (3)
    }

    /**
     * 暗黙的にインテントを起動する。
     * 
     * @param view
     */
    public void onClickImplisitButton(View view) {
        EditText edit1 = (EditText) findViewById(R.id.editText1);

        Intent intent = new Intent(Intent.ACTION_SEND);    // (4)
        intent.putExtra("message", edit1.getText());
        startActivity(intent);
    }
}
---

(1) 明示的にインテント・オブジェクトを生成する

コンテキストとクラスを明示的に指定してインテント・オブジェクトを生成する。

    Intent intent = new Intent(this, OtherActivity.class);    // (1)


明示的にインテント・オブジェクトを生成するコンストラクター
---
Intent(Context packageContext, Class<?> cls) 
---

または、空のインテント・オブジェクトを作って、つぎのメソッドでクラスを設定する。
---
Intent  setClass(Context packageContext, Class<?> cls) 
Intent  setClassName(Context packageContext, String className) 
Intent  setClassName(String packageName, String className) 
---

自分のアプリケーションでないものなどは、3 番目のメソッドを利用して指定することも
できる。たとえば、ブラウザーなどはつぎのように指定することができる。
    setClassName("com.android.browser", "com.android.browser.BrowserActivity")


(2) 渡すデータを設定する

Uri オブジェクト以外のデータは、つぎのように、putExtra() メソッドを利用して、つ
ぎのアクティビティに渡すことができる。

putExtra() の第 1 引数には、渡すデータを意味する文字列。

    intent.putExtra("message", edit1.getText());    // (2)

データの取得側では、この "message" をキーとして、データを取得する。
なお、汎用のキーとして、Intent クラスの定数に、EXTRA_xxx という形でキーが用意さ
れているので、それを使うこともできる。


・Extra データ設定関係のメソッド(スカラーのもののみ)
---
Intent     putExtra(String name, boolean value)
Intent     putExtra(String name, byte value)
Intent     putExtra(String name, double value)
Intent     putExtra(String name, char value)
Intent     putExtra(String name, int value)
Intent     putExtra(String name, float value)
Intent     putExtra(String name, long value)
Intent     putExtra(String name, short value)
Intent     putExtra(String name, CharSequence value)
Intent     putExtra(String name, String value)
Intent     putExtra(String name, Serializable value)
---


(3) アクティビティを起動する

startActivity() メソッドにより、つぎのアクティビティを起動する。

    startActivity(intent);    // (3)

なお、指定されたアクティビティがない場合、
android.content.ActivityNotFoundException
がスローされる。


(4) 暗黙的にインテント・オブジェクトを生成する

何をするべきものなのかというアクションを指定して、インテント・オブジェクトを生成
する。

    Intent intent = new Intent(Intent.ACTION_SEND);    // (4)


暗黙的にインテント・オブジェクトを生成するコンストラクター
---
Intent(String action) 
Intent(String action, Uri uri) 
---


▲ レイアウト

明示的と暗黙的にインテントを起動するボタン。

□ 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" >

    <TextView
        android:id="@+id/text1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text=""
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <EditText
        android:id="@+id/editText1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <requestFocus />
    </EditText>

    <Button
        android:id="@+id/explisitButton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="onClickExplisitButton"
        android:text="@string/explicitButtonLabel" />

    <Button
        android:id="@+id/implisitButton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="onClickImplisitButton"
        android:text="@string/implicitButtonLabel" />
</LinearLayout>
---


■ 呼び出される側

▲ 呼び出されるアクティビティのクラス

これは、単に渡されたデータをテキスト・ビューに設定して表示するだけのプログラム。

□ OtherActivity.java
---
package jp.marunomaruno.android.intent;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;

public class OtherActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.other);

        Intent intent = getIntent();        // (1)
        TextView text1 = (TextView) findViewById(R.id.otherTextView1);
        text1.setText(intent.getCharSequenceExtra("message").toString()); // (2)
    }
}
---

(1) インテントを取得する

    Intent intent = getIntent();        // (1)


(2) データを取得する

putExtra(String, CharSequence) で設定したデータは、getCharSequenceExtra(String) 
で取得する。

    text1.setText(intent.getCharSequenceExtra("message").toString());    // (2)


・Extra データ設定関係のメソッド(スカラーのもののみ)
---
boolean       getBooleanExtra(String name, boolean defaultValue)
byte          getByteExtra(String name, byte defaultValue)
char          getCharExtra(String name, char defaultValue)
double        getDoubleExtra(String name, double defaultValue)
float         getFloatExtra(String name, float defaultValue)
int           getIntExtra(String name, int defaultValue)
long          getLongExtra(String name, long defaultValue)
short         getShortExtra(String name, short defaultValue)
CharSequence  getCharSequenceExtra(String name)
String        getStringExtra(String name)
Serializable  getSerializableExtra(String name)
---


▲ レイアウト

main のアクティビティから受け取った文字列を表示するだけのレイアウト。

□ res/layout/other.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" >

    <TextView
        android:id="@+id/otherTextView1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text=""
        android:textAppearance="?android:attr/textAppearanceLarge" />

</LinearLayout>
---


■ Intent クラス

java.lang.Object 
   +  android.content.Intent 

プログラムの実行に関する情報を管理するメッセージのクラス。

・アクティビティ関係の標準アクション
---
ACTION_MAIN           メインプログラムの起動
ACTION_VIEW           ユーザーデータの表示
ACTION_ATTACH_DATA    添付データがついた
ACTION_EDIT           データの編集
ACTION_PICK           データからの取り出し
ACTION_CHOOSER        チューザーの表示
ACTION_GET_CONTENT    コンテントの取得
ACTION_DIAL           データをもとにダイアルする
ACTION_CALL           電話をかける
ACTION_SEND           データの送信
ACTION_SENDTO         メッセージの送信
ACTION_ANSWER         電話がかかってきた
ACTION_INSERT         指定のコンテナにデータを追加
ACTION_DELETE         データの削除
ACTION_RUN            データの実行
ACTION_SYNC           同期の開始
ACTION_PICK_ACTIVITY  アクティビティの選択
ACTION_SEARCH         検索
ACTION_WEB_SEARCH     Web 検索
ACTION_FACTORY_TEST   ファクトリーテスト用
---

・ブロードキャストの標準アクション
---
ACTION_TIME_TICK             現在の時刻が変更された
ACTION_TIME_CHANGED          時間が変更された
ACTION_TIMEZONE_CHANGED      タイムゾーンが変更された
ACTION_BOOT_COMPLETED        起動の完了
ACTION_PACKAGE_ADDED         パッケージの追加
ACTION_PACKAGE_CHANGED       パッケージの変更
ACTION_PACKAGE_REMOVED       パッケージの削除
ACTION_PACKAGE_RESTARTED     パッケージのリストア
ACTION_PACKAGE_DATA_CLEARED  パッケージ・データの初期化
ACTION_UID_REMOVED           ユーザーID の削除
ACTION_BATTERY_CHANGED       バッテリー状況の変更
ACTION_POWER_CONNECTED       電源接続
ACTION_POWER_DISCONNECTED    バッテリー起動への切替
ACTION_SHUTDOWN              シャットダウン
---

・主なカテゴリー
---
CATEGORY_DEFAULT     標準カテゴリ
CATEGORY_BROWSABLE   ブラウザから安全に起動することが可能
CATEGORY_TAB         TabActivity 内のタブ
CATEGORY_LAUNCHER    ホーム画面のアイコンから起動可能
CATEGORY_INFO        パッケージ情報が提供されている
CATEGORY_HOME        ホームスクリーンを表示する
CATEGORY_PREFERENCE  プリファレンスパネルがターゲット
CATEGORY_TEST        テストとして使用
---

・拡張データ
---
EXTRA_ALARM_COUNT 
EXTRA_BCC 
EXTRA_CC 
EXTRA_CHANGED_COMPONENT_NAME 
EXTRA_DATA_REMOVED 
EXTRA_DOCK_STATE 
EXTRA_DOCK_STATE_HE_DESK 
EXTRA_DOCK_STATE_LE_DESK 
EXTRA_DOCK_STATE_CAR 
EXTRA_DOCK_STATE_DESK 
EXTRA_DOCK_STATE_UNDOCKED 
EXTRA_DONT_KILL_APP 
EXTRA_EMAIL 
EXTRA_INITIAL_INTENTS 
EXTRA_INTENT 
EXTRA_KEY_EVENT 
EXTRA_PHONE_NUMBER 
EXTRA_REMOTE_INTENT_TOKEN 
EXTRA_REPLACING 
EXTRA_SHORTCUT_ICON 
EXTRA_SHORTCUT_ICON_RESOURCE 
EXTRA_SHORTCUT_INTENT 
EXTRA_STREAM 
EXTRA_SHORTCUT_NAME 
EXTRA_SUBJECT 
EXTRA_TEMPLATE 
EXTRA_TEXT 
EXTRA_TITLE 
EXTRA_UID 
---

・フラグ
---
FLAG_ACTIVITY_BROUGHT_TO_FRONT
FLAG_ACTIVITY_CLEAR_TASK 
FLAG_ACTIVITY_CLEAR_TOP 
FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET 
FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS 
FLAG_ACTIVITY_FORWARD_RESULT 
FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY 
FLAG_ACTIVITY_MULTIPLE_TASK 
FLAG_ACTIVITY_NEW_TASK 
FLAG_ACTIVITY_NO_ANIMATION 
FLAG_ACTIVITY_NO_HISTORY 
FLAG_ACTIVITY_NO_USER_ACTION 
FLAG_ACTIVITY_PREVIOUS_IS_TOP  
FLAG_ACTIVITY_REORDER_TO_FRONT 
FLAG_ACTIVITY_RESET_TASK_IF_NEEDED 
FLAG_ACTIVITY_SINGLE_TOP 
FLAG_ACTIVITY_TASK_ON_HOME 
FLAG_DEBUG_LOG_RESOLUTION 
FLAG_EXCLUDE_STOPPED_PACKAGES 
FLAG_FROM_BACKGROUND 
FLAG_GRANT_READ_URI_PERMISSION 
FLAG_GRANT_WRITE_URI_PERMISSION 
FLAG_INCLUDE_STOPPED_PACKAGES 
FLAG_RECEIVER_REGISTERED_ONLY 
FLAG_RECEIVER_REPLACE_PENDING 
---


・コンストラクタ-
---
Intent() 
Intent(Intent o) 
Intent(String action) 
Intent(String action, Uri uri) 
Intent(Context packageContext, Class<?> cls) 
Intent(String action, Uri uri, Context packageContext, Class<?> cls)  
---

・主なメソッド
---
Intent         addCategory(String category) 
Intent         addFlags(int flags) 
boolean        filterEquals(Intent other) 
int            filterHashCode() 
String         getAction() 

Set<String>    getCategories() 

ComponentName  getComponent() 
Uri            getData() 
String         getDataString() 

int            getFlags() 

static Intent  getIntent(String uri) 
static Intent  getIntentOld(String uri)  

String         getPackage() 

String         getScheme() 
Intent         getSelector() 

Rect           getSourceBounds() 
String         getType() 
boolean        hasCategory(String category) 
boolean        hasFileDescriptors() 
void           removeCategory(String category) 
void           removeExtra(String name) 
Intent         setAction(String action) 
Intent         setClass(Context packageContext, Class<?> cls) 
Intent         setClassName(Context packageContext, String className) 
Intent         setClassName(String packageName, String className) 
Intent         setComponent(ComponentName component) 
Intent         setData(Uri data) 
Intent         setDataAndType(Uri data, String type) 
Intent         setFlags(int flags) 
Intent         setPackage(String packageName) 
Intent         setType(String type) 
String         toUri(int flags) 
---


・Extra 関係のメソッド
---
xxx[]           getXxxArrayExtra(String name) 
xxx             getXxxExtra(String name, xxx defaultValue) 
    xxx: boolean, byte, char, double, float, int, long, short

ArrayList<Integer>  getIntegerArrayListExtra(String name) 

Yyy[]           getYyyArrayExtra(String name) 
ArrayList<Yyy>  getYyyArrayListExtra(String name) 
Yyy             getYyyExtra(String name) 
    Yyy: CharSequence, String

Parcelable[]                         getParcelableArrayExtra(String name) 
<T extends Parcelable> ArrayList<T>  getParcelableArrayListExtra(String name) 
<T extends Parcelable> T             getParcelableExtra(String name) 

Serializable    getSerializableExtra(String name) 

Bundle          getBundleExtra(String name) 
Bundle          getExtras() 

boolean         hasExtra(String name) 

Intent  putExtra(String name, xxx[] value) 
Intent  putExtra(String name, xxx value) 
    xxx: boolean, byte, char, double, float, int, long, short

Intent  putExtra(String name, Yyy value) 
Intent  putExtra(String name, Yyy[] value) 
Intent  putYyyArrayListExtra(String name, ArrayList<Yyy> value) 
    Yyy: CharSequence, String, Parcelable

Intent  putExtra(String name, Bundle value) 
Intent  putExtra(String name, Serializable value) 

Intent  putExtras(Intent src) 
Intent  putExtras(Bundle extras) 

Intent  putIntegerArrayListExtra(String name, ArrayList<Integer> value) 

Intent  replaceExtras(Bundle extras) 
Intent  replaceExtras(Intent src) 
---


■ マニュフェスト

マニフェストには、2 つのアクティビティ要素が記される。

□ AndroidManifest.xml
---
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="jp.marunomaruno.android.intent"
    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=".Intent01Activity"
            android:label="@string/app_name" >    <!-- (1) -->
            <intent-filter>    <!-- (2) -->
                <action android:name="android.intent.action.MAIN" /> <!-- (3) -->
                <category android:name="android.intent.category.LAUNCHER" />
                                                                    <!-- (4) -->
            </intent-filter>
        </activity>
        <activity
            android:name=".OtherActivity"
            android:label="other activity" >
            <intent-filter>
                <action android:name="android.intent.action.SEND" /> <!-- (5) -->
                <category android:name="android.intent.category.DEFAULT" />    
                                                                    <!-- (6) -->
            </intent-filter>
        </activity>
    </application>
</manifest>
---

(1) アクティビティ

    <activity
        android:name=".Intent01Activity"
        android:label="@string/app_name" >    <!-- (1) -->


(2) インテント・フィルター

このクラスがサポートするアクションやカテゴリーについて指定する。

    <intent-filter>    <!-- (2) -->

この要素の子要素として、つぎの要素が指定できる。
    action
    category
    data


(3)(5) アクション

Intent01Activity のアクションを「メインプログラムの起動」にする。これは、アプリ
ケーションが最初に表示するアクティビティを意味する。

    <action android:name="android.intent.action.MAIN" />    <!-- (3) -->


OtherActivity のアクションを「データの送信」にする。

    <action android:name="android.intent.action.SEND" />    <!-- (5) -->

指定できるアクションについては、上記の Intent クラスの定数を参考。
定数 ACTION_xxx の xxx 部分が
android.intent.action.XXX
になる。


(4)(6) カテゴリー

Intent01Activity のカテゴリーを「ランチャー」にする。これは、このアクティビティ
をランチャーで選択できるようにする。

    <category android:name="android.intent.category.LAUNCHER" />    <!-- (4) -->


OtherActivity のカテゴリーを「デフォルト」にする。

    <category android:name="android.intent.category.DEFAULT" />    <!-- (6) -->
      
指定できるカテゴリーについては、上記の Intent クラスの定数を参考。
定数 CATEGORY_xxx の xxx 部分が
android.intent.category.XXX
になる。


■ リソース

□ res/values/strings.xml
---
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">Intent01</string>
    <string name="explicitButtonLabel">明示的にインテントを起動</string>
    <string name="implicitButtonLabel">暗黙的にインテントを起動</string>
</resources>
---

                                                                            以上