Программно зарегистрировать приемник вещания

149

Я хотел бы знать, какова наилучшая практика / способ программной регистрации приемника вещания. Я хочу зарегистрировать конкретных получателей по выбору пользователя.

Поскольку регистрация выполняется через файл манифеста, мне интересно, есть ли правильный способ добиться этого в коде.

CoolStraw
источник
2
CoderzPassion Broadcast Reciever - лучший подробный учебник за всю историю
karanatwal.github.io
Пожалуйста, обратитесь по этой ссылке stackoverflow.com/questions/15698790/…

Ответы:

64

Похоже, вы хотите контролировать, активны ли компоненты, опубликованные в вашем манифесте, а не динамически регистрировать получателя (через Context.registerReceiver ()) во время работы.

Если это так, вы можете использовать PackageManager.setComponentEnabledSetting () для управления активностью этих компонентов:

http://developer.android.com/reference/android/content/pm/PackageManager.html#setComponentEnabledSetting(android.content.ComponentName, int, int)

Обратите внимание, если вы заинтересованы только в получении трансляции во время работы, лучше использовать registerReceiver (). Компонент приемника в первую очередь полезен для случаев, когда вам необходимо убедиться, что ваше приложение запускается при каждой отправке трансляции.

hackbod
источник
1
Умная ! Вы меня правильно поняли. Большое спасибо
CoolStraw
Хороший - понятия не имел, что ты мог бы сделать это :)
Крис Нолдус
это похоже на stackoverflow.com/questions/24140894/…
Анкит Шривастава
1
@hackbod Как добавить метаданные в пользовательский приемник? Есть идеи? Мне нужно добавить тег метаданных, который мы используем в androidmanifest.xml.
Зала Джанаксин
1
Лучший учебник до даты coderzpassion.com/implement-broadcastreceiver-android и на простом языке
Джагджит Сингх
269

В вашем onCreateметоде вы можете зарегистрировать получателя следующим образом:

private BroadcastReceiver receiver;

@Override
public void onCreate(Bundle savedInstanceState){

  // your oncreate code should be

  IntentFilter filter = new IntentFilter();
  filter.addAction("SOME_ACTION");
  filter.addAction("SOME_OTHER_ACTION");

  receiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
      //do something based on the intent's action
    }
  };
     registerReceiver(receiver, filter);
}

Не забудьте запустить это в onDestroyметоде:

 @Override
 protected void onDestroy() {
  if (receiver != null) {
   unregisterReceiver(receiver);
   receiver = null;
  }
  super.onDestroy();
 }
Эрик Нордвик
источник
19
Спасибо, это сработало отлично. Для отправки трансляции я использовал код Intent i = new Intent ("SOME_ACTION"); sendBroadcast (я);
Бен Клейтон,
7
почему не в резюме и на старте?
Сайед Раза Мехди
Что будет, если я не откажусь от регистрации приемника вещания? Оставит ли трансляционный ресивер зарегистрированным даже после перезагрузки?
Джейдев
5
Не гарантируется, что onDestroy()вызов будет вызван, тем самым создавая потенциальную утечку памяти. Лучше зарегистрироваться / отменить регистрацию в onStart()/ onStop().
Нерия Нахум
Означает ли это, что мне не нужно создавать класс приемника вещания? Я мог бы просто разместить здесь весь мой код onReceive (), и это сработало бы?
Таслит Осень
70

Один важный момент, о котором люди забывают упомянуть, это время жизни Broadcast Receiver. Отличие программной регистрации от регистрации в AndroidManifest.xml состоит в том, что. В файле манифеста это не зависит от времени жизни приложения. Хотя при программной регистрации это зависит от времени жизни приложения. Это означает, что если вы зарегистрируетесь в AndroidManifest.xml , вы сможете поймать транслируемые намерения, даже если ваше приложение не запущено.

Редактировать: упомянутое примечание больше не относится к Android 3.1, система Android исключает все получатели из намерений получения по умолчанию, если соответствующее приложение никогда не запускалось пользователем или если пользователь явно остановил приложение через меню Android (в Управление → Приложение). https://developer.android.com/about/versions/android-3.1.html

