国内第三方Rom在Android6.0以下系统的权限适配
2017-07-18 17:05
225 查看
我们都知道,在 Android 6.0 以下系统,在我们的 app 中需要使用到某权限时,只需要在 AndroidManifest 文件中声明,app 在安装时就会默认授权。但是在 Android 6.0 以后,Android 系统修改了权限机制,即原有的权限分为安全权限和危险权限,其中,危险权限不仅需要在 AndroidManifest 文件中声明,还需要在 app 运行时提示用户手动授权。
关于 Android 6.0 以上动态权限的申请,此类文章有很多,我就不多说了。我这里主要讲一下我在适配国内第三方 ROM 中遇到的一些坑。
在动态权限申请这一机制出现之后,国内的手机厂商也很快针对其系统进行了升级,也加入了这一机制,但是他们的 ROM 很多都是基于 Android 5.0 或 5.1 定制的,这就给开发者留下了一个大坑。我们在 6.0 以下系统调用 checkSelfPermission() 这样的 API 判断是否授权时,只要你在 AndroidManifest 文件中声明过,系统都是默认授权的,但是小米、魅族这样的第三方 ROM 中,权限可能已经被禁止,这时程序就可能会崩溃。所以我们无法通过系统提供的 API 来判断是否授权。这里我的处理方式就是在可能 Crash 的地方进行 try/catch 。在 catch 代码中弹出权限申请提示框,提示用户去打开相关权限。
这时最好的处理方式就是在把错误 try catch 出来,但是在哪里 try 呢?
每个自定义相机都要实现 SurfaceHolder.Callback 接口
我是在 surfaceChanged onResume 方法中对相机进行初始化的地方进行 try 的,在 catch 代码中弹出权限申请提示框,提示用户去授权。
app默认不授予该权限,其他型号手机没有权限时不会弹出对话框,但也不会报错,但是部分手机会崩溃,比如说乐视,错误日志如下:
不得不说吐槽一下 Android 的碎片化问题,各种机型适配到你想吐。
问题还是得解决,当然这里使用 try 的方法也可以,但我为了方便,就使用了一个 Dialog 样式的 Activity 来代替系统悬浮窗,这样就避免了很多问题。
将启动模式设置为 singleTop 是为了防止同时弹出多个 Dialog
还需要注意一点,如果要在 Service 中启动 Activity 的话,要加上如下一句:
以上就是我在进行权限适配时踩过的一些坑,本人还是菜鸟一枚,如果有什么不合理的地方,请多多指教。
关于 Android 6.0 以上动态权限的申请,此类文章有很多,我就不多说了。我这里主要讲一下我在适配国内第三方 ROM 中遇到的一些坑。
在动态权限申请这一机制出现之后,国内的手机厂商也很快针对其系统进行了升级,也加入了这一机制,但是他们的 ROM 很多都是基于 Android 5.0 或 5.1 定制的,这就给开发者留下了一个大坑。我们在 6.0 以下系统调用 checkSelfPermission() 这样的 API 判断是否授权时,只要你在 AndroidManifest 文件中声明过,系统都是默认授权的,但是小米、魅族这样的第三方 ROM 中,权限可能已经被禁止,这时程序就可能会崩溃。所以我们无法通过系统提供的 API 来判断是否授权。这里我的处理方式就是在可能 Crash 的地方进行 try/catch 。在 catch 代码中弹出权限申请提示框,提示用户去打开相关权限。
Camera权限
在打开自定义相机时,需要使用 Camera 权限,这里又有一个坑。如果是打开系统相机,小米、魅族手机是不需要 Camera 权限的,可以直接打开,但是华为手机必须要开启 Camera 权限才可以,这里需要注意。如果权限被禁用,就会出现如下异常:Caused by: java.lang.RuntimeException: Camera is being used after Camera.release() was called at android.hardware.Camera.native_getParameters(Native Method) at android.hardware.Camera.getParameters(Camera.java:3195) at com.mine.app.activity.cargowork.TakePhotoActivity.setupCamera(TakePhotoActivity.java:559) at com.mine.app.activity.cargowork.TakePhotoActivity.startPreview(TakePhotoActivity.java:542) at com.mine.app.activity.cargowork.TakePhotoActivity.onResume(TakePhotoActivity.java:499) at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1317) at cn.jiguang.a.a.c.a.a.d.callActivityOnResume(Unknown Source) at android.app.Activity.performResume(Activity.java:6213) at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3376) ... 11 more
这时最好的处理方式就是在把错误 try catch 出来,但是在哪里 try 呢?
每个自定义相机都要实现 SurfaceHolder.Callback 接口
我是在 surfaceChanged onResume 方法中对相机进行初始化的地方进行 try 的,在 catch 代码中弹出权限申请提示框,提示用户去授权。
悬浮窗权限
实际开发中,经常会需要在 Servcie 中弹出 Dialog ,这时我们需要给 Dialog 设置 TYPE_SYSTEM_ALERT 属性,设置该属性后,该 Dialog 就会变成系统提示框,想要正常显示的话需要开启悬浮窗权限。app默认不授予该权限,其他型号手机没有权限时不会弹出对话框,但也不会报错,但是部分手机会崩溃,比如说乐视,错误日志如下:
Caused by: android.view.WindowManager$BadTokenException: Unable to add window android.view.ViewRootImpl$W@eaa60b4 -- permission denied for this window type at android.view.ViewRootImpl.setView(ViewRootImpl.java:724) at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:322) at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:85) at android.app.Dialog.show(Dialog.java:325) at com.mine.app.jpush.MyReceiver.otherStateType(MyReceiver.java:978) at com.mine.app.jpush.MyReceiver.onReceive(MyReceiver.java:219) at android.app.ActivityThread.handleReceiver(ActivityThread.java:3016) ... 8 more
不得不说吐槽一下 Android 的碎片化问题,各种机型适配到你想吐。
问题还是得解决,当然这里使用 try 的方法也可以,但我为了方便,就使用了一个 Dialog 样式的 Activity 来代替系统悬浮窗,这样就避免了很多问题。
<activity android:name=".activity.DialogActivity" android:launchMode="singleTop" android:theme="@style/dialogstyle"/>
将启动模式设置为 singleTop 是为了防止同时弹出多个 Dialog
<style name="dialogstyle"> <!--设置dialog的背景--> <item name="android:windowBackground">@color/transport</item> <!--设置Dialog的windowFrame框为无--> <item name="android:windowFrame">@null</item> <!--设置无标题--> <item name="android:windowNoTitle">true</item> <!--是否浮现在activity之上--> <item name="android:windowIsFloating">true</item> <!--是否半透明--> <item name="android:windowIsTranslucent">true</item> <!--设置窗口内容不覆盖--> <item name="android:windowContentOverlay">@null</item> <!--设置动画,在这里使用让它继承系统的Animation.Dialog--> <item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item> <!--背景是否模糊显示--> <item name="android:backgroundDimEnabled">true</item> </style>
还需要注意一点,如果要在 Service 中启动 Activity 的话,要加上如下一句:
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
以上就是我在进行权限适配时踩过的一些坑,本人还是菜鸟一枚,如果有什么不合理的地方,请多多指教。
相关文章推荐
- 关于android6.0权限适配6.0系统以下的问题总结(二维码扫描)
- Android6.0以下系统判断相机权限
- Android6.0以下系统判断相机权限
- Android6.0系统以下的麦克风权限处理
- Android app实现自更新和安装,权限检测适配Android6.0以下和Android6.0和Android7.0和Android8.0总结篇
- Android 悬浮窗权限各机型各系统适配大全
- android相机权限适配遇到的坑(包含6.0和6.0以下)
- Android中获取系统通讯录联系人并解决Android6.0权限问题
- Android6.0系统适配桌面歌词效果
- 解决wsimport 带https协议wdsl 时报错的处理 (解决mac系统默认不开启1024以下端口权限问题 )
- Android6.0适配权限封装类(仿RxPromission,比之更加解耦)
- Android6.0系统动态获取权限<一>
- Android 悬浮窗权限各机型各系统适配大全(总结)
- Vue + Element UI 实现权限管理系统 前端篇(十一):第三方图标库
- Android短信拦截机制适配的坑--4.4以下系统
- Android6.0运行是权限在某些手机适配问题(小米手机)
- Android中系统应用适配未知来源的管理权限
- [RK3288][Android6.0] 调试笔记 --- 无法安装需系统权限的apk问题
- Android6.0权限适配
- Android6.0权限适配之WRITE_EXTERNAL_STORAGE(SD卡写入)