Показать предупреждение в широковещательном приемнике после перезагрузки системы
Добрый день, я пытаюсь показать диалоговое окно предупреждения после перезагрузки системы в широковещательном приемнике. Я добавил получателя в свой манифест и вызвал требуемое разрешение, но получаю сообщение об ошибке. Пожалуйста, как я могу реализовать это правильно?.. Спасибо.
мой код:
public void onReceive(final Context context, Intent intent) {
Log.d(TAG, "received boot completed broadcast receiver... starting settings");
String settings = context.getResources().getString(R.string.restart_setting);
String yes = context.getResources().getString(R.string.Settings);
String no = context.getResources().getString(R.string.Cancel);
final AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setMessage(settings)
.setCancelable(false)
.setPositiveButton(yes, new DialogInterface.OnClickListener() {
public void onClick(@SuppressWarnings("unused") final DialogInterface dialog, @SuppressWarnings("unused") final int id)
Intent config = new Intent(context, WeatherConfigure.class)
context.startActivity(config);
}
})
.setNegativeButton(no, new DialogInterface.OnClickListener() {
public void onClick(final DialogInterface dialog, @SuppressWarnings("unused") final int id) {
dialog.cancel();
}
});
final AlertDialog alert = builder.create();
alert.show();
}
Получение этой ошибки журнала:
01-07 01:42:01.559: ERROR/AndroidRuntime(2004): Caused by: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
01-07 01:42:01.559: ERROR/AndroidRuntime(2004): at android.view.ViewRoot.setView(ViewRoot.java:548)
01-07 01:42:01.559: ERROR/AndroidRuntime(2004):at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:177)
01-07 01:42:01.559: ERROR/AndroidRuntime(2004): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
01-07 01:42:01.559: ERROR/AndroidRuntime(2004):at android.app.Dialog.show(Dialog.java:288)
01-07 01:42:01.559: ERROR/AndroidRuntime(2004):at com.MuaaApps.MyWeatherUpdate.myWeatherBroadcastReceiver.onReceive(MyWeatherBroadcastReceiver.java:59)
01-07 01:42:01.559: ERROR/AndroidRuntime(2004): at android.app.ActivityThread.handleReceiver(ActivityThread.java:1994)
Ответы
Ответ 1
Проблема заключается в том, что вы пытаетесь показать AlertDialog
из BroadcastReceiver
, что недопустимо. Вы не можете показать AlertDialog
из BroadcastReceiver
. Только действия могут отображать диалоги.
Вы должны сделать что-то еще, запустить BroadcastReceiver
при загрузке, как вы это делаете, и запустить действие, чтобы показать диалог.
Ниже приведено сообщение в блоге.
EDIT:
Вот как я бы рекомендовал это сделать. Из вашего BroadcastReceiver
запустите Activity
с AlertDialog
как таковым..
public class NotifySMSReceived extends Activity
{
private static final String LOG_TAG = "SMSReceiver";
public static final int NOTIFICATION_ID_RECEIVED = 0x1221;
static final String ACTION = "android.provider.Telephony.SMS_RECEIVED";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
IntentFilter filter = new IntentFilter(ACTION);
this.registerReceiver(mReceivedSMSReceiver, filter);
}
private void displayAlert()
{
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Are you sure you want to exit?").setCancelable(
false).setPositiveButton("Yes",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
}).setNegativeButton("No",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alert = builder.create();
alert.show();
}
private final BroadcastReceiver mReceivedSMSReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (ACTION.equals(action))
{
//your SMS processing code
displayAlert();
}
}
}
}
Как вы видите здесь, я НИКОГДА не называл setContentView()
. Это связано с тем, что активность будет иметь прозрачный вид и будет отображаться только окно предупреждения.
Ответ 2
Вы не можете использовать диалог BroadcastReceiver,
поэтому вместо этого вы лучше вызываете действие для диалогового окна из BroadcastReceiver,
добавьте этот код в свою функцию onReceive:
@Override
public void onReceive(Context context, Intent intent)
{
Intent i = new Intent(context, {CLASSNAME}.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
заполните {CLASSNAME} активностью диалогового окна, вот что я вижу в диалоговом режиме:
package com.example.mbanking;
import android.os.Bundle;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
// ALERT DIALOG
// Sources : http://techblogon.com/alert-dialog-with-edittext-in-android-example-with-source-code/
public class AlertDialogActivity extends Activity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder
.setTitle("Test")
.setMessage("Are you sure you want to exit?")
.setCancelable(false)
.setPositiveButton("Yes", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int id)
{
dialog.cancel();
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int id)
{
dialog.cancel();
}
});
AlertDialog alert = builder.create();
alert.show();
}
}
где я получил ответ?, здесь: Как вы используете диалоговое окно предупреждения в широковещательном приемнике в Android?
благодаря Феми!!, я просто распространяю новости: D
Ответ 3
Вот post о том, как это сделать. Вы можете получить исходный код здесь.
Вы не можете отобразить диалоговое окно непосредственно из вашего широковещательного приемника. Вы должны использовать Activity
. Кроме того, чтобы получить ACTION_BOOT_COMPLETED
, ваша активность должна быть сначала явно запущена пользователем или другим приложением (для остановки доступа к состоянию приложения google).
В принципе, для достижения требуемой функциональности вам необходимо:
- Создать прозрачную активность, отображающую диалог.
- Создайте
BroadcastReceiver
, который получает ACTION_BOOT_COMPLETED
и начинает вашу деятельность.
- Зарегистрируйте приемник вещания в манифесте и получите соответствующее разрешение.
Кроме того, этот вопрос предоставляет дополнительную информацию о том, как создать прозрачную активность.
Ответ 4
Лучший способ - сделать действие и установить его атрибут "Тема" в "Theme.Translucen"
<activity
android:name=".MyAlertDialog"
android:label="@string/title_activity_alert_dialog"
android:launchMode="singleInstance"
android:theme="@android:style/Theme.Translucent" >
</activity>
и в вашей активности создайте диалоговое окно "Предупреждение":
public class MyAlertDialog extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE); //hide activity title
setContentView(R.layout.activity_my_alert_dialog);
AlertDialog.Builder Builder=new AlertDialog.Builder(this)
.setMessage("Do You Want continue ?")
.setTitle("exit")
.setIcon(android.R.drawable.ic_dialog_alert)
.setNegativeButton(R.string.No, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
MyAlertDialog.this.finish();
}
})
.setPositiveButton(R.string.Yes,null);
AlertDialog alertDialog=Builder.create();
alertDialog.show();
}
}
и в brodcastreciver:
@Override
public void onReceive(Context context, Intent intent) {
Intent i=new Intent(context.getApplicationContext(),MyAlertDialog.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
}
Ответ 5
Это может быть старый и ответный поток, но ответ на него не помог вообще.
Вы не можете запустить всплывающее диалоговое окно в вашей реализации onReceive(). BroadcastReceiver
Вместо диалогов или popupWindow вы можете использовать активность, которая называется в диалоговом окне
<activity
android:taskAffinity=""
android:name=".activity.CallActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme.Dialog" />
Обратите внимание, что я добавляет taskAffinity внутри блока (AndroidManifest.xml)
Затем вы можете просто использовать его как обычные действия.
Intent intentPhoneCall = new Intent(context, CallActivity.class);
intentPhoneCall.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intentPhoneCall.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intentPhoneCall);
Надеюсь, это поможет. Счастливые кодировки.
Ответ 6
- Отобразить диалог из широковещательного приемника невозможно.
- мы должны показывать только диалог из Activity.
- Но ваш контекст приложения имеет только широковещательный приемник, тогда мы должны запустить его как "FLAG_ACTIVITY_NEW_TASK", затем он создает стек.
-
Если мы запустим действие с этим флагом "FLAG_ACTIVITY_NEW_TASK", мы не сможем удалить его из стека.
-
Итак, после закрытия приложения, мы пытаемся запустить приложение из стека, оно показывает одно и то же действие, потому что это действие имеет флаг FLAG_ACTIVITY_NEW_TASK, поэтому он не должен создавать новый экземпляр и использовать существующий экземпляр.
Но мы хотим показать диалог только один раз. для этого нам нужно обращаться с программным союзником.
if (count == 0) {
mBuilder = new Dialog(this);
mMsg = getIntent().getStringExtra(AlarmSchedulerUtils.EXTRA_MSG);
Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
mRingTome = RingtoneManager.getRingtone(ReminderDialog.this, notification);
mRingTome.play();
count++;
showReminderDialog();
} else {
Intent intent=new Intent(ReminderDialog.this,SplashActivity.class);
startActivity(intent);
finish();
}
Это сработало для меня.