Androidアプリの4大要素とインテント 暗黙的なIntent【Android TIPS】

この記事は2013年4月18日に書かれたものです。内容が古い可能性がありますのでご注意ください。


1
Androidアプリの4大要素とインテント
インテント(暗黙的なIntent)
この節では”暗黙的なIntent”を紹介します。暗黙的なIntentはIntentの送り元オブジェクトと送り先オブジェクトを疎結合にするための仕組みです。また、アプリの一部の機能を他のアプリに任せるといった動作も可能になり、アプリ開発の手間を削減することが可能になります。
Intentの基本情報と補足情報
暗黙的なIntentとは、宛先のオブジェクトを明示的に指定していないインテントのことです。
Intentのパラメータに起動する宛先オブジェクト(Activity、Service、BroadcastReceiver)をある程度推測できる情報を設定しておくと、Androidシステムが該当するオブジェクトをシステム全体から検索し起動する仕組みです。
インテントの送信元が送信先相手を直接知っていなくても送ることができるため、オブジェクト同士を疎結合にすることができます。
単一の宛先だけでなく複数の宛先にIntentを送ることも可能で、このことをインテントのブロードキャストと呼びます。

Intentは以下の情報から構成されています。

分類 名称 説明
基本情報 アクション インテントが期待しているふるまいや、インテントが知らせたい事柄
データ インテントの取り扱い方に関する情報
補足情報 カテゴリ アクションに対する追加情報
付加情報 他のオブジェクトと受け渡しする情報
タイプ データの形式
フラグ アクティビティの起動方法



● アクション

アクションの役割は、他の情報(特にデータと付加情報)がどのような構造となっているかを決定することです。インテントの持つ情報の中でもっとも基本的なものです。
アクションは、送り先のコンポーネントの種類によってアクティビティアクションとブロードキャストアクションに分類することができます。

  ● アクティビティアクション
    ⇒他のアクティビティを起動する際に設定されるアクション
  ● ブロードキャストアクション
    ⇒イベントが発生したことを多数のオブジェクトに知らせる際に設定されるアクションで、ブロードキャストレシーバーを起動することができる。

ブロードキャストアクションが設定されたIntentには、Androidシステムから発せられるものが存在します。
代表的な例としては、「バッテリー残量が残り少ない」「システムの起動が完了した」等があり、これらのIntentを受け取る仕組みを作っておくことで「バッテリー残量が残り少なくなったら、システムリソースを解放する」や「システムの起動が完了したら、自動的に起動する」などのアプリを作成することが可能になります。

アクションはIntentオブジェクトに文字列として設定します。
この文字列はIntentクラスの定数として定義済みのものが多数用意されており、例えば、Intent.ACTION_BATTERY_LOW(電池残量が残り少ないことを表すアクション)という定数には「”android.intent.action.BATTERY_LOW”」という文字列が定義されています。

 

Intentクラスに定義済みのアクションには以下のようなものがあります。

アクション アクション定数 内容
アクティビティ ACTION_VIEW データを参照する
ACTION_CALL 通話を開始する
ACTION_EDIT データを編集する
ACTION_MAIN 初期アクティビティとして開始する(アプリケーションのエントリーポイントとなる)
ACTION_SYNC デバイスとサーバー間のデータ同期を行う
ブロードキャスト ACTION_BATTERY_LOW バッテリー残量が残り少ない
ACTION_HEADSET_PLUG ヘッドセットが接続された、もしくは外された
ACTION_SCREEN_ON スクリーンがONになった
ACTION_TIMEZONE_CHANGED タイムゾーンの設定が変更された

定義済みのアクション以外にも独自のアクションを定義することも可能です。
その場合、文字列として定義する値は、Javaのパッケージ名などから命名することが推奨されています

 

● データ
データはIntentが取り扱う情報ををandroid.net.Uriクラスとして表現したものです。
このUriクラスはjava.net.URIクラスをAndroid用にラッピングしたクラスで、RFCで規定されているURI表現を取り扱うこのとのできるクラスです。

※RFC※
Request for Commentsはインターネットに関する技術標準を定める団体であるIETFが正式に発行する文書のことです。
インターネットで利用されるプロトコルやその他のインターネットに関するさまざまな技術仕様が公開されています。

 

データの例としては、以下のようなものがあります。
  ● http://www.example.com/index.html
  ● file://usr/local/bin/hoge
  ● mailto:foo@example.com

Intentに設定されたアクションとデータの組み合わせによって、どのような挙動となるか(どのActivityが起動するか)が決まります。
以下の表は、定義済みアクション「ACTION_VIEW」がデータ種類の違いによってどのように処理されるかを示したものです。

アクション データ 処理内容
ACTION_VIEW http://www.google.com/ ブラウザを起動する
tel:0388889999 ダイアラーを起動する
geo:0,0?q=Tokyo マップを起動する
file:///sdcard/song.mp3 音楽プレイヤーを起動する



同じアクションが設定されていても、データ種類によって起動するアプリが変わっている点に注目してください。

暗黙的なIntent
暗黙的なIntentに用いるIntentオブジェクトを作成するには、下記3つのコンストラクタのうちのどれかを使用します。

コンストラクタ 処理内容
Intent() 空のインテントを作成する
Intent(String action) アクションを指定してインテントを作成する
Intent(String action, Uri uri) アクションとデータ(Uri)を指定してインテントを作成する



1つ目のコンストラクタはアクションもデータも指定せずにIntentオブジェクトを作成します。
一般的にはこの後に別途メソッドを用いて、アクションやデータを設定することになるでしょう。

