checkSelfPermission总是返回PERMISSION_GRANTED

今天在实现录音功能的权限申请时遇到了问题,然后网上找资料,基本都是分割线下面的解决方法,但是在我的Smartisan OS V3.7.0.2(android 6.0  23), 项目中target sdk version设置为了22。

令人疑惑的是 录音权限在设置为每次询问时,PermissionChecker#checkSelfPermission总是返回PERMISSION_GRANTED,让我调试的开始怀疑人生了,我找了一台android 7.0的原生的手机就是ok的,当然原生的手机只有录音权限只有开和关两项,并没有每次询问,我初步怀疑是厂商的代码导致的该问题

在录音的时候,针对录制的过程还是要加try catch进行捕获异常,防止由于没有权限导致崩溃,其他权限可以类似处理,根据catch到的异常进行处理,优化用户体验。


------------------------------------------------------------分割线---------------------------------------------------------------------

以下内容引自其他博客:

Android M运行targetSdkVersion < 23的应用时,调用checkSelfPermission,不管用户是否取消授权,checkSelfPermission的返回值始终为PERMISSION_GRANTED的解决办法


  1. If your application is targeting an API level before 23 (android M) then both:ContextCompat#checkSelfPermission and Context#checkSelfPermission doesn't work and always returns 0 (PERMISSION_GRANTED). Even if you run the application on Android 6.0 (API 23).

  2. It's not fully true that if you targeting an API level before 23 then  you don't have to take care of permissions. If you targeting an API level before 23 then:

    • Android < 6.0: Everything will be ok.

    • Android 6.0: Application's run-time permissions will be granted by default (compatibility mode applies), but the user can change run-time permissions in Android Settings, then you may have a problem.

  3. As I said in the 1st point, if you targeting an API level before 23 on Android 6.0 then ContextCompat#checkSelfPermission and Context#checkSelfPermission doesn't work. Fortunately you can use PermissionChecker#checkSelfPermission to check run-time permissions.

Example code:


[html]  view plain  copy
  1. public boolean selfPermissionGranted(String permission) {  
  2.        // For Android < Android M, self permissions are always granted.  
  3.        boolean result = true;  
  4.   
  5.        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {  
  6.   
  7.            if (targetSdkVersion >= Build.VERSION_CODES.M) {  
  8.                // targetSdkVersion >= Android M, we can  
  9.                // use Context#checkSelfPermission  
  10.                result = context.checkSelfPermission(permission)  
  11.                        == PackageManager.PERMISSION_GRANTED;  
  12.            } else {  
  13.                // targetSdkVersion < Android M, we have to use PermissionChecker  
  14.                result = PermissionChecker.checkSelfPermission(context, permission)  
  15.                        == PermissionChecker.PERMISSION_GRANTED;  
  16.            }  
  17.        }  
  18.   
  19.        return result;  
  20.    }  

In order to obtain target Sdk Version you can use:

[html]  view plain  copy
  1. try {  
  2.        final PackageInfo info = context.getPackageManager().getPackageInfo(  
  3.                context.getPackageName(), 0);  
  4.        targetSdkVersion = info.applicationInfo.targetSdkVersion;  
  5.    } catch (PackageManager.NameNotFoundException e) {  
  6.        e.printStackTrace();  
  7.    }  

It works on Nexus 5 with Android M.

---------------------------------------------------------------------------分割线----------------------------------------------------------------------

这段代码是一个静态方法,用于保存数据到文件中。下面对每一行代码进行解释: 1. `public static boolean saveFile(Context context, String fileName, String data, boolean append){}` 这是方法的声明,指定方法名称为saveFile,参数类型为Context、String、String、boolean,返回类型为boolean。 2. `String path = Environment.getExternalStorageDirectory()+"/osnavData/";` 获取外部存储目录的路径,并在路径后面添加一个名为osnavData的文件夹名,用于存储文件。 3. `String filePath = path+fileName;` 将文件名添加到路径后面,生成完整的文件路径。 4. `File folder = new File(path);` 创建一个名为folder的File对象,代表存储文件的目录。 5. `File file = new File(filePath);` 创建一个名为file的File对象,代表要保存数据的文件。 6. `if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M){}` 判断当前设备的Android版本是否小于23(Build.VERSION_CODES.M)。 7. `threadToast(context, "版本号:"+Build.VERSION.SDK_INT);` 如果版本小于23,则调用threadToast方法,弹出一个Toast提示当前的Android版本号。 8. `return false;` 并返回false,表示保存文件失败。 9. `} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {` 如果版本号大于或等于30(Build.VERSION_CODES.R)。 10. `if(!Environment.isExternalStorageManager()){` 判断当前应用是否被授予管理所有文件的权限。 11. `Intent intent = new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);` 如果没有被授予权限,则创建一个Intent对象,跳转到系统设置界面,让用户手动授权。 12. `context.startActivity(intent);` 启动Intent对象,跳转到系统设置界面。 13. `return false;` 并返回false,表示保存文件失败。 14. `} else{` 如果版本号在23到29之间。 15. `if (ActivityCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {` 检查当前应用是否被授予写外部存储的权限。 16. `ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, CODE_WRITEFILE);` 如果没有被授予权限,则请求授权,弹出授权对话框,并等待用户授权。 17. `return false;` 并返回false,表示保存文件失败。 18. `}` 如果已经被授予权限,则继续执行下面的代码。 在这段代码中,没有对权限请求的结果进行处理,需要在onRequestPermissionsResult方法中处理授权结果。 该方法的主要作用是判断当前设备的Android版本和应用是否被授予权限,如果没有被授予权限,则请求授权,并在授权完成后保存数据到文件中。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值