public class MyReceiver extends BroadcastReceiver {
public boolean isRegistered;
/**
* register receiver
* @param context - Context
* @param filter - Intent Filter
* @return see Context.registerReceiver(BroadcastReceiver,IntentFilter)
*/
public Intent register(Context context, IntentFilter filter) {
try {
// ceph3us note:
// here I propose to create
// a isRegistered(Contex) method
// as you can register receiver on different context
// so you need to match against the same one :)
// example by storing a list of weak references
// see LoadedApk.class - receiver dispatcher
// its and ArrayMap there for example
return !isRegistered
? context.registerReceiver(this, filter)
: null;
} finally {
isRegistered = true;
}
}
/**
* unregister received
* @param context - context
* @return true if was registered else false
*/
public boolean unregister(Context context) {
// additional work match on context before unregister
// eg store weak ref in register then compare in unregister
// if match same instance
return isRegistered
&& unregisterInternal(context);
}
private boolean unregisterInternal(Context context) {
context.unregisterReceiver(this);
isRegistered = false;
return true;
}
// rest implementation here
// or make this an abstract class as template :)
...
}
public class Example extends Activity {
private BroadCastReceiver_example br_exemple;
final Messenger mMessenger = new Messenger(new IncomingHandler());
private boolean running = false;
static class IncomingHandler extends Handler {
@Override
public void handleMessage(Message msg) {
running = false;
switch (msg.what) {
case BroadCastReceiver_example.ALIVE:
running = true;
....
break;
default:
super.handleMessage(msg);
}
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
IntentFilter filter = new IntentFilter();
filter.addAction("pl.example.CHECK_RECEIVER");
br_exemple = new BroadCastReceiver_example();
getApplicationContext().registerReceiver(br_exemple , filter); //register the Receiver
}
// call it whenever you want to check if Broadcast Receiver is running.
private void check_broadcastRunning() {
/**
* checkBroadcastHandler - the handler will start runnable which will check if Broadcast Receiver is running
*/
Handler checkBroadcastHandler = null;
/**
* checkBroadcastRunnable - the runnable which will check if Broadcast Receiver is running
*/
Runnable checkBroadcastRunnable = null;
Intent checkBroadCastState = new Intent();
checkBroadCastState .setAction("pl.example.CHECK_RECEIVER");
checkBroadCastState .putExtra("mainView", mMessenger);
this.sendBroadcast(checkBroadCastState );
Log.d(TAG,"check if broadcast is running");
checkBroadcastHandler = new Handler();
checkBroadcastRunnable = new Runnable(){
public void run(){
if (running == true) {
Log.d(TAG,"broadcast is running");
}
else {
Log.d(TAG,"broadcast is not running");
}
}
};
checkBroadcastHandler.postDelayed(checkBroadcastRunnable,100);
return;
}
.............
}
ブロードキャストレシーバー:
public class BroadCastReceiver_example extends BroadcastReceiver {
public static final int ALIVE = 1;
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Bundle extras = intent.getExtras();
String action = intent.getAction();
if (action.equals("pl.example.CHECK_RECEIVER")) {
Log.d(TAG, "Received broadcast live checker");
Messenger mainAppMessanger = (Messenger) extras.get("mainView");
try {
mainAppMessanger.send(Message.obtain(null, ALIVE));
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
.........
}
}
public class YourApplication extends Application
{
@Override
public void onCreate()
{
super.onCreate();
//register your Broadcast receiver here
IntentFilter intentFilter = new IntentFilter("MANUAL_BROADCAST_RECIEVER");
registerReceiver(new BroadcastReciever(), intentFilter);
}
}
public class MyBroadcastReceiver extends BroadcastReceiver{
private boolean isRegistered;
public void register(final Context context) {
if (!isRegistered){
Log.d(this.toString(), " going to register this broadcast receiver");
context.registerReceiver(this, new IntentFilter("MY_ACTION"));
isRegistered = true;
}
}
public void unregister(final Context context) {
if (isRegistered) {
Log.d(this.toString(), " going to unregister this broadcast receiver");
context.unregisterReceiver(this);
isRegistered = false;
}
}
@Override
public void onReceive(final Context context, final Intent intent) {
switch (getResultCode()){
//DO STUFF
}
}
}
次に、アクティビティクラスで:
public class MyFragmentActivity extends SingleFragmentActivity{
MyBroadcastReceiver myBroadcastReceiver;
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
registerBroacastReceiver();
}
@Override
protected Fragment createFragment(){
return new MyFragment();
}
//This method is called by the fragment which is started by this activity,
//when the Fragment is done, we also register the receiver here (if required)
@Override
public void receiveDataFromFragment(MyData data) {
registerBroacastReceiver();
//Do some stuff
}
@Override
protected void onStop(){
unregisterBroacastReceiver();
super.onStop();
}
void registerBroacastReceiver(){
if (myBroadcastReceiver == null)
myBroadcastReceiver = new MyBroadcastReceiver();
myBroadcastReceiver.register(this.getApplicationContext());
}
void unregisterReceiver(){
if (MyBroadcastReceiver != null)
myBroadcastReceiver.unregister(this.getApplicationContext());
}
}
受信機が登録されているかどうかを確認するAPI関数はありません。回避策としては、以下のように `try catch ブロック' にコードを記述することです。
このスレッド]1を考慮すると、APIが直接APIを提供しているとは思えませんね:
最も簡単なソリューション。 =====================。
レシーバーで: ------------。
コード: --------。
広告1 。
-返信:
-「よりエレガントな方法」は、フラグを登録および設定するためにレシーバーにメソッドを追加しました。
@amin-コードの存続期間を参照してください(マニフェストエントリによって登録されたシステムではありません)登録レシーバー:)。
このソリューションを使用しています。
いくつかのオプションがあります。
1.クラスやアクティビティにフラグを入れることができます。クラスにブーリアン変数を入れて、このフラグを見て、レシーバーが登録されているかどうかを知ることができます。
2.Receiverを継承したクラスを作成し、そこで使用します:
try / catch:を使用する必要があります。
簡単に行うことができます。...
1)ブール変数を作成します。 ...
2)ブロードキャストレシーバーを登録するときに、TRUEに設定します。
3)onPause()でそれを行います。..
それだけで、今、onPause()で例外エラーメッセージが表示されることはありません。
ヒント1:onDestroy()ではなくonPause()でunregisterReceiver()を常に使用します。 ヒント2:unregisterReceive()を実行するときに、bolBroadcastRegistred変数をFALSEに設定することを忘れないでください。
成功。!
これをonDestroyまたはonStopメソッドに置く場合。 アクティビティが再び作成されたとき、MessageReciverは作成されていなかったと思います。
Intentを使用して、ブロードキャストレシーバーにメインアクティビティスレッドのハンドラーインスタンスを知らせ、メッセージを使用してメインアクティビティにメッセージを渡しました。
このようなメカニズムを使用して、Broadcast Receiverがすでに登録されているかどうかを確認しました。 Broadcast Receiverを動的に登録し、2回作成したくない場合や、Broadcast Receiverが実行されている場合にユーザーに提示する場合に必要になる場合があります。
主な活動:
ブロードキャストレシーバー:
個人的には、unregisterReceiverを呼び出し、例外がスローされた場合はそれを飲み込む方法を使用します。 これは醜いことに同意しますが、現在提供されている最良の方法です。
Android APIにレシーバーが追加されているかどうかを確認するためのブールメソッドを取得するための機能リクエストを提起しました。追加を確認したい場合は、こちらでサポートしてください。 [https://code.google.com/p/android/issues/detail?id = 73718][1]。
[1]:https://code.google.com/p/android/issues/detail?id = 73718。
私はあなたの問題を見つけました、私は私のアプリケーションで同じ問題に直面しました。 アプリケーション内でregisterReceiver()に複数回電話をかけていました。
この問題の簡単な解決策は、カスタムアプリケーションクラスでregisterReceiver()を呼び出すことです。 これにより、ブロードキャストレシーバーがアプリケーションライフサイクル全体で1つだけ呼び出されるようになります。
これは私がやった方法です。これは、ceph3usによって与えられ、slinden77によって編集された回答の修正バージョンです(特に、必要のないメソッドの戻り値を削除しました)。
次に、アクティビティクラスで:
このコードを親アクティビティに入れます。
リスト registeredReceivers = new ArrayList();。
Daggerを使用して、そのレシーバーのリファレンスを作成できます。
まずそれを提供します:
次に、必要な場所に注入します(「コンストラクター」またはフィールド「インジェクション」を使用)。
単に「registerReceiver」に渡します。
また、「トライ/キャッチ」ブロックにも入れます。
アプリケーションを閉じても、Broadcasterがすでに登録されているかどうかを確認するために私が行ったことは次のとおりです(finish())。
アプリケーションを実行するときに、最初にブロードキャストを送信します。true/ falseを返します。これは、ブロードキャスターがまだ実行されているかどうかによって異なります。
私の放送局。
私の主な活動。
NullPointerExceptionを確認してください。 レシーバーが存在しない場合は、...