从服务显示警报对话框时获取异常。
以下是我的Service类中的代码:我正在尝试显示AlertDialog。
但我收到错误:无法添加窗口 - 令牌null不适用于应用程序
我还将我的日志快照附加到此问题。
if(!mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)&& !mLocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)){
Log.d("TrackingService","H: Exception after this");
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Your GPS seems to be disabled, do you want to enable it?")
.setCancelable(false)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(final DialogInterface dialog, final int id) {
startActivity(new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS));
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(final DialogInterface dialog, final int id) {
dialog.cancel();
}
});
AlertDialog alert = builder.create();
alert.show();
}
答案 0 :(得分:21)
我有这个问题,但现在是solved
,如果您希望真的从服务运行alertDialog,您应该将对话框配置为系统警报并记住在AndroidManifest.xml中添加权限:
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
/以下是示例代码:
AlertDialog.Builder builder = new AlertDialog.Builder(ctx);
builder.setTitle("Test dialog");
builder.setIcon(R.drawable.icon);
builder.setMessage("Content");
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
//Do something
dialog.dismiss();
}
});
builder.setNegativeButton("Close", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
dialog.dismiss();
}
});
AlertDialog alert = builder.create();
alert.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
alert.show();
答案 1 :(得分:4)
创建你的gui时,你应该记住一些事情:
所有耗时的非gui工作都应该在后台完成(使用asyncTask,Services,Threads等)。
应始终从UIthreads创建和更新GUI(如视图和其他图形对象)。
因此创建和显示对话框是UI工作,因此它应该在UI线程中。要在UI线程中运行任何代码,您可以使用不同的方法,如:
我认为对于你的情况runOnUiThread是最好的所以使用
runOnUiThread (new Runnable() {
public void run ()
{
// WRITE YOUR PIECE OF CODE HERE TO UPDATE OR CREATE GUI.
}
});
要理解这个概念,这可以帮助您:
http://developer.android.com/guide/components/processes-and-threads.html
要创建广播,您可以使用:
步骤1:在您开始服务的活动中创建广播接收器。
BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("create_dialog")) {
// create your dialog here.
}
}
};
步骤2:创建广播接收器后注册接收器。
IntentFilter filter = new IntentFilter("create_dialog");
registerReceiver(receiver, filter);
步骤3:从您的服务发送广播到显示对话框。
Intent intent = new Intent("create_dialog");
intent.putExtra("dialog_data", data_object to display in dialog);
SendBroadcast(intent);
我希望这可以帮到你。
答案 2 :(得分:2)
使用 SYSTEM_ALERT_WINDOW 权限执行此操作,而不是创建新的透明活动
public void onReceive(Context ctx, Intent intent) {
LayoutInflater inflater = (LayoutInflater)ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View popup = inflater.inflate(R.layout.mypopup, null, false);
CustomDialog dialog = new CustomDialog(ctx, popup );
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
dialog.getWindow().getAttributes().windowAnimations = R.style.PauseDialogAnimation;
dialog.show();
}
答案 3 :(得分:1)
试试这个。
AlertDialog.Builder alertDialog = new AlertDialog.Builder(myContext);
编辑。
很抱歉没有评论。将启动服务的Context放在服务中并使用它。
class SomeService
{
private final Context myContext;
public WebService(Context myContext)
{
this.myContext= myContext;
}
public void showDialog()
{
AlertDialog d = new AlertDialog.Builder(myContext);
}
}
答案 4 :(得分:0)
您可以执行UI内容,例如仅在UI线程中显示AlertDialog
。
由于您的service
未在UI线程上运行,因此您将收到此异常。
尝试使用runOnUiThread
来显示提醒: -
if(!mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)&& !mLocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)){
runOnUiThread(new Runnable(){
public void run(){
Log.d("TrackingService","H: Exception after this");
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Your GPS seems to be disabled, do you want to enable it?")
.setCancelable(false)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(final DialogInterface dialog, final int id) {
startActivity(new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS));
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(final DialogInterface dialog, final int id) {
dialog.cancel();
}
});
AlertDialog alert = builder.create();
alert.show();
}
});
}