Програмно зареєструвати приймач широкомовної програми


149

Мені хотілося б знати, яка найкраща практика / спосіб програмно зареєструвати приймач радіомовлення. Я хочу зареєструвати конкретні приймачі за вибором користувача.

Оскільки реєстрація здійснюється через файл маніфесту, мені цікаво, чи є правильний спосіб досягти цього в коді.


2
CoderzPassion Трансляція найкращого детального підручника коли-небудь
karanatwal.github.io

Будь ласка , зверніться цю Link 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 (). Компонент приймача в першу чергу корисний, коли вам потрібно переконатися, що ваш додаток запускається щоразу, коли передача трансляції.


1
Розумний! Ти мене зрозумів прямо. Дуже дякую
CoolStraw

Хороший - не мав уявлення, що ти можеш це зробити :)
Кріс Нолдус


1
@hackbod Як додати тег метаданих у спеціальний приймач? У вас є ідея !! Мені потрібно додати тег метаданих, який ми використовуємо в androidmanifest.xml.
Зала Джанаксінь

1
Кращий підручник до дати coderzpassion.com/implement-broadcastreceiver-android та простою мовою
Jagjit Singh

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 (i);
Бен Клейтон

7
чому б не взяти участь у резюме та на початку?
Syed Raza Mehdi

Що буде, якщо я не скасую реєстрацію приймача мовлення? Чи залишить цей приймач зареєстрованим навіть після перезавантаження?
Джейдев

5
Це не гарантовано, що onDestroy()буде викликано, таким чином створивши потенційну витік пам'яті. Краще зареєструватися / скасувати реєстрацію в onStart()/ onStop().
Neria Nachum

Чи означає це, що мені не потрібно створювати клас приймача широкомовної передачі? Я міг просто помістити сюди весь свій код onReceive (), і він буде працювати?
Taslim Oseni

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, швидше за все, знищить вашу програму, в результаті чого ваші програмно зареєстровані приймачі більше не працюватимуть, але зареєстрований маніфест все одно буде працювати.
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();
}

Для детального посібника ознайомтеся з приймачем широкомовної передачі - двома способами реалізації .


найкращий приклад до цих пір я знайшов! Дякую!
Аюш Гоял

1
@SohailAziz Посилання дає хорошу відповідь. Чи можете ви поставити контекст посилання у своїй відповіді, так що якщо посилання знизиться, ваша відповідь залишається актуальною?
iRuth

на мою особисту думку, трансляцію слід реєструвати в програмі onResume і onPause, як ви запропонували, але деякі люди кажуть, що вона повинна бути в режимі onCreate і onDestroy, чи можете ви пояснити плюси і мінуси обох?
Syed Raza Mehdi

2
@SyedRazaMehdi, якщо трансляція використовується для оновлення користувальницького інтерфейсу [що в більшості випадків], ви повинні зареєструвати його в onResume та скасувати реєстрацію в OnPause, оскільки інше мовлення буде марно.
SohailAziz

Спасибі.Це найкраща відповідь.
Saeid 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) для отримання додаткової інформації.


1
Я спробував зателефонувати, context.registerReceiverале його не зателефонували, чи можете ви подивіться на це питання stackoverflow.com/questions/13238600/…
Полювання

2

Найкраще практика завжди надавати дозвіл під час реєстрації приймача, інакше ви отримаєте будь-яку програму, яка надсилає відповідні наміри. Це може дозволити шкідливим програмам транслюватись на ваш приймач.


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

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 (увімкнено = вірно, експортовано = помилково)]

public class BCReceiver : BroadcastReceiver
{

    BCReceiver receiver;

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

Додайте цей код від своєї діяльності:

LocalBroadcastManager.getInstance(ApplicationContext)
    .registerReceiver(receiver, filter);
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.