当我们直接在service的生命周期中创建一个dialog并调用show()方法让他显示的时候,会得到一个报错: Unable to add window – token null is not for an application
因为我们知道Dialog必须放在一个Window上,以往都是放到Activity上,所以不会出现这样的错误,那我们联想一下在service中打开一个Activity的时候是怎么做的!没错添加一个flag,现在我们给dialog的window设置一个类型
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
注意:必须在dialog.show()方法之前设置这句话
添加之后再次运行依然报错:android.view.WindowManager
W@24a537cb – permission denied for this window type
看到这个就知道是权限的问题
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
但是在手机的系统版本高于23的时候需要获得用户的同意才可以所以:
if (Build.VERSION.SDK_INT >= 23) {
if (!Settings.canDrawOverlays(getApplicationContext())) {
//启动Activity让用户授权
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
startActivity(intent);
return;
} else {
//执行6.0以上绘制代码
}
} else {
//执行6.0以下绘制代码
}
参考Android6.0以上绘制系统级悬浮窗异常 permission denied for window type 2002
综上问题就解决了
由于只是简单的想测试一下,所以使用的开启服务,代码如下:
public class DialogService extends Service {
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("提示");
builder.setIcon(R.mipmap.ic_launcher);
builder.setMessage("我是服务的对话框");
AlertDialog dialog = builder.create();
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
dialog.show();
return super.onStartCommand(intent, flags, startId);
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
public class ServiceActivity extends AppCompatActivity {
private Button btn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_service);
btn = findViewById(R.id.btn);
if (Build.VERSION.SDK_INT >= 23) {
if (!Settings.canDrawOverlays(getApplicationContext())) {
//启动Activity让用户授权
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
startActivity(intent);
return;
} else {
//执行6.0以上绘制代码
}
} else {
//执行6.0以下绘制代码
}
}
public void btnOnClick(View view) {
Intent intent = new Intent(this, DialogService.class);
startService(intent);
}
}