Intent

ええとイマサラですが、Android Hacks のインテント入門の項について確認しております。その中でも特に_インテントフィルタ_の項にあるサンプルについて、実際に動作を確認してみましたので、備忘録という事でメモ。
いくつかソースを引用しつつ、中身の意図を確認してみます。とりあえず Manifest から。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="jp.shuri.android.ifs"
      android:versionCode="1"
      android:versionName="1.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".IntentActivity"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".FilterActivity"
                  android:label="@string/app_name">
            <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" />
            </intent-filter>
        </activity>
    </application>
</manifest> 

インテントフィルタに着目すると IntentActivity の中で定義されている intent-filter な要素については、

            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

となってて、これは

  • このアプリのトップレベルなエントリである事を示していて
  • action.MAIN な action はメインなエントリポイントである事を示し
  • category.LAUNCHER な category はランチャにインストールされてるアプリである事を示し
    • てか、ランチャにインストール可能らしい

ているそうな。起動時に表示される Activity にこの intent-filter がナニされる模様。
で、次の FilterActivity の intent-filter が以下。

            <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" />
            </intent-filter>

上記のフィルタは action が action.VIEW で data の scheme が http という事で category の指定が intent に無かった場合、DEFAULT なのか BROWSABLE なのかを決めかねる、って事でユーザにどっちか選べ、って選択ダイアログが出てくる、って理解で良いのかどうか。
一応ココには

  • action
  • data (both URI and data type)
  • category

の三つで決めるけんね、と書いてある (はず)。あと選択ダイアログに表示されるソレが activity の label 属性になってる模様。
あとは VIEW な intent を投げてる箇所が出てくるはずなのでそちらで。

レイアウト

以下二つです。一つはボタンが二つあるソレ (main.xml)。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<Button
    android:id="@+id/button1"
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="@string/button1"
    />
<Button
    android:id="@+id/button2"
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="@string/button2"
    />
</LinearLayout>

もう一つは TextView が一つあるナニ (filter.xml)。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<TextView
    android:id="@+id/textview"
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    />
</LinearLayout>

あと、res/values/strings.xml も以下に。

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="hello">Hello World, IntentActivity!</string>
    <string name="app_name">IntentFilterSample</string>
    <string name="button1">明示的 Intent</string>
    <string name="button2">暗黙的 Intent</string>
</resources>

Activity です。まず、IntentActivity の定義から。

package jp.shuri.android.ifs;

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class IntentActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        Button btn = (Button)findViewById(R.id.button1);
        btn.setOnClickListener(new OnClickListener() {

	    @Override
            public void onClick(View v) {
                Intent i = new Intent();
                i.setClassName("com.android.browser", 
                               "com.android.browser.BrowserActivity");
                startActivity(i);
            }
        	
        });
        
        btn = (Button)findViewById(R.id.button2);
        btn.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                Uri u = Uri.parse("http://www.google.co.jp");
                Intent i = new Intent();
                i.setAction(Intent.ACTION_VIEW);
                i.setData(u);
                startActivity(i);
            }
        });
    }
}

ボタンが二つ。一つは明示的インテントによってブラウザを表示させてます。もう一つは Intent.ACTION_VIEW な action で http な scheme のソレを data として保持している暗黙的なインテントを使っています。
で、メニューから DEFAULT なソレが選択された場合、以下な Activity (FilterActivity) が起動されます。

package jp.shuri.android.ifs;

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

public class FilterActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.filter);
        if(!getIntent().getAction().equals(Intent.ACTION_MAIN)){
            Uri u = getIntent().getData();
            TextView tv = (TextView)findViewById(R.id.textview);
            tv.setText(u.toString());
        }
    }
}

こちら、MAIN な action で起動されなかった (暗黙的なインテントで起動された) 場合に、インテントからデータを取り出して TextView に設定しております。

とりあえず

これを元にしてスライドを作ってみます。とりあえずココに zipped な Android プロジェクトを置いてます。入り用の方は遠慮なくどうぞ。