Это дополнительная функция безопасности, поскольку пользователь может быть уверен, что только приложения, которые он запустил, будут получать намерения вещания.

Таким образом, можно понимать, что получатели, программно зарегистрированные в Приложении, onCreate()будут иметь тот же эффект, что и получатели , объявленные в AndroidManifest.xml от Android 3.1 выше.

криптон
источник
1
Это хорошая заметка. Я на самом деле смотрю на книгу, которую я читаю об Android, и удивляюсь, почему были реализованы оба способа реализации трансляции. Мне кажется, что это для обратной совместимости. Но я не уверен, хотя.
Neon Warge
Ну, ты правда считаешь, что редактирование правда? Я имею в виду последнее предложение. Android может убить ваше приложение в любое время, что приведет к тому, что ваши программно зарегистрированные получатели больше не будут работать, но зарегистрированный манифест будет работать.
JacksOnF1re
40

Определите приемник вещания в любом месте действия / фрагмента следующим образом:

mReceiver = new BroadcastReceiver() {
 @Override
 public void onReceive(Context context, Intent intent) {
     Log.d(TAG," onRecieve"); //do something with intent
   }
 };

Определить IntentFilter в onCreate()

mIntentFilter=new IntentFilter("action_name");

Теперь зарегистрируйте BroadcastReciever в onResume()и отмените его регистрацию onPause()[потому что трансляция не используется, если действие приостановлено].

@Override
protected void onResume() {
     super.onResume();
     registerReceiver(mReceiver, mIntentFilter);
}

@Override
protected void onPause() {
    if(mReceiver != null) {
            unregisterReceiver(mReceiver);
            mReceiver = null;
    }
    super.onPause();
}

Для подробного руководства взгляните на приемник вещания - два способа реализации .

SohailAziz
источник
лучший пример, который я нашел! Спасибо!
Аюш Гоял
1
@SohailAziz Ссылка дает хороший ответ. Не могли бы вы указать контекст ссылки в своем ответе, чтобы в случае отказа ссылки ваш ответ оставался актуальным?
iRuth
по моему личному мнению, трансляция должна быть зарегистрирована в onResume и onPause, как вы и предлагали, но некоторые люди говорят, что трансляции должны быть на onCreate и onDestroy. Можете ли вы объяснить плюсы и минусы для обоих?
Сайед Раза Мехди
2
@SyedRazaMehdi, если широковещательная рассылка используется для обновления пользовательского интерфейса [что в большинстве случаев], вы должны зарегистрировать ее в onResume и отменить регистрацию в onPause, поскольку широковещательная передача в противном случае будет бесполезной.
Сохаил Азиз
Спасибо. Это лучший ответ.
Саид Z
4
package com.example.broadcastreceiver;


import android.app.Activity;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.widget.Toast;

public class MainActivity extends Activity {

   UserDefinedBroadcastReceiver broadCastReceiver = new UserDefinedBroadcastReceiver();

   @Override
   public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
   }

   @Override
   public boolean onCreateOptionsMenu(Menu menu) {
      getMenuInflater().inflate(R.menu.main, menu);
      return true;
   }

   /**
    * This method enables the Broadcast receiver for
    * "android.intent.action.TIME_TICK" intent. This intent get
    * broadcasted every minute.
    *
    * @param view
    */
   public void registerBroadcastReceiver(View view) {

      this.registerReceiver(broadCastReceiver, new IntentFilter(
            "android.intent.action.TIME_TICK"));
      Toast.makeText(this, "Registered broadcast receiver", Toast.LENGTH_SHORT)
            .show();
   }

   /**
    * This method disables the Broadcast receiver
    *
    * @param view
    */
   public void unregisterBroadcastReceiver(View view) {

      this.unregisterReceiver(broadCastReceiver);

      Toast.makeText(this, "unregistered broadcst receiver", Toast.LENGTH_SHORT)
            .show();
   }
}
Сунил Пандей
источник
1
Можете ли вы объяснить ОП, почему это лучшая практика?
Мартин Прикрыл
1
Они не объясняют, «они» всегда публикуют код, потому что это намного лучше, вы знаете. -сарказм
Неон Вардж
2

