从android中的非活动类显示对话框警报

Saq*_*qib 10 android android-alertdialog

我想通过AlertDialogManager类向一个non-activityDeviceAdminReceiverSample的方法显示一个Alert Dialog onDisabled,但每当我alertDialog通过该方法调用它时,它会生成以下文本的错误

错误

06-12 12:01:19.923: E/AndroidRuntime(468): FATAL EXCEPTION: main
06-12 12:01:19.923: E/AndroidRuntime(468): java.lang.RuntimeException: Unable to start           
receiver com.android.remotewipedata.DeviceAdminReceiverSample:   
android.view.WindowManager$BadTokenException: Unable to add window -- token null is not   
for an application
Run Code Online (Sandbox Code Playgroud)

我知道这个问题与context事情有关,但我不知道该放什么,以便它起作用,我试过this,getApplicationContext()但都是徒劳的.我的两个类的代码如下

AlertDialogManager

public class AlertDialogManager {

public void showAlertDialog(Context context, String title, String message,
        Boolean status) {
    final AlertDialog alertDialog = new AlertDialog.Builder(context).create();
    alertDialog.setTitle(title);
    alertDialog.setMessage(message);

    if (status != null)
        alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                alertDialog.dismiss();
            }
        });
    alertDialog.show();
}
Run Code Online (Sandbox Code Playgroud)

}

DeviceAdminReceiverSample

public class DeviceAdminReceiverSample extends DeviceAdminReceiver {
static final String TAG = "DeviceAdminReceiver";
AlertDialogManager alert = new AlertDialogManager();

/** Called when this application is no longer the device administrator. */
@Override
public void onDisabled(Context context, Intent intent) {
    super.onDisabled(context, intent);
    Toast.makeText(context, R.string.device_admin_disabled,
            Toast.LENGTH_LONG).show();
    // intent.putExtra("dialogMessage", "Device admin has been disabled");
    // intent.setClass(context, DialogActivity.class);
    // intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    // context.startActivity(intent);
    alert.showAlertDialog(context, "Alert",
            "Device admin has been disabled", true);
}
Run Code Online (Sandbox Code Playgroud)

Eli*_*uta 40

只需在你之前加上这个 alertDialog.show();

alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
Run Code Online (Sandbox Code Playgroud)

并使用此权限:

alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_APPLICATION_PANEL); 
Run Code Online (Sandbox Code Playgroud)

  • 我认为我们不应该使用这个..因为它将在完整的android系统中显示警报,无论在哪个应用程序用户...以及第二次触摸警报外,它不是解雇.如果你想为你的应用做任何动作,那么它可能会崩溃 (3认同)
  • 很好的发现。谢谢。根据文档,添加到该解决方案中,`使应用程序可以使用TYPE_SYSTEM_ALERT类型打开窗口,该窗口显示在所有其他应用程序的顶部。很少有应用程序应使用此权限;这些窗口用于与用户进行系统级交互。因此,在使用此解决方案时,我们还需要注意。 (2认同)

Pan*_*mar 13

问题是' You can show AlertDialogs from Activity only'.这不是背景问题.

虽然从接收器显示对话框不是一个好主意(更好的是使用通知),但是如果你想这样做,你可以创建一个 Activity作为对话框并显示


Chr*_*van 7

如果您总是希望从应用程序中的任何位置获取当前活动,则可以在Application实例上注册ActivityLifecycleCallback.

这是一个未经测试的实现,可能会让您更接近.

public class TestApp extends Application {

    private WeakReference<Activity> mActivity = null;

    @Override
    public void onCreate() {
        super.onCreate();
        registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
            @Override
            public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
                mActivity = new WeakReference<Activity>(activity);
            }

            @Override
            public void onActivityDestroyed(Activity activity) {
                mActivity.clear();
            }

            /** Unused implementation **/
            @Override
            public void onActivityStarted(Activity activity) {}

            @Override
            public void onActivityResumed(Activity activity) {}
            @Override
            public void onActivityPaused(Activity activity) {}

            @Override
            public void onActivityStopped(Activity activity) {}

            @Override
            public void onActivitySaveInstanceState(Activity activity, Bundle outState) {}
        });
    }

    public Activity getCurrentActivity() {
        return mActivity.get();
    }

}
Run Code Online (Sandbox Code Playgroud)

然后在整个应用程序中使用它,你会做这样的电话......

Activity activity = ((TestApp)getApplicationContext()).getCurrentActivity(); 
Run Code Online (Sandbox Code Playgroud)

优点是你可以随时跟踪你当前的活动,但是对于仅从Activity中处理Dialogs来说它有点过分.