android-discuss icon indicating copy to clipboard operation
android-discuss copied to clipboard

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

Open start141 opened this issue 10 years ago • 54 comments

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

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

各位有更好的办法吗?

start141 avatar May 21 '15 03:05 start141

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

t12x3456 avatar May 21 '15 06:05 t12x3456

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

start141 avatar May 21 '15 06:05 start141

@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

t12x3456 avatar May 21 '15 06:05 t12x3456

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

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

start141 avatar May 21 '15 06:05 start141

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

newtonker avatar Aug 24 '15 05:08 newtonker

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

start141 avatar Aug 24 '15 05:08 start141

@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;
    }
}

newtonker avatar Aug 24 '15 05:08 newtonker

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

2015-08-24 13:50 GMT+08:00 newtonker [email protected]:

@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 .

Qixingchen avatar Aug 24 '15 05:08 Qixingchen

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

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

start141 avatar Aug 24 '15 05:08 start141

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

newtonker avatar Aug 24 '15 13:08 newtonker

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

1207229280 avatar Feb 12 '16 07:02 1207229280

照相机权限

1207229280 avatar Feb 12 '16 07:02 1207229280

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

l123456789jy avatar Mar 14 '16 09:03 l123456789jy

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

Labmem003 avatar May 12 '16 03:05 Labmem003

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

imhet avatar May 30 '16 09:05 imhet

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

xilost avatar Jun 15 '16 07:06 xilost

@newtonker 懂了!太感谢了~

xilost avatar Jun 15 '16 07:06 xilost

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

ssurprise avatar Jun 17 '16 08:06 ssurprise

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

xilost avatar Jun 21 '16 07:06 xilost

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

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

ssurprise avatar Jun 21 '16 07:06 ssurprise

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

ssurprise avatar Jun 21 '16 09:06 ssurprise

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

CaptainJno avatar Jul 09 '16 09:07 CaptainJno

魅族不按套路出牌,相机权限这里也是被坑过。 CaptainJno [email protected]于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 .

drakeet avatar Jul 09 '16 09:07 drakeet

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

zijing07 avatar Aug 13 '16 11:08 zijing07

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

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

  • PS:没有测试更多设备

SeniorZhai avatar Feb 13 '17 03:02 SeniorZhai

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

sundxing avatar Mar 10 '17 11:03 sundxing

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

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

08carmelo avatar Mar 29 '17 05:03 08carmelo

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

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

gordonpro avatar Apr 14 '17 08:04 gordonpro

@androidmalin

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

08carmelo avatar Apr 25 '17 09:04 08carmelo

小米的定位权限我遇见过坑,后来是在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 avatar Jun 08 '17 08:06 star-andy