我希望通过AlertDialogManager
课程向non-activity
课程DeviceAdminReceiverSample
的方法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
我知道问题出在this
这个问题上,但我不知道该放在那里以便工作,我尝试了getApplicationContext()
,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();
}
但都是徒劳的。我的两个类的代码都在
AlertDialogManager
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);
}
}
DeviceAdminReceiverSample
{{1}}
答案 0 :(得分:37)
只需在alertDialog.show();
alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
or try following is above doesn't works:
alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_APPLICATION_PANEL);
并使用此权限:
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
答案 1 :(得分:13)
问题是“You can show AlertDialogs from Activity only
”。这不是背景问题。
虽然从接收器 显示对话框不是一个好主意(更好的是使用通知),但是如果你想这样做,你可以创建一个{{ 3}}
答案 2 :(得分:6)
如果您总是希望从应用程序中的任何位置获取当前活动,则可以在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();
}
}
然后在整个应用程序中使用它,您可以像这样打电话......
Activity activity = ((TestApp)getApplicationContext()).getCurrentActivity();
优点是你可以随时跟踪你当前的活动,但是对于仅从活动中处理对话来说它有点过分。
答案 3 :(得分: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();
}
答案 4 :(得分:0)
正如AJAY建议的那样,最好的方法是使用&#39;活动&#39;在参数中而不是使用&#39;上下文&#39;。
在您的个人班级中,只需在其构造函数中请求活动作为必填参数=&gt; public void constructorOfTheClass(Activity activity){...}。
当您在Activity中调用构造函数时,只需指出此参数,您就可以直接在类中使用它。
然后你可以使用这个&#39;活动&#39;您的类中的AlertDialog方法中的信息,因为SUNIL注意到在所需的活动中正确提示。
希望它有所帮助......并确保它能够正常工作! ; O)
答案 5 :(得分: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");
答案 6 :(得分:-1)
这是一个正确执行此任务的快速方法,它完成了我的工作。基本上,你要做的只是创建一个新的线程。
声明一个公共和静态变量,其类型与原始活动类匹配。
public static Activity1 activity;
Activity1是变量所在的类。
onCreate();
后,将变量设置为等于活动的上下文,也称为 this 。示例:
@Override
protected void onCreate( Bundle savedInstanceState ) {
super.onCreate( savedInstanceState );
activity = this;
}
<小时/> 3.由于我们现在拥有活动的上下文,我们可以使用它来创建一个带有警告对话框的函数,方法是使用调用警告对话框的函数内部的
runOnUiThread();
方法。我们将new Runnable()
用于runOnUiThread();
所需的可运行操作,并且实际打开警报对话框,我们将覆盖可运行项目的运行功能,并将警报对话框的代码放在那里。
示例功能:
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.
}
}
}
希望这会有所帮助:)
答案 7 :(得分:-2)
您可以在MainActivity中使用初始值(this)定义一个公共Context变量;如此处所示:
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 );
}
}
}