我遇到了从Service显示AlertDialog的问题。我可以使用Toast或使用WindowManager(TYPE_SYSTEM_ALERT或TYPE_SYSTEM_OVERLAY)显示自定义布局窗口。但是,我不想使用自定义布局,我更喜欢直接使用不错的AlertDialog GUI。
情景:
AlertDialog.Builder(this)
创建)错误:
ERROR/AndroidRuntime(1063): Caused by: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
搜索答案会让我觉得我正在尝试一些目前无法实现的功能(Android 2.2)。或者也许是。
答案 0 :(得分:25)
找到了符合描述情景的解决方案。
已创建新活动并从服务启动。但是,它是半透明背景的活动。此类活动在super.setContentView()
中没有行onCreate()
。更重要的是,确保透明度
@android:风格/ Theme.Translucent
。因此,添加到清单xml的新行是
android:theme="@android:style/Theme.Translucent"
在onCreate()
实际显示AlertDialog
按下AlertDialog按钮会导致Dialog和Activity关闭并发送Intent(或使用其他方法)将结果传递给服务。
确保为Dialog定义了setOnDismissListener()(实现应该在activity上调用finish())。如果你不这样做,请按返回键取消对话框,但让你进入当前活动,这是透明的,并向用户看,就像是非常错误。
答案 1 :(得分:6)
感谢您的解决方案。 我遇到了同样的问题,并在你的帮助下解决了问题。
我把这个答案只是为了分享我将结果传递回服务的方式。
我没有创建任何额外的自定义意图类,只通过Intent.putExtra()
方法解决了结果传递问题。
在服务中,使用此代码启动DialogActivity
,在onCreate()
中显示警告对话框。
Intent intent = new Intent(this.getApplicationContext(), DialogActivity.class);
intent.putExtra(DialogActivity.CLASS_KEY, this.getClass().getCanonicalName());
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
在DialogActivity
中,完成如下:
private void returnOk(boolean ok) {
Intent srcIntent = this.getIntent();
Intent tgtIntent = new Intent();
String className = srcIntent.getExtras().getString(CLASS_KEY);
Log.d("DialogActivity", "Service Class Name: " + className);
ComponentName cn = new ComponentName(this.getApplicationContext(), className);
tgtIntent.setComponent(cn);
tgtIntent.putExtra(RESULT_KEY, ok ? RESULT_OK : RESULT_CANCEL);
this.startService(tgtIntent);
this.finish();
}
最后,在服务中,覆盖onStartCommand()
方法并从意图中获取结果。
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
int ret = super.onStartCommand(intent, flags, startId);
Bundle extras = intent.getExtras();
if (extras != null) {
int result = extras.getInt(DialogActivity.RESULT_KEY, -1);
if (result >= 0) {
if (result == DialogActivity.RESULT_OK) {
// Your logic here...
}
} else {
// Your other start logic here...
}
}
return ret;
}
我不确定这种方式是否是一个很好的解决方案,至少它对我有用。希望这对像我这样的人有用。
完整的来源可以在这里找到: