android-cn / android-discuss

Android 问题交流讨论坛, 微信公众号:codekk, 网站:
https://github.com/android-cn/android-discuss/issues
Apache License 2.0
4.08k stars 536 forks source link

如何检测程序是否获得了某项权限? #174

Open start141 opened 9 years ago

start141 commented 9 years ago

众所周知,MIUI、Flyme等Android定制系统在程序请求打开相机、录音等操作时,系统会先弹出对话框提示用户是否允许程序执行这些操作,如果用户选择允许,则接下来的操作一切正常,如果用户选择拒绝之后,程序后面的工作将无法正常允许,甚至崩溃。

提问:在这种情况下,如何判断用户是拒绝还是允许了操作? 目前我知道用try catch可以粗暴的判断,但我不确定所有的权限请求被拒绝后都会抛异常。

各位有更好的办法吗?

t12x3456 commented 9 years ago

PackageManager有个checkPermission(String permName, String pkgName)方法可以判断.返回PackageManager.PERMISSION_GRANTED即为已经授权,PackageManager.PERMISSION_DENIED为被拒绝. 当然这里要注意一点, 这个api没办法在所有机型上通用,某些系统上把特定权限的名字已经修改掉了. 另外定位权限比较特殊,没办法同步获取是否已授权.

start141 commented 9 years ago

checkPermission测试的是manifest有没有注册某项权限吧,并不能判断用户是否允许了某项权限。

t12x3456 commented 9 years ago

@start141 ,checkPermission就是用来判断用户是否授予权限的,比如是否开启获取联系人,录音的权限,你可以看下api,并且检验下,这个是具体的api解释:

public abstract int checkPermission (String permName, String pkgName)

Added in API level 1 Check whether a particular package has been granted a particular permission.

Parameters permName The name of the permission you are checking for, pkgName The name of the package you are checking against. Returns If the package has the permission, PERMISSION_GRANTED is returned. If it does not have the permission, PERMISSION_DENIED is returned. See Also PERMISSION_GRANTED PERMISSION_DENIED

start141 commented 9 years ago

api的注释我的理解是指menifest注册了权限就返回PERMISSION_GRANTED,否则就返回PERMISSION_DENIED。也可能是我理解错了。

不过重要的是这个方法我测试过,无效。

newtonker commented 9 years ago

@start141 楼主这个问题,最后有没有什么解决方案?

start141 commented 9 years ago

@newtonker 我目前知道的只有try catch,我们的app里面目前是用try catch来判断的。

newtonker commented 9 years ago

@start141 本来我也用的try catch,在其他手机上(华为,小米,魅族低版本)都是好的。但是在测试MX5 Android 5.1的系统时,在打开相机的那一刻,如果在弹出的权限对话框中拒绝了权限,会直接闪退。报的闪退居然是RuntimeException,Method called after release() 。但是我表示都正常release了。

public void releaseCamera() {
    if (camera != null) {
        camera.setPreviewCallback(null);
        camera.stopPreview();
        camera.release(); 
        camera = null;
    }
}
Qixingchen commented 9 years ago

Method called after release() 的意思是,你在release后又进行了操作。 可能是系统自动帮你release了,也可能是你的release函数在其他地方调用了,具体看报错栈才知道。

2015-08-24 13:50 GMT+08:00 newtonker notifications@github.com:

@start141 https://github.com/start141 本来我也用的try catch,在其他手机上(华为,小米,魅族低版本)都是好的。但是在测试MX5 Android 5.1的系统时,在打开相机的那一刻,如果在弹出的权限对话框中拒绝了权限,会直接闪退。报的闪退居然是RuntimeException,Method called after release() 。但是我表示都正常release了。 public void releaseCamera() { if (camera != null) { camera.setPreviewCallback(null); camera.stopPreview(); camera.release(); camera = null; } }

— Reply to this email directly or view it on GitHub https://github.com/android-cn/android-discuss/issues/174#issuecomment-134048452 .

start141 commented 9 years ago

这个问题可能是因为你在多个地方release()了,你可以在release()之后设置camera=null,下次release()的时候先判断camera是不是等于null。 还有可能是你try catch之后没有return后面的操作。

总之你看一次Log的错误行数吧,跟一下流程。@Qixingchen 已经说了原因。

newtonker commented 9 years ago

@Qixingchen , @start141 多谢你们两个人的帮助,我最终还是通过try catch解决了。MX 5 的相机权限和之前碰到的不一样。之前碰到华为,小米里弹出权限对话框时,如果禁止了相机权限,camera对象会返回null, MX 5 禁止了之后还是会返回一个相机对象,导致if(null != camera)方法判断无效了,所以会出现上面的问题。扩大了Exception的范围,捕获这个异常就行了。

1207229280 commented 8 years ago

我没做任何处理的话也不会出现异常 所以没办法catch 日志里只说明app不允许跳转

1207229280 commented 8 years ago

