Программно зарегистрировать приемник вещания
Я хотел бы знать, какова наилучшая практика / способ программной регистрации приемника вещания. Я хочу зарегистрировать конкретных получателей по выбору пользователя.
Поскольку регистрация выполняется через файл манифеста, мне интересно, есть ли правильный способ добиться этого в коде.
9 ответов
Похоже, вы хотите контролировать, активны ли компоненты, опубликованные в вашем манифесте, а не динамически регистрировать получателя (через Context.registerReceiver()) во время работы.
Если это так, вы можете использовать PackageManager.setComponentEnabledSetting() для управления активностью этих компонентов:
http://developer.android.com/reference/android/content/pm/PackageManager.html
Обратите внимание, если вы заинтересованы только в получении трансляции во время работы, лучше использовать registerReceiver(). Компонент приемника в первую очередь полезен для случаев, когда вам необходимо убедиться, что ваше приложение запускается при каждой отправке трансляции.
В вашем 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();
}
Один важный момент, о котором люди забывают упомянуть, это время жизни 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 выше.
Определите приемник вещания в любом месте в Activity/Fragment, как это:
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();
}
Для подробного руководства взгляните на широковещательный приемник - два способа реализации.
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) Если вы хотите читать трансляцию только тогда, когда видимость видна,
registerReceiver(...
) в onStart()
а также unregisterReceiver(...)
в onStop()
2) Если вы хотите читать трансляцию, даже если активность находится в фоновом режиме,
registerReceiver(...)
в onCreate(...)
а также unregisterReceiver(...)
в onDestroy()
Бонус:
Если ты ленивый
Если вы не хотите писать стандартный код для регистрации и отмены регистрации BroadcastReceiver снова и снова в каждом действии, тогда,
- Создать абстрактную активность
- Напишите шаблонный код в Activity
- Оставьте реализацию как абстрактные методы
Вот фрагмент кода:
Абстрактная деятельность
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();
}
Используя этот подход, вы можете написать больше стандартного кода, такого как написание обычной анимации, привязка к сервису и т. Д.
Смотрите полный код:
Рекомендуется всегда указывать разрешение при регистрации получателя, в противном случае вы получите уведомление для любого приложения, которое отправляет соответствующее намерение. Это может позволить вредоносным приложениям транслироваться на ваш приемник.
Для 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")
В соответствии с прослушиванием и трансляцией глобальных сообщений, а также установкой будильника в общих задачах и как их выполнять в Android:
Если получающий класс не зарегистрирован с использованием его манифеста, вы можете динамически создать экземпляр и зарегистрировать получателя, вызвав Context.registerReceiver().
Посмотрите на registerReceiver(приемник BroadcastReceiver, фильтр IntentFilter) для получения дополнительной информации.
Создать приемник вещания
[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);