В соответствии с прослушиванием и трансляцией глобальных сообщений, а также настройкой будильника в общих задачах и как их выполнять в Android :

Если получающий класс не зарегистрирован с использованием его манифеста, вы можете динамически создать экземпляр и зарегистрировать получателя, вызвав Context.registerReceiver () .

Посмотрите на registerReceiver (приемник BroadcastReceiver, фильтр IntentFilter) для получения дополнительной информации.

McStretch
источник
1
Я пытался позвонить, context.registerReceiverно звонить не получилось. Пожалуйста, посмотрите на этот вопрос stackoverflow.com/questions/13238600/…
Охота
2

Рекомендуется всегда указывать разрешение при регистрации получателя, в противном случае вы получите уведомление для любого приложения, которое отправляет соответствующее намерение. Это может позволить вредоносным приложениям транслироваться на ваш приемник.

ChopperCharles
источник
1

для LocalBroadcastManager

   Intent intent = new Intent("any.action.string");
   LocalBroadcastManager.getInstance(context).
                                sendBroadcast(intent);

и зарегистрируйтесь в onResume

LocalBroadcastManager.getInstance(
                    ActivityName.this).registerReceiver(chatCountBroadcastReceiver, filter);

и отмените регистрацию onStop

LocalBroadcastManager.getInstance(
                ActivityName.this).unregisterReceiver(chatCountBroadcastReceiver);

и получить это ..

mBroadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            Log.e("mBroadcastReceiver", "onReceive");
        }
    };

где IntentFilter

 new IntentFilter("any.action.string")
Zar E Ahmer
источник
1

Два варианта

1) Если вы хотите читать трансляцию только тогда, когда видимость видна,

registerReceiver(...) в onStart()и unregisterReceiver(...)вonStop()

2) Если вы хотите читать трансляцию, даже если активность находится в фоновом режиме,

registerReceiver(...)в onCreate(...)и unregisterReceiver(...)вonDestroy()

Бонус:

Если ты ленивый

Если вы не хотите писать стандартный код для регистрации и отмены регистрации BroadcastReceiver снова и снова в каждом действии, тогда,

  1. Создать абстрактную активность
  2. Напишите шаблонный код в разделе «Деятельность».
  3. Оставьте реализацию как абстрактные методы

Вот фрагмент кода:

Абстрактная деятельность

public abstract class BasicActivity extends AppCompatActivity {

    private BroadcastReceiver broadcastReceiver;
    private IntentFilter filter;
    private static final String TAG = "BasicActivity";

    /**********************************************************************
    *                   Boilerplate code
    **********************************************************************/

    @Override
    public void onCreate(Bundle sis){
        super.onCreate(sis);
        broadcastReceiver = getBroadcastReceiver();
        filter = getFilter();
    }

    @Override
    public void onStart(){
        super.onStart();
        register();
    }

    @Override
    public void onStop(){
        super.onStop();
        unregister();
    }

    private void register(){
        registerReceiver(broadcastReceiver,filter);
    }

    private void unregister(){
        unregisterReceiver(broadcastReceiver);
    }

    /**********************************************************************
    *                   Abstract methods
    **********************************************************************/

    public abstract BroadcastReceiver getBroadcastReceiver();

    public abstract IntentFilter getFilter();

}

Используя этот подход, вы можете написать больше стандартного кода, такого как написание общих анимаций, привязка к сервису и т. Д.

Смотрите полный код:

ВОТ

Рохит Сингх
источник
0

Создать приемник вещания

[BroadcastReceiver (Enabled = true, Exported = false)]

public class BCReceiver : BroadcastReceiver
{

    BCReceiver receiver;

    public override void OnReceive(Context context, Intent intent)
    {
        //Do something here
    }
}

Из вашей деятельности добавьте этот код:

LocalBroadcastManager.getInstance(ApplicationContext)
    .registerReceiver(receiver, filter);
fulgen
источник