BroadcastReceiver onReceive запускается при регистрации

У меня есть широковещательный приемник, который запускается в тот момент, когда он зарегистрировался (и впоследствии перезапущен с onPause/onResume), неужели это неправильное поведение? Я что-то пропустил?

class FooActivity extends Activity {    

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        broadcastReceiver = new FooBroadcastReceiver();
        intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
    }

    @Override
    protected void onResume() {
        super.onResume();
        registerReceiver(connectivityReceiver, intentFilter);         
    }

    @Override
    protected void onPause() {
        super.onPause();
        unregisterReceiver(connectivityReceiver);
    }


class MyBroadcastReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {       
        if (connectivityAction(intent)) {
            Log.d("footag", "onReceive");
        }
    }

    private boolean connectivityAction(Intent intent) {
        return ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction());
    }

}

Ответ 1

Спасибо за ответы! Мое решение было результатом их всех, переключившись на манифест объявленного приемника и включив/отключив компонент приемника в onResume/onPause, остановив липкий характер получателя. И, включив/отключив компонент, я могу подумать, что я гражданин второго сорта.

@Override
protected void onResume() {
    super.onResume();
    setReceiverState(PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
}

@Override
protected void onPause() {
    super.onPause();
    setReceiverState(PackageManager.COMPONENT_ENABLED_STATE_DISABLED);
}


private void setReceiverState(int receiverState) {
    ComponentName receiver = new ComponentName(this, FooBroadcastReceiver.class);
    PackageManager pm = this.getPackageManager();
    pm.setComponentEnabledSetting(receiver, receiverState,       
    PackageManager.DONT_KILL_APP);
}

AndroidManifest.xml

<receiver android:name="com.example.receiver.FooBroadcastReceiver">
  <intent-filter>
    <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
  </intent-filter>
</receiver>

Ответ 2

Передача CONNECTIVITY_ACTION, похоже, липкая на некоторых устройствах (хотя документация подразумевает, что это не так). Это означает, что когда вы зарегистрируете приемник, он немедленно вызовет onReceive() с самой последней переданной трансляцией. Поскольку вы регистрируетесь и не регистрируетесь в onPause() и onResume(), вы получите много вызовов onReceive(). Возможно, вы захотите сделать это по-другому.

Ответ 3

Здесь другое решение, которое сработало для меня:

class FooActivity extends Activity {    

    private Intent mReceiverRegisteringIntent;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        broadcastReceiver = new FooBroadcastReceiver();
        intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
    }

    @Override
    protected void onResume() {
        super.onResume();
        mReceiverRegisteringIntent = registerReceiver(connectivityReceiver, intentFilter);         
    }

    @Override
    protected void onPause() {
        super.onPause();
        unregisterReceiver(connectivityReceiver);
    }


    private class MyBroadcastReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {       
            if (connectivityAction(intent)) {
                Log.d("footag", "onReceive");
                //if mReceiverRegisteringIntent is not null, then this is the sticky
                //broadcast received when registering the receiver for the first time
                if (mReceiverRegisteringIntent != null) {
                    //set it to null for future broadcasts
                    mReceiverRegisteringIntent = null;
                    return; //do nothing
                }

                //logic for future broadcasts
                ...
            }
        }

        private boolean connectivityAction(Intent intent) {
            return ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction());
        }
    }

}

Я предполагаю, что MyBroadcastReceiver является внутренним классом для FooActivity, поэтому он может получить доступ к mReceiverRegisteringIntent

Ответ 4

удалите следующие две строки, они не будут запущены в onPause и onResume!

registerReceiver(connectivityReceiver, intentFilter);
unregisterReceiver(connectivityReceiver);