11

AlertDialogManager我想通过类向non-activityDeviceAdminReceiverSample的方法显示警报对话框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

我知道问题出在context事情上,但我不知道该放什么让它起作用,我试过了thisgetApplicationContext()但都是徒劳的。我的两个类的代码如下

警报对话管理器

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

}

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

7 回答 7

42

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

alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);

或者如果上述方法不起作用,请尝试以下操作:

alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_APPLICATION_PANEL); 

并使用此权限:

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
于 2015-07-04T14:18:48.657 回答
13

问题是' You can show AlertDialogs from Activity only'​​。这不是上下文问题。

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

于 2013-06-12T07:10:56.240 回答
8

如果您总是想从应用程序中的任何位置获取当前活动,您可以在您的应用程序实例上注册一个 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();
    }

}

然后要在整个应用程序中使用它,你会做一些这样的调用......

Activity activity = ((TestApp)getApplicationContext()).getCurrentActivity(); 

优点是您可以始终跟踪您当前的活动,但是对于仅从 Activity 中处理 Dialogs 来说有点过分了。

于 2016-06-08T21:33:46.380 回答
1

在活动类中调用此方法

public static void showAlert(Activity activity, String message) {

        TextView title = new TextView(activity);
        title.setText("Title");
        title.setPadding(10, 10, 10, 10);
        title.setGravity(Gravity.CENTER);
        title.setTextColor(Color.WHITE);
        title.setTextSize(20);

        AlertDialog.Builder builder = new AlertDialog.Builder(activity);
        // builder.setTitle("Title");
        builder.setCustomTitle(title);
        // builder.setIcon(R.drawable.alert_36);

        builder.setMessage(message);

        builder.setCancelable(false);
        builder.setNegativeButton("OK", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int id) {
                dialog.cancel();

            }

        });

        AlertDialog alert = builder.create();
        alert.show();
    }
于 2013-06-12T07:12:57.653 回答
0

这是我制作和使用的:

myDialog.java:

import android.app.Activity;
import android.content.DialogInterface;
import android.support.v7.app.AlertDialog;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;

public class myDialog {
    private Activity mActivity;

    myDialog(Activity a) {
        this.mActivity = a;
    }

    @SuppressWarnings("InflateParams")
    public void build(String title, String msg) {
        LayoutInflater inflater = LayoutInflater.from(mActivity);
        View subView = inflater.inflate(R.layout.dialog_box_text, null);
        final TextView message = subView.findViewById(R.id.message);
        message.setText(msg);
        AlertDialog.Builder builder = new AlertDialog.Builder(mActivity);
        builder.setTitle(title);
        builder.setView(subView);
        builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
            }
        });
        AlertDialog alert = builder.create();
        alert.show();
    }
}

dialog_box_text.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:weightSum="1"
    android:orientation="horizontal">
    <TextView
        android:id="@+id/message"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="  "
        android:maxLines="1"
        android:textColor="@color/colorBlack" />
</LinearLayout>

示例代码:

public class MainActivity extends AppCompatActivity {
    private myDialog md;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        md = new myDialog(this);

...

        md.build("Title", "Message");
于 2018-04-04T05:01:05.857 回答
-2

您可以在 MainActivity 中使用初始值 (this) 定义一个公共 Context var;如这里所示:

public class MainActivity< alertdail > extends AppCompatActivity {

    ////////////////////////////////////////////////////////////
    //Public var refers to Main Activity:
    Context mainActivity = this;
    ////////////////////////////////////////////////////////////

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate ( savedInstanceState );
        setContentView ( R.layout.activity_main );
        AlertDialogManager alert  =new AlertDialogManager ();
alert.showAlertDialog ( this,"Title","Message",true );


     }


    public class AlertDialogManager {

        public void showAlertDialog(Context context, String title, String message,
                                    Boolean status) {
            final AlertDialog alertDialog = new AlertDialog.Builder ( mainActivity ).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 ( );
        }

        public void showAlertDialog(Context c) {
        }
    }


    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 );
        }
    }
}
于 2020-04-09T18:23:14.117 回答
-3

这是正确执行此任务的一种快速方法,它为我完成了这项工作。基本上,你要做的只是创建一个新线程。


  1. 声明一个类型与原始活动类匹配的公共静态变量。

    public static Activity1 activity;

Activity1 是变量所在的类。


  1. 在调用方法onCreate();时,将变量设置为等于活动的上下文,否则称为this

例子:

@Override 
    protected void onCreate( Bundle savedInstanceState ) {
    super.onCreate( savedInstanceState );
    activity = this;
}


3. 由于我们现在有了活动的上下文,我们可以使用它来创建一个带有警报对话框的函数,方法是使用runOnUiThread();函数内部调用警报对话框的方法。我们将 anew Runnable()用于 所需的可运行操作runOnUiThread();,并且要真正打开警报对话框,我们将覆盖可运行项的 run 函数并将警报对话框的代码放在那里。

示例函数:

public static void exampleDialog(){
Activity1.activity.runOnUiThread(new Runnable){
@Override
    public void run(){
    //alert dialog code goes here.  For the context, use the activity variable from Activity1.
        }
    }
}

希望这可以帮助 :)

于 2017-04-09T19:52:42.753 回答