Android BroadcastReceiver チュートリアルとサンプル
*BroadcastReceiver`は、システム全体のブロードキャストイベントやインテントをリッスンする役割を持つアンドロイドコンポーネントです。
Androidでは、ほとんどのシステムイベントは Intent オブジェクトによってブロードキャストされます。これを行うために、これらのIntentオブジェクトは、Context.sendBroadcast()メソッドを使ってBroadcastReceiversに送られます。
このようなイベントがブロードキャストされると、BroadcastReceiverはイベントを受信し、ステータスバーに通知を作成するか、指定されたタスクを実行することで反応します。
BroadcastReceiver "は、"Activity "や "Service "と同様にアンドロイドのコンポーネントであるため、ほとんどの場合、アンドロイドのマニフェストファイルに登録する必要があります。
しかし、Activityとは異なり、BroadcastReceiverにはユーザーインターフェースがありません。
クラスとしてのBroadcastReceiverは抽象的で、通常はonReceive()と呼ばれるメソッドを持ち、タスクが受信されたときに発生させたいタスクを実行するためにオーバーライドします。
標準的なシステムイベントのほとんどは、アクション文字列として定義されており、IntentクラスのAPIドキュメントに記載されています。
例えば、ユーザーがデバイスに充電器を接続したり、切断したりしたときに、アプリが通知を受ける必要があるとすると、Intentクラスで定義された2つのブロードキャストアクションがそれを行います。
- 1.アクション_パワーディスコネクト
action_power_connectedです。
以下に例を示します。
public class PhoneChargerConnectedListener extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (Intent.ACTION_POWER_CONNECTED.equals(action)) {
context.startService(
new Intent(MyService.ACTION_POWER_CONNECTED));
} else if (Intent.ACTION_POWER_DISCONNECTED.equals(action)) {
context.startService(
new Intent(MyService.ACTION_POWER_DISCONNECTED));
}
}
}
このメソッドでは、Context.startService()を呼び出して、イベントを実際の作業を行うサービスに委譲するだけです。
BroadcastReceiver はどうやって登録するのですか?
ブロードキャストレシーバーを登録するには2つの方法があります。
1. AndroidManifest.xml経由
BroadcastReceivers**を実装するためのデフォルトの方法は、android manifestで宣言することです。
そのため、ユーザーがアプリケーションを起動していなくても、BroadcastReceiverがserviceを通知することが可能になります。
これは、ユーザーの操作なしに特定のシステムイベントで起動する必要があるアプリケーションの場合に特に有効です。
<receiver android_name=".PhoneChargerConnectedListener">
<intent-filter>
<action android_name="android.intent.action.ACTION_POWER_CONNECTED"/>
<action android_name="android.intent.action.ACTION_POWER_DISCONNECTED"/>
</intent-filter>
</receiver>
この方法は最も簡単な方法でもあります。
AndroidManifest.xmlを使用して<strong>BroadcastReceiver</strong>を登録することで、アプリケーションをアンインストールするまで、アプリケーションはブロードキャストを取得し続けます。これは、BroadcastReceiver`のライフサイクルのコントロールを少し犠牲にしていることを意味します。
そのためには、次のブロードキャストレシーバーの登録方法を確認します。
2. プログラムで登録する
BroadcastReceiversは、Activityやサービスの中でプログラム的に登録することもできます。
実際、ブロードキャストインテントの中には、プログラムでしか登録できないものもあります。その一方で、マニフェストで宣言しないと動作しないものもあります。
BroadcastReceiver**をプログラムで登録する場合、マッチングするコールバックで登録を解除することも忘れてはいけません。
以下はその例です。
public class MyActivity extends AppCompatActivity {
private PhoneChargerConnectedListener myPhoneChargerConnectedListener;
@Override
protected void onResume() {
super.onResume();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_POWER_CONNECTED);
intentFilter.addAction(Intent.ACTION_POWER_DISCONNECTED);
myPhoneChargerConnectedListener = new PhoneChargerConnectedListener();
registerReceiver(myPhoneChargerConnectedListener, intentFilter);
}
@Override
protected void onPause() {
super.onPause();
unregisterReceiver(myPhoneChargerConnectedListener);
}
}
このケースでは、ContextクラスのregisterReceiver()メソッドを使って、プログラム的にBroadcastReceiverを登録しています。このメソッドを使用することで、必要に応じて登録と登録解除を行うことで、BroadcastReceiverのライフサイクルを制御することができます。
AlarmManagerを使ったブロードキャストレシーバーの例
ここでは、アラームマネージャーを使ったシンプルなブロードキャストレシーバーの例を見てみましょう。
ここでは、1つの activity と1つのクラスを用意します。
(a). MainActivity.java
まず、アンドロイドスタジオで「アクティビティ」を作成します。
ここでは「MainActivity」クラスを作成します。このクラスは、サポートライブラリに存在するAppCompatActivityから派生します。
3つのメソッドを用意しました。
- onCreate()`です。
- initializeViews()`である。
- go()`です。
この activity のユーザインタフェースは、setContentView() メソッドを用いて content_main.xml からインフレーションされます。
使用するビューはEditTextsとButtonsです。
findViewById()`を使用して、レイアウト仕様からこれらを参照します。
go()`メソッドでアラームの初期化と起動を行います。
package com.tutorials.hp.alarmmanagerstarter;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
Button startBtn;
EditText timeTxt;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
initializeViews();
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
}
/*
INITIALIZE VIEWS
*/
private void initializeViews()
{
timeTxt= (EditText) findViewById(R.id.timeTxt);
startBtn= (Button) findViewById(R.id.startBtn);
startBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
go();
}
});
}
/*
INITIALIZE AND START OUR ALARM
*/
private void go()
{
//GET TIME IN SECONDS AND INITIALIZE INTENT
int time=Integer.parseInt(timeTxt.getText().toString());
Intent i=new Intent(this,MyReceiver.class);
//PASS CONTEXT,YOUR PRIVATE REQUEST CODE,INTENT OBJECT AND FLAG
PendingIntent pi=PendingIntent.getBroadcast(this,0,i,0);
//INITIALIZE ALARM MANAGER
AlarmManager alarmManager= (AlarmManager) getSystemService(ALARM_SERVICE);
//SET THE ALARM
alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+(time*1000),pi);
Toast.makeText(MainActivity.this, "Alarm set in "+time+" seconds", Toast.LENGTH_SHORT).show();
}
}
(b). MyReciever.java
- MyRecieverクラスです。
- android.content.BroadcastReceiverクラスから派生しています。
- メソッド: onReceive().
- onReceive()`メソッドでは、アラーム音をシミュレートするために、トーストメッセージを表示しています。
package com.tutorials.hp.alarmmanagerstarter;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
public class MyReceiver extends BroadcastReceiver {
/*
RING ALARM WHEN IN WHEN WE RECEIVE OUR BROADCAST
*/
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Alarm Ringing...", Toast.LENGTH_SHORT).show();
}
}
(c) activity_main.xml
- メインの
activityレイアウトファイルです。 - MainActivityにインフレーションされるものとします。
- ルートタグはrelativeLayoutです。
- EditTextとボタンを含みます。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android_layout_width="match_parent"
android_layout_height="match_parent"
tools_context="com.tutorials.hp.alarmmanagerstarter.MainActivity"
>
<EditText
android_id="@+id/timeTxt"
android_layout_width="wrap_content"
android_layout_height="wrap_content"
android_layout_alignParentLeft="true"
android_layout_alignParentTop="true"
android_layout_marginTop="28dp"
android_ems="10"
android_hint="Number of seconds"
android_inputType="numberDecimal" />
<Button
android_id="@+id/startBtn"
android_layout_width="wrap_content"
android_layout_height="wrap_content"
android_layout_alignRight="@+id/timeTxt"
android_layout_below="@+id/timeTxt"
android_layout_marginRight="60dp"
android_layout_marginTop="120dp"
android_text="Start" />
</RelativeLayout>
(d). AndroidManifest.xml
BroadcastReceiver」クラスをアンドロイドマニフェストに登録する必要があります。
これが私のマニフェストの全文です。
<?xml version="1.0" encoding="utf-8"?>
<manifest
package="com.tutorials.hp.alarmmanagerstarter">
<application
android_allowBackup="true"
android_icon="@mipmap/ic_launcher"
android_label="@string/app_name"
android_supportsRtl="true"
android_theme="@style/AppTheme">
<activity
android_name=".MainActivity"
android_label="@string/app_name"
android_theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android_name="android.intent.action.MAIN" />
<category android_name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android_name="MyReceiver" >
</receiver>
</application>
</manifest>
Quick BroadcastReceiver Examples
1. BroadcastReceiver`を使ってネットワークの状態変化を聞く
まず、Javaクラスを作成し、android.content.BroadcastReceiverから派生させる必要があります。
インスタンスフィールドとして、ネットワークが接続されているかどうかを示す真偽値を保持するブーリアン型の isNetWorkConnected を用意します。
また,Contextオブジェクトも用意しています.
2つのコンストラクタを用意しました。1つはクラスに Context オブジェクトを注入します。
次に、BroadcastReceiverクラスのonReceive()メソッドをオーバーライドします。通常、このメソッドは2つのオブジェクトを受け取ります。1つは Context オブジェクトで、もう1つは Intent オブジェクトです。
ここでは,ContextクラスのgetSystemService() ,メソッドを用いてConnectivityManagerを初期化する。
ConnectivityManagerのインスタンスを使って、getActiveNetworkInfo()メソッドを呼び出し、android.net.NetworkInfo`オブジェクトに保持されているネットワーク情報を受け取ります。
最終的には、isNetWorkConnectedのブール値に`isConnected()の値を設定します。
次に、isNetWorkAvailable()メソッドがあり、基本的にネットワークが利用可能かどうかをチェックします。
これは単なるパブリックメソッドで、後ほど説明するように、このクラスのインスタンスが呼び出される必要があります。
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.widget.Toast;
import java.util.concurrent.CopyOnWriteArrayList;
public class NetWorkStateReceiver extends BroadcastReceiver {
public boolean isNetWorkConnected;
private Context mContext;
public NetWorkStateReceiver() {
super();
}
public NetWorkStateReceiver(Context context) {
mContext = context;
}
@Override
public void onReceive(Context context, Intent intent) {
ConnectivityManager connectivityManager = (ConnectivityManager)
context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected()) {
isNetWorkConnected = true;
} else {
isNetWorkConnected = false;
Toast.makeText(context, "No network Connection", Toast.LENGTH_SHORT).show();
}
}
/**
* Check if network is available
* @return boolean value
*/
public boolean isNetWorkAvailable() {
ConnectivityManager connectivityManager = (ConnectivityManager)
mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
if (networkInfo != null) {
return networkInfo.isConnected();
}
return false;
}
}
MainActivityでもどこでも、上記のクラスをインスタンス化することで始めることができます。
publi class MainActivity extends AppCompatActivity{
NetWorkStateReceiver receiver;
@Override
public void onCreate(Bundle savedInstanceState){
.....
receiver = new NetWorkStateReceiver(this);
if(receiver.isNetWorkAvailable())
{
//do something network is available
}
}
}
AndroidManifest.xmlでは、適切なパーミッションを追加して、BroadcastReceiver`を登録する必要があります。
<?xml version="1.0" encoding="utf-8"?>
<manifest
>
<uses-permission android_name="android.permission.INTERNET" />
<uses-permission android_name="android.permission.ACCESS_NETWORK_STATE" />
<application>
....
<receiver
android_name=".broadcasts.NetWorkStateReceiver"
android_enabled="true"
android_exported="true" />
....
</application>
2. カスタムBroadcastReceiverの作成方法
ここでは、カスタムの抽象的なBroadcastRecieverクラスを紹介します。明らかに BroadcastReceiver から派生しています。このクラスの重要なメソッドである registerReceiver(), unregisterReceiver(), sendBroadcast() を再定義します。
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.v4.content.LocalBroadcastManager;
public abstract class LocalBroadcastCommunicator extends BroadcastReceiver {
// The action name used to send and alsoe receive intents
private static String sAction = null;
private static <T> void registerReceiver(LocalBroadcastCommunicator receiver, Context context) {
sAction = receiver.getClass().getName();
LocalBroadcastManager.getInstance(context).registerReceiver(receiver, new IntentFilter(sAction));
}
private static <T> void unregisterReceiver(LocalBroadcastCommunicator receiver, Context context) {
LocalBroadcastManager.getInstance(context).unregisterReceiver(receiver);
}
public static void sendBroadcast(Context context, Intent intent) {
if(sAction == null) {
/* If sAction is null at this point, no receiver has been registered yet and there's no
* point in sending a broadcast. */
return;
}
intent.setAction(sAction);
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
}
public void registerReceiver(Context context) {
registerReceiver(this, context);
}
public void unregisterReceiver(Context context) {
unregisterReceiver(this, context);
}
}
完全な例
1. BroadcastReceiver`を使ってバッテリー残量が少ないことを通知する方法
BroadcasteReceiver クラスを使用して、シンプルな BatteryManager を作成します。バッテリー残量をテキストビューで表示し、進捗状況をプログレスバーで表示します。
以下は、私たちが使用しているAPIの一部です。
(a). BroadcastReceiver`(ブロードキャストレシーバー
これは、sendBroadcast()によって送られたインテントを受信するコードの基本クラスです。
(b). IntentFilter (インテントフィルタ)
IntentFilter は、マッチさせるべき Intent の値を構造的に記述したものです。IntentFilterは、Intent内のactions、categories、data(タイプ、スキーム、パスのいずれか)とマッチさせることができます。
**(c). バッテリーマネージャー
このクラスは ACTION_BATTERY_CHANGED``Intent の値に使用される文字列と定数を含みます。
MainActivity.java (メインアクティビティ
これはメインの activity です。
package com.example.ankitkumar.broadcastreceiver_batterymanager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.BatteryManager;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.ProgressBar;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
TextView batteryLevel;
ProgressBar myProgressBar;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
batteryLevel = (TextView)findViewById(R.id.textView);
myProgressBar = (ProgressBar)findViewById(R.id.progressBar);
IntentFilter intentFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
registerReceiver(myBroadcastReceiver, intentFilter);
}
BroadcastReceiver myBroadcastReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
context.unregisterReceiver(this);
int currentLevel = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
int level = -1;
if (currentLevel >= 0 && scale > 0) {
level = (currentLevel * 100) / scale;
}
batteryLevel.setText("Battery Level remaining :"+ level +"%");
myProgressBar.setProgress(level);
}
};
}
activity_main.xml これはメインの activity です。
これはメインの activity のレイアウトです。
ここでは、バッテリー残量を表示するTextViewと、バッテリー残量の割合を表示するプログレスバーを用意しています。
<?xml version="1.0" encoding="UTF-8"?>
<RelativeLayout
tools_context="com.example.ankitkumar.broadcastreceiver_batterymanager.MainActivity" android_paddingTop="@dimen/activity_vertical_margin" android_paddingRight="@dimen/activity_horizontal_margin" android_paddingLeft="@dimen/activity_horizontal_margin" android_paddingBottom="@dimen/activity_vertical_margin" android_layout_height="match_parent" android_layout_width="match_parent" android_id="@+id/activity_main" >
<TextView
android_layout_height="wrap_content" android_layout_width="wrap_content" android_id="@+id/textView" android_layout_centerHorizontal="true" android_layout_centerVertical="true" android_textSize="20sp" android_text="Hello World!"/>
<ProgressBar
android_layout_height="20dp" android_layout_width="match_parent" android_id="@+id/progressBar" android_layout_alignParentRight="true" android_layout_alignParentEnd="true" android_layout_below="@+id/textView" android_layout_marginTop="25dp" android_max="100" style="?android:attr/progressBarStyleHorizontal"/>
</RelativeLayout>
**ダウンロード
| --- |
|---|
2. BroadcastReceiver`を使って、受信したSMSを聞いて、それを表示する
BroadcastReceiverを使用して、受信した SMS を受信し、それを読み込んで Toast メッセージに表示します。
MainActivity.java (メインアクティビティ)
これがメインの activity です。
package com.example.ankitkumar.msgreceive;
import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//checking wether the permission is already granted
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_SMS) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_SMS}, 1);
}
}
}
IcomingSMS.java これは、メインの activity です。
私たちの IncomingSMS.java ファイルです。使用しているAPIの一部を紹介します。
(a). SmsManager
これは android.telephony パッケージで定義されたクラスで、データ、テキスト、および pdu の SMS メッセージの送信など、SMS 操作の管理を行います。
(b). SmsMessage (SMSメッセージ)
ショートメッセージサービスのメッセージを表します。
package com.example.ankitkumar.msgreceive;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.telephony.SmsManager;
import android.telephony.SmsMessage;
import android.util.Log;
import android.widget.Toast;
import static android.telephony.SmsMessage.createFromPdu;
public class IncomingSms extends BroadcastReceiver {
// Get the object of SmsManager
final SmsManager sms = SmsManager.getDefault();
@Override
public void onReceive(Context context, Intent intent) {
// Retrieves a map of extended data from the intent.
final Bundle bundle = intent.getExtras();
try {
if (bundle != null) {
final Object[] pdusObj = (Object[]) bundle.get("pdus");
for (int i = 0; i < pdusObj.length; i++) {
SmsMessage currentMessage = createFromPdu((byte[]) pdusObj[i]);
String phoneNumber = currentMessage.getDisplayOriginatingAddress();
String senderNum = phoneNumber;
String message = currentMessage.getDisplayMessageBody();
Log.i("SmsReceiver", "senderNum: " + senderNum + "; message: " + message);
int duration = Toast.LENGTH_LONG;
final Toast toast = Toast.makeText(context, "senderNum: " + senderNum + ", message: " + message, duration);
toast.show();
//Countdown Timer for extending normal time of toast notification
new CountDownTimer(9000, 1000) {
public void onTick(long millisUntilFinished) {
toast.show();
}
public void onFinish() {
toast.show();
}
}.start();
} // end for loop
} // bundle is null
} catch (Exception e) {
Log.e("SmsReceiver", "Exception smsReceiver" + e);
}
}
}
activity_main.xml (日本語)
メインの activity のレイアウトです。
<?xml version="1.0" encoding="UTF-8"?>
<RelativeLayout
tools_context="com.example.ankitkumar.msgreceive.MainActivity" android_background="#f2f2f2" android_layout_height="match_parent" android_layout_width="match_parent" >
<ImageView
android_background="@drawable/ic_sms" android_layout_height="200sp" android_layout_width="200sp" android_contentDescription="@string/app_name" android_layout_centerInParent="true" android_alpha="0.4"/>
</RelativeLayout>
**ダウンロード
| --- |
|---|
Android LocalBroadcastManager
Android LocalBroadcastManager with IntentService Tutorial and Example.
これは、アンドロイドの LocalBroadcastManager のチュートリアルと例です。LocalBroadcastManager "とは何か、そして "IntentService "とどのように併用するのかを見てみましょう。
ビデオチュートリアル
ビデオチュートリアルを好む人もいます。その場合は、このチュートリアルのビデオバージョンをご覧ください。
What You Learn in This Tutorial
このチュートリアルでは、以下のことを学びます。
- LocalBroadcastManager "とは何か、そしてその API 定義。
- LocalBroadcastManager "の利点。
- IntentService
とLocalBroadcastManager`を併用する方法。
LocalBroadcastManager とは何ですか?
LocalBroadcastManager` はヘルパークラスで、プロセス内のローカルオブジェクトにインテントのブロードキャストを登録・送信することができます。
これがそのAPI定義です。
public final class LocalBroadcastManager
extends Object
java.lang.Object
↳ android.support.v4.content.LocalBroadcastManager
LocalBroadcastManager の利点
SendBroadcast(Intent)メソッドでグローバルなブロードキャストを送信するのに比べて、LocalBroadcastManager`の利点は以下の通りです。
- このクラスはアプリケーションプロセス内の限られたオブジェクトのみを扱うので、アプリケーションデータはプライベートに保たれます。
- アプリケーションプロセス内でのみ動作するので、より安全です。
- システムを通してグローバルなブロードキャストを送信するよりも効率的です。
(a). BroadcastSenderIntentService
これは私たちの IntentService クラスです。ここでは、android.app.IntentServiceを継承し、onHandleIntent()メソッドをオーバーライドします。このメソッドの中では、threadクラスのsleep()メソッドを呼び出して、重いタスクをシミュレートします。
package info.camposha.localbroadcastandintentservice;
import android.app.IntentService;
import android.content.Intent;
import android.support.v4.content.LocalBroadcastManager;
public class BroadcastSenderIntentService extends IntentService {
public BroadcastSenderIntentService() {
super("BroadcastSenderIntentService");
}
@Override
protected void onHandleIntent(Intent intent) {
String message = getString(R.string.running);
Intent broadcastIntent = new Intent();
broadcastIntent.setAction(MainActivity.MESSAGE_SENT_ACTION);
broadcastIntent.putExtra(MainActivity.MESSAGE_EXTRA, message);
LocalBroadcastManager.getInstance(this).sendBroadcast(broadcastIntent);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
message = getString(R.string.finished);
broadcastIntent = new Intent();
broadcastIntent.setAction(MainActivity.MESSAGE_SENT_ACTION);
broadcastIntent.putExtra(MainActivity.MESSAGE_EXTRA, message);
LocalBroadcastManager.getInstance(this).sendBroadcast(broadcastIntent);
}
}
(b). MainActivity.java
これが私たちのメインの activity です。まず、いくつかの文字列定数を定義することから始めます。これらの定数は、識別子として機能するため、インテントを送受信する際に役立ちます。
package info.camposha.localbroadcastandintentservice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
public static final String MESSAGE_SENT_ACTION = "info.camposha.MESSAGE_RECEIVED_ACTION";
public static final String MESSAGE_EXTRA = "info.camposha.MESSAGE_EXTRA";
private static final String MESSAGE_FROM_SERVICE_KEY = "info.camposha.MESSAGE_FROM_SERVICE_KEY";
private BroadcastReceiver receiver;
private TextView serviceMessageView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
serviceMessageView = findViewById(R.id.service_message_textview);
if (savedInstanceState != null) {
serviceMessageView.setText(savedInstanceState.getString(MESSAGE_FROM_SERVICE_KEY));
}else{
serviceMessageView.setText("Null");
}
}
@Override
protected void onResume() {
super.onResume();
receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
String message = bundle.getString(MESSAGE_EXTRA);
serviceMessageView.setText(message);
}
};
LocalBroadcastManager.getInstance(this).registerReceiver(receiver, new IntentFilter(MESSAGE_SENT_ACTION));
}
@Override
protected void onPause() {
super.onPause();
if (receiver != null) {
LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver);
receiver = null;
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString(MESSAGE_FROM_SERVICE_KEY, serviceMessageView.getText().toString());
}
public void onStartServiceClicked(View view) {
startService(new Intent(this, BroadcastSenderIntentService.class));
}
}
activity_main.xml
これがメインの activity のレイアウトです。ここには、テキストビューとボタンがあります。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android_layout_width="match_parent"
android_layout_height="match_parent"
tools_context=".MainActivity">
<TextView
android_id="@+id/headerLabel"
android_layout_width="wrap_content"
android_layout_height="wrap_content"
android_layout_alignParentTop="true"
android_layout_centerHorizontal="true"
android_fontFamily="casual"
android_text="LocalBroadcastReceiver"
android_textAllCaps="true"
android_textSize="24sp"
android_textStyle="bold" />
<LinearLayout
android_layout_width="wrap_content"
android_layout_height="wrap_content"
android_layout_centerHorizontal="true"
android_layout_centerVertical="true"
android_gravity="center"
android_orientation="vertical" >
<TextView
android_id="@+id/textView1"
android_layout_width="wrap_content"
android_layout_height="wrap_content"
android_text="@string/service_status"
android_textSize="16dp" />
<TextView
android_id="@+id/service_message_textview"
android_layout_width="wrap_content"
android_layout_height="wrap_content"
android_text="@string/not_running"
android_textSize="16dp" />
</LinearLayout>
<Button
android_id="@+id/button1"
android_onClick="onStartServiceClicked"
android_text="@string/start_service"
android_layout_width="wrap_content"
android_layout_height="wrap_content"
android_layout_alignParentBottom="true"
android_layout_centerHorizontal="true"
android_layout_marginBottom="12dp"
android_fontFamily="serif-monospace" />
</RelativeLayout>
AndroidManifest.xml
アンドロイドマニフェストでは、serviceの登録を確認しなければなりません。これが私のマニフェストです。
<?xml version="1.0" encoding="utf-8"?>
<manifest
package="info.camposha.localbroadcastandintentservice">
<application
android_allowBackup="true"
android_icon="@mipmap/ic_launcher"
android_label="@string/app_name"
android_roundIcon="@mipmap/ic_launcher_round"
android_supportsRtl="true"
android_theme="@style/AppTheme">
<activity android_name=".MainActivity">
<intent-filter>
<action android_name="android.intent.action.MAIN" />
<category android_name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android_name=".BroadcastSenderIntentService" />
</application>
</manifest>
Kotlin LocalBroadcastManager の例
kotlinによるAndroidXのlocalbroadcastmanagerの例で、IntentServiceとBroadcastReceiverを使っています。
ビデオチュートリアルはこちら。
Step 1: 依存関係の追加
gradleファイルにAndroiX localbroadcastmanagerを依存関係として追加します。
implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.0.0'
ステップ2:レイアウトの設計
テキストビューとボタンのあるレイアウトをデザインします。
<?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:gravity="center"
android:orientation="vertical">
<TextView
android:id="@+id/dateText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Initial value"
android:textSize="20dp"
android:textStyle="bold"/>
<Button
android:id="@+id/startButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="Start Service"/>
</LinearLayout>
ステップ 3: IntentService の作成
インテントサービスのクラスを作成し、onHandleIntentメソッドをオーバーライドします。
package info.camposha.ms_localbroadcastmanager
import android.app.IntentService
import android.content.Intent
import android.util.Log
import androidx.localbroadcastmanager.content.LocalBroadcastManager
import java.util.*
//IntentService is a ntentService is a base class for Services that handle asynchronous
// requests (expressed as Intents) on demand.
class MyIntentService : IntentService("MyIntentService") {
override fun onHandleIntent(arg0: Intent?) {
val intent = Intent(CUSTOM_ACTION)
//get date to send
intent.putExtra("DATE", Date().toString())
Log.d(MyIntentService::class.java.simpleName, "sending broadcast")
// send local broadcast
//LocalBroadcastManager is a Helper to register for and send broadcasts of Intents
// to local objects within your process.
LocalBroadcastManager.getInstance(this).sendBroadcast(intent)
}
companion object {
const val CUSTOM_ACTION = "YOUR_CUSTOM_ACTION"
}
}
Step 4: MainActivityの作成
ランチャーである activity を作成します。
package info.camposha.ms_localbroadcastmanager
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.localbroadcastmanager.content.LocalBroadcastManager
import kotlinx.android.synthetic.main.activity_main.*
//Our main activity
class MainActivity : AppCompatActivity(), View.OnClickListener {
//override onCreate
public override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
startButton.setOnClickListener(this)
}
//when activity is paused
override fun onPause() {
super.onPause()
// unregister local broadcast
LocalBroadcastManager.getInstance(this).unregisterReceiver(mReceiver)
}
//when activity is resumed
override fun onResume() {
super.onResume()
// register local broadcast
val filter = IntentFilter(MyIntentService.CUSTOM_ACTION)
LocalBroadcastManager.getInstance(this).registerReceiver(mReceiver, filter)
}
/**
Create a BroadcastReceiver
* BroadcastReceiver is a Base class for code that will receive intents sent by sendBroadcast().
* Broadcast receiver to receive the data
*/
private val mReceiver: BroadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
val date = intent.getStringExtra("DATE")
dateText.text = date
}
}
//when user clicks the start button, start our intent service
override fun onClick(view: View) {
if (view.id == R.id.startButton) {
// start intent service
val intent = Intent(this, MyIntentService::class.java)
startService(intent)
}
}
}
ステップ5:コンポーネントの登録
android manifextファイルに2つのコンポーネントを登録します。
- MainActivity
- IntentService` (インテントサービス)
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".MyIntentService"/>
ステップ6: 実行
プロジェクトを実行すると、以下のようになります。

コードのダウンロード
コードのダウンロードはこちら(%E3%81%8B%E3%82%89)https://github.com/Oclemy/MsLocalBroadcastManager/archive/refs/heads/master.zip)から%E3%81%8B%E3%82%89)。