読者です 読者をやめる 読者になる 読者になる

リア充爆発日記

You don't even know what ria-ju really is.

Androidのインテントのまとめメモ

http://developer.android.com/guide/components/intents-filters.htmlのまとめメモ。

Intent周りはノリでやってたけど、ブロードキャスト実装をやってたら、ちゃんと仕様を抑えないとキツくなってきたので。。

  • アクティビティ、サービス、ブロードキャストレシーバのAndroid3大コア要素はインテントによって起動される。
  • Context.startActivity()やActivity.startActivityForResult()にインテントを渡すことによって、新たなアクティビティを起動したり、既存のアクティビティに新しいことをさせたりする。
  • Context.startService()にインテントを渡すことによって、サービスを開始したり、既存のサービスに新しい指示を出すことができる。Context.bindService()も結果として同様のことができる。
  • Context.sendBroadcast()などのブロードキャストメソッドインテントを渡すことによって、関連したすべてのブロードキャストレシーバにインテントを配信することができる。
  • これらの仕組みは独立しており、例えばブロードキャストしたインテントがアクティビティに渡されるようなことはない。
  • インテントは基本的に以下のものを含む
    • コンポーネント名(Component name)
      • オプショナル。設定されていれば指定クラスのインスタンスに渡される。
    • アクション(Action)
      • String型の実行されるべきアクションを表したもの。もしくはブロードキャストの場合は、起こったできごとのレポートを表したもの。
      • 予め定義されたものがたくさんあるが、自分で定義することもできる。
    • データ(Data)
      • 使用されるデータのURIとそのMIMEタイプ※本体内データだとcontent:とか画像だとimage/jpegとか
    • カテゴリ(Category)
    • エキストラ(Extras)
      • Key-Valueで設定できる追加データ。
    • フラグ(Flags)
      • いろんなフラグ。アクティビティの起動方法とか、起動後どうするか(ヒストリに残すか)?とか。
  • 暗黙的インテントの受け渡しにはインテントフィルタを使う。
    • フィルタは目的に応じて別個に設定する。例えばノートパッドアプリで言えば、新規にメモを起こすフィルタ、既存のメモを起動するフィルタ、など。
  • インテントフィルタは、インテントオブジェクトのアクション、データ、カテゴリの3つのフィールドに対応したフィールドを持つ。
  • 暗黙的インテントでは、それぞれのフィールドがすべてチェックされ、1つでもパスしなかったらそのインテントコンポーネントには渡されない。
    • 全部のフィールドを記載しなければいけないわけじゃない。どこかのフィールドが記載ない場合、記載しない場合の挙動に応じて結果が決まる。
  • フィルタは複数設定できるので、1つのフィルタが通らなくても別のフィルタで通ればコンポーネントに渡される。
    • アクションチェックでは、インテントに1つアクションが設定されたら、フィルタは必ず1つ以上のアクションを指定しなければならない。でなければ、すべてのインテントはブロックされる。
      • インテントとフィルタがアクションを指定しないと、どうなるか?
        • フィルタがアクションを指定していない場合は、すべてのインテントがブロックされる
        • インテントにアクションが設定されてないと全部のアクションチェックをパスする(フィルタに最低1つのアクションが指定されていれば)
    • カテゴリチェックでは、基本的にはカテゴリが設定されていないインテントは常にカテゴリチェックを通る。
      • が、1つ注意しないといけないのは、システムはインテントに"android.intent.category.DEFAULT" が設定されているものとみなしてstartActivity()に渡してしまう。ので、暗黙的インテントを受け取りたいアクティビティは"android.intent.category.DEFAULT" が必要。(ServiceとかBroadcastレシーバだったら全部通らないってことかな??)
      • ちなみにAPIに定義されている定数と"android.intent.category.DEFAULT" のような文字列記述方式は対応がとれてて、manifestファイルには定数は使わず、文字列のほうを使う。"android.intent.category.DEFAULT" == CATEGORY_DEFAULT
    • データチェックではアクションやカテゴリのようにインテントフィルタの子要素として指定できる。要素複数設定できるし、0の場合もある。
      • ではURIMIME typeを指定する。URLは"scheme://host:port/path"の構成となっていて、パーツごとにそれぞれ指定する。
      • 例えば"content://com.example.project:200/folder/subfolder/etc"というURIがあったとき、schemeは"content"、hostは"com.example.project"、postは"200"、pathは"folder/subfolder/etc"となる。また、hostとportを合わせてauthorityという。
      • 上記のそれぞれの要素はオプションだが、下位の要素を指定するなら、その上位の要素指定しなければいけない。(schemeだけはOKだけどpathだけはNG)
      • インテントにいくらURIが設定されていても、フィルタで設定された部分しか評価されない。例えばフィルタでschemeだけ指定されているのなら、インテントで設定されているURIscheme部分のみ一致すればあとの部分は考慮されない。ちなみにpathにはワイルドカード(*)が使える。
      • typeにMIME typeを指定する。typeも"text/*"のようにワイルドカードが使える。
      • データチェックの評価ルールは以下
        • インテントURIMIMEも持たない場合は、フィルタも両方持たない場合のみチェックをパスする。
        • インテントURIだけ持ち、MIMEを持たない場合(かつ、MIMEURIから推定されない場合)は、フィルタにマッチするURIが設定されており、MIMEが設定されいない場合のみチェックをパスする。これはmailto:とかtel:のような実データを参照しないようなもののみで発生するケース。
        • インテントURIは持たず、MIMEのみを持つ場合、フィルタもマッチするMIMEが記載され、URIの記載がない場合のみチェックをパスする。
        • インテントURIMIMEも持つ場合は、フィルタもそれぞれマッチするものが記載されている場合はチェックをパスする。もしくはインテントURIがcontent:かfile:の場合は、フィルタにURIの指定がなくてもMIMEがマッチすればチェックをパスする。つまり、フィルタでURIの記載をしないと、content:とfile:をサポートするコンポーネントだと推定される。