My Photo

« Androidアプリ開発メモ054:Intent その3:コマンドラインからAVDにIntentを投げる | Main | 2作品視聴中視 #anime »

January 22, 2012

Androidアプリ開発メモ055:ブロードキャストレシーバ その2:インテントフィルタ

ブロードキャストレシーバ、Intentの以前の記事:
Androidアプリ開発メモ014:Intentその2
Androidアプリ開発メモ020:ブロードキャストレシーバ

以前のブロードキャストレシーバに関する記事があまりにても簡素すぎたので、もうちょっと詳しく。
暗黙インテントを受信するブロードキャストレシーバとインテントフィルタの設定について。

内部クラスとしてブロードキャストレシーバ(privateとpublic static)を持つアクティビティのコード
package com.example.broadcastreceiverexample;

import java.util.Set;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.os.Bundle;
import android.os.PatternMatcher;
import android.util.Log;

public class BroadcastReceiverExample extends Activity {
  
  private BroadcastReceiver receiver;
  
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    
    // ブロードキャストレシーバの作成、登録
    receiver = new InnerReceiver1();
    IntentFilter intentFilter = new IntentFilter("jp.aabb.ACTION_A");
    intentFilter.addDataScheme("http");
    intentFilter.addDataAuthority("aabb.jp", null);
    intentFilter.addDataPath("/abc.txt", PatternMatcher.PATTERN_LITERAL);
    intentFilter.addCategory("jp.aabb.CATEGORY_1");
    registerReceiver(receiver, intentFilter);
  }

  @Override
  protected void onDestroy() {
    super.onDestroy();
    
    // ブロードキャストレシーバの登録を解除
    unregisterReceiver(receiver);
  }

  public static void logv(String prefix, Intent intent) {
    String action = intent.getAction();
    Uri data = intent.getData();
    Set<String> categories = intent.getCategories();
    Log.v("TEST", prefix
        + ":act=" + action 
        + " dat=" + ((data == null) ? "" : data.toString())
        + " cat=" + ((categories == null) ? "" : categories.toString()));
  }
  
  /** privateな内部クラスのブロードキャストレシーバ */
  private class InnerReceiver1 extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
      logv("InnerReceiver1#onReceive()", intent);
      
      // ここに実行した処理を記述
    }
  }
  
  /** public staticな内部クラスのブロードキャストレシーバ */
  public static class InnerReceiver2 extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
      logv("InnerReceiver2#onReceive()", intent);
      
      // ここに実行した処理を記述
    }
  }
}
publicなブロードキャストレシーバのコード
package com.example.broadcastreceiverexample;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

public class PublicReceiver extends BroadcastReceiver {

  @Override
  public void onReceive(Context context, Intent intent) {
    BroadcastReceiverExample.logv("PublicReceiver#onReceive()", intent);
    
    // ここに実行した処理を記述
  }
}
AndroidManifest.xmlのブロードキャストレシーバの設定部分
<receiver android:name=".BroadcastReceiverExample$InnerReceiver2">
  <intent-filter>
      <action android:name="jp.aabb.ACTION_A" />
      <action android:name="jp.aabb.ACTION_B" />
  </intent-filter>
</receiver>

<receiver android:name=".PublicReceiver">
  <intent-filter>
    <action android:name="jp.aabb.ACTION_A" />
    <data android:scheme="http" android:host="aabb.jp" /> 
  </intent-filter>
  <intent-filter>
    <action android:name="jp.aabb.ACTION_B" />
    <data android:scheme="http" android:host="aabb.jp" />
    <category android:name="jp.aabb.CATEGORY_1" /> 
  </intent-filter>
</receiver>

InnerReceiver1はprivateなクラスなので、AndroidManifest.xmlに記述するのではなく25~31行目のようにインテントフィルタと一緒にContext#registerReceiver()で登録する。
登録したレシーバはアプリケーションが終了するまでに適当なタイミングでContext#unregisterRecieverで登録解除しなければならない。上記のアプリの場合はonDestroy()の中で登録解除している(39行目)。

InnerReceiver2とPublicReceiverはpublicなクラスなので、AndroidManifest.xmlにreceiver要素で書いておく。

インテントフィルタの設定

上記のコードのブロードキャストレシーバについて、インテントフィルタの設定と受信できるインテントについて表にまとめた。

A055

「act=A」はアクションが"jp.aabb.ACTION_A"、cat=1はカテゴリが"jp.aabb.CATEGORY_1"という意味で、そのインテントを受信できる場合は○とした。

アクションが列挙されている場合、インテントのアクションが列挙されたアクションのどれかに一致すればフィルタを通過する。
表のInnerReceiver2では、アクションが"jp.aabb.ACTION_A","jp.aabb.ACTION_B"のどちらでもフィルタを通過する。

データはスキーマとホストだけ設定されている場合はパスは何であってもフィルタを通過する。
パスまで指定されいている場合はパスまで一致する場合にフィルタを通過する。
表のPublicReceiverでは、1個目のフィルタにスキーマ="http"、ホスト="aabb.jp"が設定されているので、データが "http://aabb.jp"、"http://aabb.jp/abc.txt"、"http://aabb.jp/xxx.txt" のどれでも通過する。
InnerReceiver1では、スキーマ="http"、ホスト="aabb.jp"、パス="/abc.txt"なので、データが "http://aabb.jp/abc.txt" はフィルタを通過するが、"http://aabb.jp" や "http://aabb.jp/xxx.txt" はフィルタを通過しない。

カテゴリーが列挙されている場合、インテントのカテゴリすべてがフィルタに列挙されているカテゴリと一致した場合にフィルタを通過する。
表のInnerReceiver1では、フィルタにはカテゴリ"jp.aabb.CATEGORY_1" が設定されているので、カテゴリが "jp.aabb.CATEGORY_1"だけのインテントはフィルタを通過するが、"jp.aabb.CATEGORY_1" に加えて "jp.aabb.CATEGORY_2" を持つインテントはフィルタを通過できない。

« Androidアプリ開発メモ054:Intent その3:コマンドラインからAVDにIntentを投げる | Main | 2作品視聴中視 #anime »

Androidアプリ開発」カテゴリの記事

Comments

Post a comment

(Not displayed with comment.)

TrackBack

TrackBack URL for this entry:
http://app.cocolog-nifty.com/t/trackback/26461/53801241

Listed below are links to weblogs that reference Androidアプリ開発メモ055:ブロードキャストレシーバ その2:インテントフィルタ:

« Androidアプリ開発メモ054:Intent その3:コマンドラインからAVDにIntentを投げる | Main | 2作品視聴中視 #anime »

April 2017
Sun Mon Tue Wed Thu Fri Sat
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30            
無料ブログはココログ

日本blog村

  • にほんブログ村 IT技術ブログへ
  • にほんブログ村 アニメブログへ
  • にほんブログ村 サッカーブログ アルビレックス新潟へ

好きな音楽家

メモ

XI-Prof