转载请标明出处:
http://blog.csdn.net/DJY1992/article/details/77942568
本文出自:【奥特曼超人的博客】
很多人问小米系统是不是需要单独处理授权问题,其实授权问题都是类似的,在Android 5.0之后系统权限要求越来越严格,当然,5.0系统bug比较多,兼容性不太好,所以出来没多久就直接问世了,在Android 6.0之后才趋于平稳,系统更新也比较快,权限问题也是我们必须处理的一个问题,还有一点,就是7.0之后的某些版本使用吐司Toast会引起crash。
我们来看下权限的流程:
- 弹出对话框询问
- 成功则进入
- 失败进入询问
- 失败则“设置”
- 拒绝不处理
SDK里所带的悬浮窗功能所需权限是WindowManager,在android官网可以看到7.0之后更新的相关内容, 如果想查看android 7.0 之后权限存储有什么不同的可以看这篇文章《Android 7.0之访问文件的权限和FileProvider类》,包括申请悬浮窗的权限问题。
如果拒绝权限则会出现以下异常:
可以看到报了Unable to add window
和 permission denied for this window type
android.view.WindowManager$BadTokenException: Unable to add window android.view.ViewRootImpl$W@8d2524d -- permission denied for this window type
at android.app.ActivityThread.handleCreateService(ActivityThread.java:2887)
at android.app.ActivityThread.-wrap4(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1427)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
所以我们xml配置文件记得要把权限配置上,在Android 7.0之前都是可以正常使用的,包括7.0的系统,但是如果在7.1.1没有进行特别处理的话是会出现如下错误:
可以看到报了Unable to add window
和 has already been added
android.view.WindowManager$BadTokenException: Unable to add window -- window android.view.ViewRootImpl$W@326f7b2 has already been added
at android.view.ViewRootImpl.setView(ViewRootImpl.java:691)
at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:342)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:94)
at android.widget.Toast$TN.handleShow(Toast.java:434)
at android.widget.Toast$TN$2.handleMessage(Toast.java:345)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
那是因为 WindowManagerGlobal 在 AddView 的时候会进行预处理 View,此处更新的标志位是TYPE_TOAST,在handle里面增加了TYPE_PHONE,所以我们在申请悬浮窗处理的时候也要增加判断,不然则会抛出异常。
其实很简单,在申请的时候增加下判断就可以了。
解决方法:
WindowManager.LayoutParams wmParamsDu = new WindowManager.LayoutParams();
windowManager = (WindowManager) context.getSystemService(context.WINDOW_SERVICE);
if (Build.VERSION.SDK_INT > 24) {
wmParamsDu.type = WindowManager.LayoutParams.TYPE_PHONE;
} else {
wmParamsDu.type = WindowManager.LayoutParams.TYPE_TOAST;
}
申请权限可参考:
try {
Class clazz = Settings.class;
Field field = clazz.getDeclaredField(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
Intent intent = new Intent(field.get(null).toString());
Log.i("FLAG_ACTIVITY_NEW_TASK","Karl-Dujinyang");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setData(Uri.parse("package:" + context.getPackageName()));
context.startActivity(intent);
} catch (Exception e) {
Log.e("Exception", "permission "+e.getMessage());
}
注意:注意 WindowManagerGlobal 中的View,也包括Toast,所以如果在调用时用了Toast就会报错,会报同样的错误,Unable to add window -- window
和 has already been added
,吐司崩溃,如果想要使用Toast,也是需要增加判断的。
|| 版权声明:本文为博主杜锦阳原创文章,转载请注明出处。