Показать предупреждение в широковещательном приемнике после перезагрузки системы

Добрый день, я пытаюсь показать диалоговое окно предупреждения после перезагрузки системы в широковещательном приемнике. Я добавил получателя в свой манифест и вызвал требуемое разрешение, но получаю сообщение об ошибке. Пожалуйста, как я могу реализовать это правильно?.. Спасибо.

мой код:

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();
        }

Это сработало для меня.