照相机权限

l123456789jy commented 8 years ago

手机里面不是有个应用权限列表吗?看下framework层的那个列表的权限状态,如何获取,能获取到这个我觉得就可以了!

Labmem003 commented 8 years ago

各位,除了try catch 外有新的进展吗?我在尝试发短信,需要检查android.permission.SEND_SMS权限,但是发短信这个调用连异常都不会抛出。。。

imhet commented 8 years ago

@Labmem003 小米手机上拒绝发送短信的权限异常确实没有抛出,可以加一个超时(比如3秒)没有返回短信是否发送成功的消息则判断发送短信权限被拒绝。

xilost commented 8 years ago

@newtonker 你好,我也遇到了和你一样的问题,同样是魅族手机。你说的“扩大了Exception的范围,捕获这个异常就行了。”,想问一下具体是扩大到什么地方呢。

xilost commented 8 years ago

@newtonker 懂了!太感谢了~

ssurprise commented 8 years ago

@xilost java.lang.RuntimeException: Camera is being used after Camera.release() was called 为什么我的是抱这样的错误。同样只是魅族MX5 有这样的问题

xilost commented 8 years ago

@jmbeizi 我的就是报这个错,用上面那个哥们的办法判断就好了。 @luffykou 你的问题应该是一样的。

ssurprise commented 8 years ago

@xilost @luffykou 我的问题已经处理了 。 解决办法也是来源自楼上。 主要是在入口那里判断的,而像QQ,微信也同样是在拍照入口那里的,并没有在预览页。 mCamera = Camera.open(i);//打开当前选中的摄像头( 这里对于大多数的设备是可以的) Camera.Parameters mParameters = mCamera.getParameters(); mCamera.setParameters(mParameters);(这里是对于魅族MX5 处理的,其他的设备未知) mCamera.startPreview();//开始预览(这里其实就可以不用了)

对于设备厂商的乱搞 真的是恶心透了

ssurprise commented 8 years ago

我把我的问题描述和解决方案放到博客里了 http://blog.csdn.net/jm_beizi/article/details/51728495

CaptainJno commented 8 years ago

我看了源码发现,Android内部其实也是通过捕获异常来判断摄像头权限是否开启的。大家可以看看android.hardware.Camera这个类,在第490行。

drakeet commented 8 years ago

魅族不按套路出牌,相机权限这里也是被坑过。 CaptainJno notifications@github.com于2016年7月9日 周六17:25写道:

我看了源码发现,Android内部其实也是通过捕获异常来判断摄像头权限是否开启的。大家可以看看android.hardware.Camera这个类,在第490行。

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/android-cn/android-discuss/issues/174#issuecomment-231525282, or mute the thread https://github.com/notifications/unsubscribe/AE-QBrXy7wwdT2-Q34G2XPyph096GxaDks5qT2kBgaJpZM4EizF1 .

zijing07 commented 8 years ago

有人判断过怎么获取 通知 功能有没有打开吗?android官方的库里,得到19、21才能用几个方法获得,有点坑

SeniorZhai commented 7 years ago

Flyme 在拒绝摄像头权限时,使用Camera2 API,会不受权限影响,正常使用

型号: M5 Note Android 版本: 6.0 版本号: Flyme 5.2.11.3A

  • PS:没有测试更多设备
sundxing commented 7 years ago

https://testerhome.com/topics/5181 关于 AppOpsManager.java 权限接口的介绍,没有做过实验,可以参考。

08carmelo commented 7 years ago

try catch + 数据异常判断,双重检测。比如录音,先try catch然后对录音数据做检测,关闭权限后录音数据byte全是0

详解:http://www.jianshu.com/p/7d255fa8247d

gordonpro commented 7 years ago

ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA);
貌似可以检测 6.0 以下的权限是否被 ROM自带的一些工具禁用。

我测试过三星,4.3 的系统,可以。

08carmelo commented 7 years ago

@androidmalin

http://www.jianshu.com/p/7d255fa8247d

star-andy commented 7 years ago

小米的定位权限我遇见过坑,后来是在miui的论坛上找到了个解决方法。 坑:在运行时申请权限时不管点允许还是拒绝都会走权限成功的回调 解决办法,在允许的回调内进行二次校验,代码如下

@TargetApi(Build.VERSION_CODES.KITKAT)
    @Override
    public void onPermissionGranted(PermissionGrantedResponse response) {
        final int version = Build.VERSION.SDK_INT;
        if (version >= 19) {
            AppOpsManager appOpsManager = (AppOpsManager) getSystemService(Context.APP_OPS_SERVICE);
            int checkOp = appOpsManager.checkOp(AppOpsManager.OPSTR_FINE_LOCATION, Process.myUid(), getPackageName());
            if (checkOp == AppOpsManager.MODE_IGNORED) {
                // 权限被拒绝了 .
                showDeniedDialog();
            }
        }
    }

