SIN@SAPPOROWORKSの覚書

C#を中心に、夜な夜な試行錯誤したコードの記録です。

Xamarin.Android ブロードキャストレシーバー

【 Xamarin 記事一覧 】
ブロードキャストレシーバーとは、ブロードキャストされた暗黙的インテントに応答するための仕組みです。
暗黙的インテントの受信対象となるのは、Activity・Service・BroadcastReceiverの3種類ですが、ブロードキャストレシーバーは、そのうちの1つです。

1 BroadcastReceiverクラス

BroadcastReceiverは、インテントを受け取った際に、唯一1つのメソッド実行するだけの極めてシンプルな構造です。実装は、BroadcastReceiverクラスを継承し、onReceive()メソッドを実装するだけです。
onReceive()では、引数のintentから受け取ったIntent情報を取得することができます。
なお、OnReceive()は、画面描画を行っているUIスレッドで実行されます。

public class MyReceiver : BroadcastReceiver{
    public override void OnReceive(Context context, Intent intent){
        //インテントを受け取った際の処理    
    }
}

2 BroadcastReceiverクラスの有効化

暗黙的インテントが発行されると、Androidシステムは、受け手となるうるクラスを検索することになりますが、その時に使用されるのが、インテントフィルターです。

作成したBroadcastReceiverクラスは、このインテントフィルターをBroadcastReceiverオブジェクトと紐づけることで有効になります。

インテントフィルター定義及び紐づけの方法は、次の2種類があります。

(1)RegisterReceiverによる方法

第1引数はBroadcastReceiverクラスのオブジェクト、第2引数はIntentFilterオブジェクトを指定します。

//インテントフィルターの作成
var intentFilter = new IntentFilter();
intentFilter.AddAction(ACTION_TEST);
//BroadcastReceiverオブジェクトとの紐づけ
RegisterReceiver(new MyReceiver(), intentFilter);

(2)マニフェストファイルによる方法

マニフェストファイルのreceiverタグ内にintent-filterタグを定義することで行います。Xamarinでは、これを属性で追加することができます。


[BroadcastReceiver]
[IntentFilter(new[] { ACTION_TEST })]
public class MyReceiver : BroadcastReceiver{

属性指定によって自動的に追加されたマニュフェストは、次のようになっていました。


<receiver android:name="androidapplication1.Activity1_MyReceiver">
    <intent-filter>
        <action android:name="com.example.intent.action.TEST" />
    </intent-filter>
</receiver>


3 ブロードキャストの送信

ブロードキャストの送信は、SendBroadcast()で行います。

//インテントの作成
var intent = new Intent(ACTION_TEST);
intent.PutExtra("sample", 100);
//ブロードキャスト送信
SendBroadcast(intent);


4 サンプル

001

最後に、今回作ってみたサンプルを載せます。ボタンを押すとブロードキャスト送信し、同時にブロードキャストレシーバで受信します。当然ですが、送信受信は同一アプリである必要はありません。

namespace AndroidApplication1{
    [Activity(Label = "AndroidApplication1", MainLauncher = true, Icon = "@drawable/icon")]
    public class Activity1 : Activity{

        private const String ACTION_TEST = "com.example.intent.action.TEST";

        protected override void OnCreate(Bundle bundle){
            base.OnCreate(bundle);
            SetContentView(Resource.Layout.Main);

            //RegisterReceiverによる登録
            //var intentFilter = new IntentFilter();
            //intentFilter.AddAction(ACTION_TEST);
            //RegisterReceiver(new MyReceiver(), intentFilter);

            FindViewById&lt;Button>(Resource.Id.MyButton).Click += (s, a) =>{
                //インテントの生成
                var intent = new Intent(ACTION_TEST);
                intent.PutExtra("n", 123);
                intent.PutExtra("s", "NAME");
                //ブロードキャスト送信
                SendBroadcast(intent);
            };
        }

        //ブロードキャストレシーバーの定義
        [BroadcastReceiver]
        [IntentFilter(new[] { ACTION_TEST })]
        public class MyReceiver : BroadcastReceiver{
            public override void OnReceive(Context context, Intent intent){
                //受信したインテントからデータを取得する
                var n = intent.GetIntExtra("n", 0);
                var s = intent.GetStringExtra("s");
                Toast.MakeText(context, String.Format("n:{0} s:{1}",n, s), ToastLength.Short).Show();
            }
        }
    }
}

【 Xamarin 記事一覧 】