Service中弹Dialog

当我们直接在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 B a d T o k e n E x c e p t i o n : U n a b l e t o a d d w i n d o w a n d r o i d . v i e w . V i e w R o o t I m p l 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);
    }
}

猜你喜欢

转载自blog.csdn.net/hello_1s/article/details/80941159