Вызов метода активности из BroadcastReceiver на Android
Здесь я создаю онлайн-приложение, которое зависит только от Интернета.
Поэтому всякий раз, когда возникает сетевая ошибка, он должен уведомлять пользователя. Для этого я создал BroadcastReciver, который получает вызов, когда сетевое соединение теряется (Интернет).
Все это прекрасно работает. Теперь мне нужно, чтобы я вызывал метод Activity из этого широковещательного приемника, где я создал диалог оповещений.
Я прочитал много ответов на stack-overflow.com, что могу объявить этот метод статическим и вызовом, используя только имя Activity,
e.g MyActivityName.myMethod()
Но я не могу объявить свой метод static, потому что я использую Alert Dialogue там, и он показывает мне ошибку в строке,
AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
что не может использовать это в статическом контексте.
Итак, как я могу вызвать метод Activity (не должен статически и не запускать эту активность) из широковещательного приемника?
И могу ли я получить имя Activity (или фрагмента) из широковещательного приемника, который в настоящее время запущен?
Ответы
Ответ 1
попробуйте этот код:
ваш класс вещательного класса для утраченного класса в Интернете:
public class InternetLostReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
context.sendBroadcast(new Intent("INTERNET_LOST"));
}
}
в вашей активности добавьте это для вызова трансляции:
public class TestActivity extends Activity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
registerReceiver(broadcastReceiver, new IntentFilter("INTERNET_LOST"));
}
BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// internet lost alert dialog method call from here...
}
};
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(broadcastReceiver);
}
}
Ответ 2
Добавьте логическую переменную в вашу деятельность, откуда вы открыли alertdialog
boolean isDialogOpened = false;
// in broadcast recever check
if(isDialogOpened) {
alertDialog();
}
И замените свой код для alertdialog на этот
public void alertDialog() {
AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
alertDialog.setMessage("Network not found.");
alertDialog.setPositiveButton("Check Setting",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
}
});
alertDialog.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
}
});
alertDialog.setOnDismissListener(new OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
isDialogOpened = false;
}
});
alertDialog.setOnCancelListener(new OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
isDialogOpened = false;
}
});
alertDialog.show();
}
Ответ 3
Передать контекст своей деятельности в конструктор BroadcastReceiver.
public class ResponseReceiver extends BroadcastReceiver{
MainActivity ma; //a reference to activity context
public ResponseReceiver(MainActivity maContext){
ma=maContext;
}
@Override
public void onReceive(Context context, Intent intent) {
ma.brCallback("your string"); //calling activity method
}
}
и в вашем MainActivity
public class MainActivity extends AppCompatActivity {
...
public void onStart(){
...
ResponseReceiver responseReceiver = new ResponseReceiver(this); //passing context
LocalBroadcastManager.getInstance(this).registerReceiver(responseReceiver,null);
...
}
public void brCallback(String param){
Log.d("BroadcastReceiver",param);
}
}
надеюсь, что это поможет
Ответ 4
ИНТЕРФЕЙС: Держите BroadCastReceiver и код активности отдельно!
Вы можете сделать интерфейс CallBackListener. Интерфейс будет работать как мост между BroadcastReceiver
и Activity
.
1) Создать CallbackListener
interface ConnectionLostCallback{
public void connectionLost();
}
2) Предоставьте ConnectionLostCallback
в вашем BroadcastReceiver
public class MyBroadcastReceiver extends BroadcastReceiver{
private ConnectionLostCallback listener;
public MyBroadcastReceiver(ConnectionLostCallback listener ){
this.listener = listener //<-- Initialze it
}
@Override
public void onReceive(Context context, Intent intent) {
listener.connectionLost();
}
}
3) Реализуйте ConnectionLostCallback
в вашей деятельности и переопределите метод
YourActvity extends AppcompatActivity implements ConnectionLostCallback{
// Your Activity related code //
// new MyBroadcastReceiver(this); <-- create instance
private void showAlertMessage(){
AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
}
@Override
public void connectionLost(){
showAlertMessage(); //<--- Call the method to shoe alert dialog
}
}
Соответствующая ссылка:
Если вы хотите знать, как сделать BroadcastReceiver независимым от какого-либо действия, т.е. как вы можете повторно использовать один и тот же BroadCastReceiver для разных действий? Тогда ПРОЧИТАЙТЕ ЭТО
Ответ 5
То же, что и ответ Виджю, но вместо этого используется локальное вещание
public class SampleReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Intent intentToBroadcast = new Intent(YOUR_ACTION_HERE");
intentToBroadcast.putExtras(bundle); // if any
LocalBroadcastManager.getInstance(context).sendBroadcast(intentToBroadcast);
}
}
В вашей деятельности добавьте это
public class SampleActivity extends Activity {
@Override
protected void onResume() {
super.onResume();
LocalBroadcastManager.getInstance(this).registerReceiver(mSampleReceiver, new IntentFilter(YOUR_ACTION_HERE));
}
@Override
protected void onPause() {
LocalBroadcastManager.getInstance(this).unregisterReceiver(mSampleReceiver);
super.onPause();
}
private SampleReceiver mSampleReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// your code here
}
};
}
Примечание Переместите регистрацию/отмену регистрации вызовов в onCreate/onDestroy, если вы хотите получать уведомления, даже если ваша деятельность находится в фоновом режиме.