Hatena::Groupandroid

lnzntの Android 日記 このページをアンテナに追加 RSSフィード

2012年04月08日(日)

暗黙的インテント

18:36 | 暗黙的インテント - lnzntの Android 日記 を含むブックマーク はてなブックマーク - 暗黙的インテント - lnzntの Android 日記 暗黙的インテント - lnzntの Android 日記 のブックマークコメント

Hello では startActivity() でアクティビティを起動する時にインテントを渡してました。

  startActivity(new Intent(HelloActivity.this, SubActivity.class));

このインテントは、起動するアクティビティを明示しているので、明示的インテントです。

これに対し、起動するアクティビティを明示しない暗黙的インテントがあります。

起動するアクティビティはシステムが適当に見繕ってくれます。

暗黙的インテントでブラウザを起動

では、暗黙的インテントでブラウザを起動するアプリを作ります。

Eclipse で [New] > [Project] で Android Project を選択してプロジェクトを作成します。Name は BrowserLauncher としました。

View には URI を表示する TextView とインテントを投げるトリガになる Button を設えます。

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:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/uri" 
        android:id="@+id/uri"/>  <!-- text を変更、id を追加 -->

    <!-- 以下の Button を追加 -->
    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/button1_label"
        android:onClick="launchBrowser"/>
</LinearLayout>

res/values/strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="uri">http://www.google.com/</string> <!-- 追加 -->
    <string name="app_name">BrowserLauncher</string>
    <string name="button1_label">Browse</string>       <!-- 追加 -->
</resources>

src/com.example/BrowserLauncherActivity.java にリスナーを追加します。

リスナーでは、TextView から URI を読み込んで、ACTION_VIEW が指定された暗黙的インテントにデータとして渡します。

package com.example;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;       // 追加
import android.widget.TextView; // 追加
import android.content.Intent;  // 追加
import android.net.Uri;         // 追加

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

    // 以下のリスナーを追加   
    public void launchBrowser(View v) {
    	TextView textView = (TextView)findViewById(R.id.uri);
    	Uri uri = Uri.parse((String)textView.getText());
    	startActivity(new Intent(Intent.ACTION_VIEW, uri));
    }     
}

以下が実行したとことです。「Browse」ボタンを押すとブラウザが起動して Google のページが表示されます。

f:id:lnznt:20120408192108j:image

f:id:lnznt:20120408192109j:image

アクティビティの選択

インテントには Action、Category、Data の要素があります。

アクティビティがどのようなインテントに反応するかはマニフェストファイルの intent-filter に記述します。

インテントにが起動すべきアクティビティに該当するものが複数ある場合は選択ダイアログが起動します。

では、もらった URI を表示するだけの疑似ブラウザを作ってインストールされている「ブラウザ」と同じインテントに反応するように登録して試してみます。

res/layout/dummy_browser.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:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/request_uri"
        android:id="@+id/request_uri"/>
</LinearLayout>

res/value/strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="uri">http://www.google.com/</string>
    <string name="app_name">BrowserLauncher</string>
    <string name="button1_label">Browse</string>
    <string name="request_uri">ここに URI が表示されます</string> <!- 追加 -> 
    <string name="dummy_browser">DummyBrowser</string>            <!- 追加 ->
</resources>

src/com.example/DummyBrowserActivity.java (新規作成)

package com.example;

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

public class DummyBrowserActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.dummy_browser);
        
        // 要求 URI (インテントのデータ) を表示する
        Intent intent		= getIntent();
    	Uri requestUri		= intent.getData();
    	TextView textView	= (TextView)findViewById(R.id.request_uri);
    	
    	textView.setText(requestUri.toString());

        //Log.v("DummyBrowser", "onCreate(): " + intent);
    }
}

DummyBrowserActivity を AndroidManifest.xml に登録します。

<!-- android:application 要素の子として以下を追加する -->
        <activity android:label="@string/dummy_browser" android:name="DummyBrowserActivity">
            <intent-filter>
                 <action android:name="android.intent.action.VIEW" />
                 <data android:scheme="http" />
                 <category android:name="android.intent.category.BROWSABLE"/>
                 <category android:name="android.intent.category.DEFAULT"/>
            </intent-filter>
        </activity>
    </application>

実行してみます。

「Browse」ボタンを押すと、今度はアクティビティの選択メニューがでます。

DummyBrowser を選ぶと上で作った疑似ブラウザが起動されます。

f:id:lnznt:20120408192108j:image

f:id:lnznt:20120408192110j:image

f:id:lnznt:20120408192111j:image

もちろん選択メニュー「ブラウザ」を選択すると既存のブラウザが起動されます。

----

ちなみに、DummyBrowser を削除して、既存のブラウザを無効(アンインストールできなかった)にして暗黙的インテントの投げ先がない状態で行なうと「Browse」ボタンを押したところで、問題が発生したため終了します、のメッセージが出てアプリが終了しました。