版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/u013260551/article/details/51927271


    我们知道,平常使用的dialog是依赖于activity的,那么我们是否可以在Service中使用dialog弹出框呢?
    但是我们也知道,系统在比如电量过低,或者按下关机键时,不论在那个界面,都会弹出系统级对话框。
    所以从理论上来说是可以的。
    在Service中弹出对话框常用的方法如下:

    1. AlertDialog dialog = alertDialog.create();
    2. dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
    3. dialog.show();

    还需在AndroidManifest.xml文件中添加如下权限:

    1. <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

    不过,很遗憾,在Android6.0上,运行后闪退显示如下错误:
    java.lang.RuntimeException: Unable to create service com.science.test.MyService: android.view.WindowManager$BadTokenException: Unable to add window android.view.ViewRootImpl$W@aa4c25e -- permission denied for this window type
    这是因为google在6.0上对应用权限进行了优化,需要单独开启:

    1. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    2. if (!Settings.canDrawOverlays(this)) {
    3. Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
    4. Uri.parse("package:" + getPackageName()));
    5. startActivityForResult(intent, 1);
    6. }
    7. }
    8. @Override
    9. protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    10. if (requestCode == 1) {
    11. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    12. if (!Settings.canDrawOverlays(this)) {
    13. // SYSTEM_ALERT_WINDOW permission not granted...
    14. }
    15. }
    16. }
    17. }

    第一次安装进入到该界面时,需要跳到如下界面:
    image.png
    不过在MIUI中,问题比较多。
    无论是基于Android6.0,5.x,4.4的MIUI中(手上只有4.4+版本的MIUI8,MIUI7貌似~也差不多),在给dialog弹窗添加TYPE_SYSTEM_ALERT,且不添加Settings.canDrawOverlays(this)时,MIUI对弹窗做了权限控制,默认关闭(基于Andorid6.0不会FC,因为MIUI没有使用原生的权限管理):
    image.png
    所以,以上方法不是最好的。
    但是,我们知道原生Toast是不需要权限就能显示的,是否可以把TYPE_SYSTEM_ALERT改为TYPE_TOAST呢?很遗憾,MIUI中还是默认关闭,而其他(包括Android6.0)可以正常显示(不再需要在程序清单文件里添加权限)。
    不过,既然原生Toast可以不需要权限且在任意系统上可以显示,就说明肯定可以有办法,没错,就是对Toast进行扩展封装,解决办法如下博客:
    http://blog.csdn.net/xyq046463/article/details/51840586
    当然,还有一个办法,那就是直接跳转到一个dialog类型的Activity,简单粗暴。


    参考:
    http://stackoverflow.com/questions/32061934/permission-from-manifest-doesnt-work-in-android-6
    http://blog.csdn.net/xyq046463/article/details/51840586
    http://www.liaohuqiu.net/cn/posts/android-windows-manager/
    http://www.jianshu.com/p/634cd056b90c