目前我又踩到了vivo不能build安装,申请相机权限时一样会走成功,但是无法打开相机。 正在努力找解决的办法 oooO ↘┏━┓ ↙ Oooo ( 踩)→┃你┃ ←(死 ) \ ( →┃√┃ ← ) /   _)↗┗━┛ ↖(_/

star-andy commented 7 years ago

@jmbeizi 我按照你的办法在vivo x6上无效 return回来的一直是true @luffykou 请问下你的vivo相机权限这个问题解决了吗?

Fengcoder commented 7 years ago

看看 这篇文章 http://www.jianshu.com/p/65e23b618f76 (里面解释的很清楚)

AganCN commented 7 years ago

@luffykou vivo的权限你解决了吗,我发现vivo这个小妖精只要 Camera.open()就会申请权限,你如果不去管倒计时介绍权限没有拿到 但是还是返回true

529523346 commented 7 years ago

@AganCN @luffykou 我发现vivox9不管你有没有授权,检测权限checkSelfPermission后返回的都是PackageManager.PERMISSION_GRANTED,你们遇到过没有,系统的是6.0.1的

manza7014 commented 7 years ago

魅族pro6小米5s都有这个问题

529523346 commented 7 years ago

@manza7014 不过逻辑貌似没问题,授权后还是会继续跳转到拍照页面,但是对它的内部处理逻辑有点疑惑

strivecheng commented 7 years ago

看看严振杰的权限适配框架,基本适配国内大部分手机,本人目前真正使用,很不错,顺便说一句小米真tm坑!!!https://github.com/yanzhenjie/AndPermission/blob/master/README-CN.md

vagrant1991 commented 7 years ago

大家相机参考: http://www.jianshu.com/p/1f072a248a37

录音 :

/**

vagrant1991 commented 7 years ago

http://www.jianshu.com/p/b524b4c249e7 这个同学写的文章也不错。

yummmyz commented 7 years ago

@529523346 是的,我也发现了。vivo x9 直接使用checkSelfPermission一直返回true,调用Camera.open()时才会申请权限,但禁止权限的时候,这个方法还是会返回非空的Camera对象

forYueji commented 7 years ago

至今..... 问题依旧啊 采用 Rx 的 RxPermissions 库来处理改问题,得到的结果是 Android 6.0 以上(包含6.0)均正确, 测试机型 : 小米 4C 5.1.1、华为 5.1.1 、华为 6.0、三星 5.0 、三星、6.0 , 7.0 ; 其中 小米 4C 5.1.1、华为 5.1.1 ;返回结果 均 为 true 也就是权限均存在,在进入 OCR 页面时 UI 变形 SurfaceView 绘制失败,后修改为 Google 的 http://wuxiaolong.me/2017/03/07/easypermissions/ ; 结果一致, 以下为 Google easypermissions 源码 /**

tianshaokai commented 7 years ago

@forYueji 你把问题搞复杂了

  1. 你要先弄明白你的绘制框变形是什么问题导致的
  2. 如果变形的手机你可以在程序里手动给app设置权限,看是否会变形
  3. 如果不变形,那说明没问题,如果变形就是说明你的扫描代码就有问题
  4. 扫描框设置权限应该在view加载之前赋予权限就行了
forYueji commented 7 years ago

@tianshaokai 谢谢 提醒 ,上述问题可能没有表述清楚,在 自定义相机的过程中失败的原因是因为 我在设置中手动将相机 权限设置为拒绝状态 ,那么在 camera 获取的时候 出现异常了, 在这里我对 camera 出现异常 做了 处理,目的是为了防止 闪退,那么外层所表现出现的结果就是 UI 变形,这其实是一个 错误的 UI ,即 因为相机权限 设置为拒绝状态

tianshaokai commented 7 years ago

@forYueji 你可以拒绝后不让进入扫一扫页面啊,必须同意

tianshaokai commented 7 years ago

@forYueji 你是做的什么功能啊,开源吗看看你的代码

CaptainJno commented 7 years ago

@forYueji 直接try catch,捕获到异常,就提醒用户去设置界面手动开启摄像头权限。 可参考这篇文章:http://www.jianshu.com/p/1f072a248a37

forYueji commented 7 years ago

@tianshaokai 是这样的 ,我这是在这深究这个问题呢 😄 😄

imkarl commented 7 years ago

oppo checkPermission(Manifest.permission.READ_CONTACTS)始终返回true,即使禁用了该权限 我测试的机型:OPPO R9s(android 6.0),有什么方法可以辨别权限是否被禁用吗?

xinglonglcu commented 7 years ago

@luffykou 我也遇到这种问题,vivo 不会报出Exception,这种方法不适用,你是怎么解决的呢 ??

waylife commented 6 years ago

如果简单的判断摄像头是否异常来区分是否有权限,那如何区分摄像头是真的有问题(比如硬件损坏)还是真的是没有权限呢?