最近又听人聊到Android能不能在service中弹出对话框的问题,于是总结一下
答案是肯定的,系统可以在低电量的时候弹出电量不足的提示,那么我们也可以按同样的方法做到
下面介绍在service中弹出对话框的两种方法:
1.将dialog的Type设置为TYPE_SYSTEM_ALERT
写一个service代码如下:
public class DialogService extends Service {
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
showDialog();
return super.onStartCommand(intent, flags, startId);
}
private void showDialog() {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
AlertDialog dialog = new AlertDialog.Builder(getApplicationContext()).setTitle("title")
.setMessage("这是一个由service弹出的对话框")
.setCancelable(false)
.setPositiveButton("button confirm", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
}
})
.create();
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
dialog.show();
}
}, 3 * 1000);
}
}
为了方便测试,我们让dialog延迟3s出现,运行代码之后发现抛出了异常
android.view.WindowManager
W@3ca3d69d – permission denied for this window type
原因是缺少相关权限,于是在AndroidMainfest.xml中添加权限,再次运行观察结果,如期弹出了dialog,如下面几种截图,可以发现在开启service之后,不管当前处于应用内还是应用外,甚至在其他应用内,都弹出了dialog。
2.将Activity设置成dialog主题弹出
将activity设置成dialog主题需要再AndroidManifest.xml中加上android:theme=”@android:style/Theme.Dialog”
相关代码如下:
private void showDialog2() {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
Intent intent = new Intent(getApplicationContext(), DialogActivity.class);
startActivity(intent);
}
}, 3 * 1000);
}
运行出错
android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
需要将activity的启动模式设置为Intent.FLAG_ACTIVITY_NEW_TASK,重新设置之后运行如下:
值得注意的是,这种方式在弹出对话框的时候,会先跳转到我们的应用,然后再弹出对话框。