Receiver가 Android에 등록되어 있는지 확인하는 방법

등록 된 수신자가 등록되어 있는지 확인해야한다면 어떻게해야합니까?



답변

이 스레드 를 고려하면 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);
        }
    }
}


답변

몇 가지 옵션이 있습니다

  1. 수업이나 활동에 깃발을 넣을 수 있습니다. 부울 변수를 클래스에 넣고이 플래그를보고 수신자가 등록되어 있는지 확인하십시오.

  2. 수신자를 확장하는 클래스를 작성하면 다음을 사용할 수 있습니다.

    1. 프로젝트에서이 클래스의 인스턴스가 하나만있는 싱글 톤 패턴.

    2. 수신자가 등록되어 있는지 알 수있는 방법을 구현하십시오.


답변

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로 설정하는 것을 잊지 마십시오

성공!