등록 된 수신자가 등록되어 있는지 확인해야한다면 어떻게해야합니까?
답변
이 스레드 를 고려하면 API가 API를 직접 제공하는지 잘 모르겠습니다 .
나는 같은 것을 궁금해했다.
내 경우 에는 수신 의도를 처리 한 후 인수로 자신을 전달BroadcastReceiver
하는 호출Context#unregisterReceiver(BroadcastReceiver)
을 구현합니다
.
수신기의있는 작은 기회가있다onReceive(Context, Intent)
가 여러에 등록되어 있기 때문에 방법은, 한 번 이상이라고IntentFilters
에 대한 가능성 생성IllegalArgumentException
에서 던진 존재는Context#unregisterReceiver(BroadcastReceiver)
.필자의 경우을 호출하기 전에 확인할 비공개 동기화 멤버를 저장할 수
Context#unregisterReceiver(BroadcastReceiver)
있지만 API가 체크 메소드를 제공하면 훨씬 깨끗합니다.
답변
수신자가 등록되었는지 확인하는 API 기능이 없습니다. 해결 방법은 코드를try catch block as done below.
try {
//Register or UnRegister your broadcast receiver here
} catch(IllegalArgumentException e) {
e.printStackTrace();
}
답변
가장 간단한 솔루션
수신기에서 :
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 :)
...
}
코드에서 :
MyReceiver myReceiver = new MyReceiver();
myReceiver.register(Context, IntentFilter); // register
myReceiver.unregister(Context); // unregister
광고 1
— 에 회신하여:
등록한 후 isRegistered 플래그를 설정해야한다는 점을 기억해야하기 때문에 실제로 그렇게 우아하지는 않습니다. – 스텔스 랍비
– “더 우아한”방식으로 수신기에 메소드를 추가하여 플래그를 등록 및 설정
기기를 다시 시작하거나 앱이 OS에 의해 종료 된 경우 작동하지 않습니다. – amin 6 시간 전
@amin-코드의 수명을 참조하십시오 (매니페스트 항목으로 시스템이 등록되지 않음) 등록 수신자 🙂
답변
이 솔루션을 사용하고 있습니다
public class ReceiverManager {
private static List<BroadcastReceiver> receivers = new ArrayList<BroadcastReceiver>();
private static ReceiverManager ref;
private Context context;
private ReceiverManager(Context context){
this.context = context;
}
public static synchronized ReceiverManager init(Context context) {
if (ref == null) ref = new ReceiverManager(context);
return ref;
}
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter intentFilter){
receivers.add(receiver);
Intent intent = context.registerReceiver(receiver, intentFilter);
Log.i(getClass().getSimpleName(), "registered receiver: "+receiver+" with filter: "+intentFilter);
Log.i(getClass().getSimpleName(), "receiver Intent: "+intent);
return intent;
}
public boolean isReceiverRegistered(BroadcastReceiver receiver){
boolean registered = receivers.contains(receiver);
Log.i(getClass().getSimpleName(), "is receiver "+receiver+" registered? "+registered);
return registered;
}
public void unregisterReceiver(BroadcastReceiver receiver){
if (isReceiverRegistered(receiver)){
receivers.remove(receiver);
context.unregisterReceiver(receiver);
Log.i(getClass().getSimpleName(), "unregistered receiver: "+receiver);
}
}
}
답변
몇 가지 옵션이 있습니다
-
수업이나 활동에 깃발을 넣을 수 있습니다. 부울 변수를 클래스에 넣고이 플래그를보고 수신자가 등록되어 있는지 확인하십시오.
-
수신자를 확장하는 클래스를 작성하면 다음을 사용할 수 있습니다.
-
프로젝트에서이 클래스의 인스턴스가 하나만있는 싱글 톤 패턴.
-
수신자가 등록되어 있는지 알 수있는 방법을 구현하십시오.
-
답변
try / catch를 사용해야합니다.
try {
if (receiver!=null) {
Activity.this.unregisterReceiver(receiver);
}
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
답변
당신은 쉽게 할 수 있습니다 ….
1) 부울 변수 생성 …
private boolean bolBroacastRegistred;
2) 방송 수신기를 등록 할 때 TRUE로 설정하십시오.
...
bolBroacastRegistred = true;
this.registerReceiver(mReceiver, new IntentFilter(BluetoothDevice.ACTION_FOUND));
....
3) onPause ()에서 …
if (bolBroacastRegistred) {
this.unregisterReceiver(mReceiver);
bolBroacastRegistred = false
}
그냥 이제는 onPause ()에 더 많은 예외 오류 메시지가 표시되지 않습니다.
팁 1 : 항상 onDestroy ()가 아닌 onPause ()에서 unregisterReceiver ()를 사용하십시오. 팁 2 : unregisterReceive ()를 실행할 때 bolBroadcastRegistred 변수를 FALSE로 설정하는 것을 잊지 마십시오
성공!