source

리시버가 안드로이드에 등록되어 있는지 어떻게 확인합니까?

manysource 2023. 7. 29. 08:36

리시버가 안드로이드에 등록되어 있는지 어떻게 확인합니까?

등록된 수신기가 아직 등록되어 있는지 확인해야 하는데 그렇지 않다면 어떻게 확인해야 합니까?

수신자 등록 여부를 확인할 수 있는 API 기능이 없습니다.해결 방법은 코드를 다음에 넣는 것입니다.try catch block as done below.

try {

 //Register or UnRegister your broadcast receiver here

} catch(IllegalArgumentException e) {

    e.printStackTrace();
}

스레드를 고려할 때 API가 직접 API를 제공하는지 확신할 수 없습니다.

저도 같은 것이 궁금했습니다.
저 같은 경우에는.BroadcastReceiver필요한 구현Context#unregisterReceiver(BroadcastReceiver)수신된 의도를 처리한 후 인수로 자신을 전달합니다.
수신기가 고장 났을 가능성이 조금 있습니다.onReceive(Context, Intent)메서드가 여러 개로 등록되어 있으므로 메서드를 두 번 이상 호출합니다.IntentFilters잠재력 창출IllegalArgumentException로부터 던져지기Context#unregisterReceiver(BroadcastReceiver).

이 경우 전화를 걸기 전에 확인할 개인 동기화된 구성원을 저장할 수 있습니다.Context#unregisterReceiver(BroadcastReceiver)그러나 API가 확인 방법을 제공한다면 훨씬 더 깨끗할 것입니다.

단순해

수신기:

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에 의해 앱이 중지된 경우에는 작동하지 않습니다. - 6시간 전입니다.

@amin - 코드(매니페스토 항목에 의해 등록된 시스템이 아님) 등록된 수신기의 수명 참조 :)

이 솔루션을 사용합니다.

public class ReceiverManager {
    private WeakReference<Context> cReference;
    private static List<BroadcastReceiver> receivers = new ArrayList<BroadcastReceiver>();
    private static ReceiverManager ref;

    private ReceiverManager(Context context) {
        cReference = new WeakReference<>(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 = cReference.get().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);
            cReference.get().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();
}

당신은 쉽게 할 수 있어요...

부울 변수 생성...

private boolean bolBroacastRegistred;

브로드캐스트 수신기를 등록할 때 TRUE로 설정합니다.

...
bolBroacastRegistred = true;
this.registerReceiver(mReceiver, new IntentFilter(BluetoothDevice.ACTION_FOUND));
....

On Pause()에서 수행...

if (bolBroacastRegistred) {
    this.unregisterReceiver(mReceiver);
    bolBroacastRegistred = false
}

이제 Pause()에 예외 오류 메시지가 더 이상 표시되지 않습니다.

팁 1: 항상 destroy()가 아닌 pause()에서 unregisterReceiver() 사용 팁 2: unregisterReceive()를 실행할 때 bolBroadcastRegistered 변수를 FALSE로 설정하는 것을 잊지 마십시오.

성공!

이것을 Destroy 또는 onStop 메서드에 장착하면 됩니다.활동이 다시 작성되었을 때 메시지 수신기가 작성되지 않은 것 같습니다.

@Override 
public void onDestroy (){
    super.onDestroy();
LocalBroadcastManager.getInstance(context).unregisterReceiver(mMessageReceiver);

}

개인적으로 저는 unregisterReceiver를 호출하고 예외가 던져지면 그것을 삼키는 방법을 사용합니다.저는 이것이 추하다는 것에 동의하지만 현재 제공되는 가장 좋은 방법입니다.

Android API에 수신기가 추가되었는지 확인하기 위해 부울 방식을 요청하는 기능을 제기했습니다.추가된 내용을 보려면 여기에서 지원하십시오. https://code.google.com/p/android/issues/detail?id=73718

브로드캐스트 수신자에게 기본 활동 스레드의 처리기 인스턴스를 알려주고 메시지를 사용하여 기본 활동에 메시지를 전달했습니다.

브로드캐스트 수신기가 이미 등록되어 있는지 확인하기 위해 이러한 메커니즘을 사용했습니다.브로드캐스트 수신기를 동적으로 등록하고 두 번 등록하지 않을 때 또는 브로드캐스트 수신기가 실행 중인 경우 사용자에게 표시할 때 필요한 경우가 있습니다.

주요 활동:

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();
        }
    }
    .........

}

}

나는 부모님의 활동에 이 코드를 넣었습니다.

등록된 수신자 나열 = 새 배열 목록<>();

@Override
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
    registeredReceivers.add(System.identityHashCode(receiver));
    return super.registerReceiver(receiver, filter);
}

@Override
public void unregisterReceiver(BroadcastReceiver receiver) {
    if(registeredReceivers.contains(System.identityHashCode(receiver)))
    super.unregisterReceiver(receiver);
}

당신의 문제를 이해합니다, 저는 제 애플리케이션에서 같은 문제에 직면했습니다.애플리케이션 내에서 registerReceiver()를 여러 번 호출했습니다.

이 문제에 대한 간단한 해결 방법은 사용자 지정 응용 프로그램 클래스의 레지스터Receiver()를 호출하는 것입니다.이렇게 하면 브로드캐스트 수신기가 전체 응용프로그램 수명 주기에서 하나만 호출됩니다.

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);

    }
}

이렇게 했습니다. ceph3us가 제공하고 slinden77이 편집한 답변의 수정된 버전입니다(다른 것들 중에서 저는 필요하지 않은 방법의 반환 값을 제거했습니다).

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());
    }
}

저에게 다음과 같은 것이 효과가 있었습니다.

if (receiver.isOrderedBroadcast()) {
   requireContext().unregisterReceiver(receiver);
}

신청을 닫더라도 브로드캐스터가 이미 등록되어 있는지 확인하기 위해 수행한 작업입니다(finish()).

응용 프로그램을 처음 실행할 때는 먼저 브로드캐스트를 보내십시오. 해당 브로드캐스트가 계속 실행 중인지 여부에 따라 true/false가 반환됩니다.

내 브로드캐스터

public class NotificationReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if(intent.getExtras() != null && intent.getStringExtra("test") != null){
            Log.d("onReceive","test");
            return;
        }
    }
}

내 기본 활동

// init Broadcaster
private NotificationReceiver nr = new NotificationReceiver();


Intent msgrcv = new Intent("Msg");
msgrcv.putExtra("test", "testing");
boolean isRegistered = LocalBroadcastManager.getInstance(this).sendBroadcast(msgrcv);

if(!isRegistered){
    Toast.makeText(this,"Starting Notification Receiver...",Toast.LENGTH_LONG).show();
    LocalBroadcastManager.getInstance(this).registerReceiver(nr,new IntentFilter("Msg"));
}
if( receiver.isOrderedBroadcast() ){
     // receiver object is registered
}
else{
     // receiver object is not registered
}

NullPointer를 확인하십시오.예외.수신기가 존재하지 않으면...

try{
    Intent i = new Intent();
    i.setAction("ir.sss.smsREC");
    context.sendBroadcast(i);
    Log.i("...","broadcast sent");
}
catch (NullPointerException e)
{
    e.getMessage();
}

언급URL : https://stackoverflow.com/questions/2682043/how-to-check-if-receiver-is-registered-in-android