2つ目のコンストラクタはアクションのみを指定してIntentオブジェクトを作成します。
データが必要のない場合などはこのコンストラクタを用いてもよいでしょう。

3つ目もコンストラクタはアクションとデータを指定してIntentオブジェクトを作成します。
必要があれば、付加情報などを設定しますが基本的にはそのままIntentを発行することができます。

 

以下はIntentクラスの主なメソッドです。
このようなメソッドを使い、Intentオブジェクトに必要な情報を設定します。(putExtra()メソッドに関しては、明示的Intentで紹介済みです。)

戻り値 メソッド 処理内容
Intent setAction(String action) インテントにアクションを設定する
Intent setData(Uri data) インテントにデータ(Uri)を設定する
Intent setType(String type) インテントにタイプを設定する
Intent putExtra(String name, String value) インテントの付加情報に要素を追加する
第2引数に基本データ型をとるメソッドもオーバーロードされている。
Intent setType(String type) インテントにカテゴリを付加する



では、実際の使用例を見てみましょう。
JPEGファイルを送信するためのActivityを起動するサンプルプログラムです。

Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND);
intent.setType("image/jpeg");
intent.putExtra(Intent.EXTRA_STREAM, Uri.parse("/mnt/sdcard/image.jpg"));
startActivity(intent);

startActivity()メソッドの引数にIntentオブジェクトを渡し、Activityを起動している点は明示的なIntentによるアプリ内画面遷移と変わりありません。
しかし、引数のIntentオブジェクトに設定されている情報を見ると、アクション・タイプ・付加情報のみです。起動するActivityクラスを指定していませんね。
つまり、このIntentオブジェクトを発した側(画面遷移元)では、Intentオブジェクトの受取り側(画面遷移先)がどんなクラスか全くわからないということです。

 

この処理が実行されると、AndroidシステムはIntentに付与されている基本情報と補足情報を元に、Intentを受け取ることのできるActivityを自分の端末内から探し、そのActivityを起動します。
この際、受取り側のActivityに複数の候補があった場合は、ユーザーへどのActivityを起動するかの選択を促すダイアログを表示します。逆に、Activityが見つからない場合は、その旨が表示され画面遷移に失敗することになります。

起動すべきActivityクラスに複数の候補があった場合は以下のような画面が表示されます。

 

なお、Activityの起動にはstartActivity()を、Serviceの起動にはstartService()を、BroadcastReceiverの起動にはsendBroadcast()を使用します。これらのメソッドはContextクラスに定義されているため、Activityクラスから使用することができます。

startActivity (Intent intent)
startService (Intent service)
sendBroadcast (Intent intent)

暗黙的なIntentで起動することができる主なアプリには以下のようなものがあります。

アプリケーション アクション URLの例
Webブラウザ Intent.ACTION_VIEW(android.intent.action.VIEW) 「http://」「https://」で始まるURL形式
電話(ただちに電話をかける) Intent.ACTION_CALL(android.intent.action.CALL) 「tel:電話番号」
電話(電話をかけるActivityを起動) Intent.ACTION_DIAL(android.intent.action.DIAL)
Intent.ACTION_VIEW(android.intent.action.VIEW)
「tel:電話番号」
地図 Intent.ACTION_VIEW(android.intent.action.VIEW) 「geo:緯度,経度」
メール送信 Intent. ACTION_SEND(android.intent.action.SEND) 「mailto:foo@example.com」
 

Webブラウザを起動する例

Uri uri = Uri.parse("http://www.google.com");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);

 

ただちに電話をかける例

Uri uri = Uri.parse("tel:09012345678");
Intent intent = new Intent(Intent.ACTION_CALL, uri);
startActivity(intent);

※Intent.ACTION_CALLを利用するには、“android.permission.CALL_PHONE”パーミッションが必要です。

 

電話アプリを起動する例

Uri uri = Uri.parse("tel:09012345678");
Intent intent = new Intent(Intent.ACTION_DIAL, uri);
startActivity(intent);

 

マップアプリを起動する例

Uri uri = Uri.parse("geo:0,0");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);

 

メールアプリを起動する例

Uri uri = Uri.parse("mailto:foo@example.com");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);

暗黙的なIntentを用いたサンプルプログラム
暗黙的なIntentを用いたアプリを作ってみましょう。
EditTextにURLを入力しブラウザ起動をクリックすると、別アプリのブラウザが起動するアプリです。

 

”res/layout/activity_main.xml”

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <EditText
        android:id="@+id/editText1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="http://www.google.co.jp/" />

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="ブラウザ起動" />

</LinearLayout>

LinearLyaoutの子要素として、2つのViewが定義されています。URLを入力するための入力フィールド”EditText”と、”Button”が1つです。
どちらもJavaプログラム側から参照する必要があるので、”android:id”を設定しています。

 

”src/com.example.intent/MainActivity.java”

package com.example.implicitintent;
// 省略
public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button button1 = (Button)findViewById(R.id.button1);
        button1.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                EditText editText1 = (EditText)findViewById(R.id.editText1);
                String text = editText1.getText().toString();
                Uri uri = Uri.parse(text);

                Intent intent = new Intent(Intent.ACTION_VIEW, uri);
                startActivity(intent);
            }
        });
    }
}

Buttonをクリックされたときの処理は14から21行目となります。
EditTextから入力されているデータを取得し、Uriオブジェクトに変換しています。その後、Intentをインスタンス化、startActivity()メソッドの呼び出しを順に行っています。

このアプリにはブラウザ機能を持たせていないというところが、ポイントですね。
 

  • このエントリーをはてなブックマークに追加

PAGE TOP