Android踩坑日记:android7.0动态相机权限

2024-04-26 11:58

本文主要是介绍Android踩坑日记:android7.0动态相机权限,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前提:

项目中使用的动态权限开源库github:https://github.com/yanzhenjie/AndPermission。

转载必须注明本文转自严振杰的博客:http://blog.csdn.net/yanzhenjie1003

添加依赖:

compile 'com.yanzhenjie:permission:1.0.3'

Android6.0:

众所周知,Android6.0时相机摄像头权限改成了动态权限申请。实际上在xml中加入CAMERA,WRITE_EXTERNAL_STORAGE全向后,直接调用摄像头。此时是没有“检查权限是否授予”,“没有授予再申请权限”的代码的。

但是(重点),我发现

1,在VIVO,华为等国产机会弹出对话框,

2,三星,sony等外国机不会有弹窗,调用摄像头直接崩溃,

3,魅族手机没有弹出,但是可以直接用摄像头。

我猜测是VIVO,华为定制系统帮助用户检查并申请了相机权限,外国机则没有,魅族可能直接授予权限。为统一,建议android6.0每次都检查并申请相机权限,如下.

 /*** 申请相机权限** @param context* @param photoFromCamera  拍照保存图片路径*** @see {https://github.com/yanzhenjie/AndPermission}* */public static void requestCameraPermission(final Context context, final String photoFromCamera){//API >=23if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){AndPermission.with(context).requestCode(PERMISSION_MEDIA_REQUEST_CODE).permission(Manifest.permission.CAMERA,Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE).rationale(new RationaleListener() {@Overridepublic void showRequestPermissionRationale(int requestCode, Rationale rationale) {// 此对话框可以自定义,调用rationale.resume()就可以继续申请。AndPermission.rationaleDialog(context, rationale).show();}}).callback(new PermissionListener() {@Overridepublic void onSucceed(int requestCode, @NonNull List<String> grantPermissions) {// 权限申请成功回调。if(requestCode == PERMISSION_MEDIA_REQUEST_CODE) {UIRouter.JumpToCameraActivity(context,photoFromCamera);}}@Overridepublic void onFailed(int requestCode, @NonNull List<String> deniedPermissions) {// 权限申请失败回调。if(requestCode == PERMISSION_MEDIA_REQUEST_CODE) {ToastView.showToast(context,"拒绝授权");}}}).start();}}

   /*** 调用系统拍照* @param saveImagePathFromCamera 拍照图片保存路径* @param context*/public static void JumpToCameraActivity(Context context, String saveImagePathFromCamera) {/*调用系统拍照*/Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);Uri uri = null; File imageFile = FileUtil.getFile(saveImagePathFromCamera);//此路径可以为storage/mounted/0/DCIM或其他外部存储路径uri = Uri.fromFile(imageFile); intent.putExtra(MediaStore.EXTRA_OUTPUT, uri); ((Activity) context).startActivityForResult(intent, CAMERA_REQUEST_CODE); }



 

Android7.0以上:

测试过程中,发现在android7.0以上的设备上使用摄像头时,直接崩溃掉了。原因是android7.0开始,相机拍照的图像保存路径必须在此应用的内部存储文件夹(storage/mounted/0/Android/data/包名//files/pictures文件夹)。需要使用FileProvider获取内部文件的uri

 /*** 申请相机权限** @param context* @param photoFromCamera  拍照保存图片路径*** @see {https://github.com/yanzhenjie/AndPermission}* */public static void requestCameraPermission(final Context context, final String photoFromCamera){//API <23if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M){UIRouter.JumpToCameraActivity(context,photoFromCamera);}else {//API >=23AndPermission.with(context).requestCode(PERMISSION_MEDIA_REQUEST_CODE).permission(Manifest.permission.CAMERA,Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE).rationale(new RationaleListener() {@Overridepublic void showRequestPermissionRationale(int requestCode, Rationale rationale) {// 此对话框可以自定义,调用rationale.resume()就可以继续申请。AndPermission.rationaleDialog(context, rationale).show();}}).callback(new PermissionListener() {@Overridepublic void onSucceed(int requestCode, @NonNull List<String> grantPermissions) {// 权限申请成功回调。if(requestCode == .PERMISSION_MEDIA_REQUEST_CODE) {UIRouter.JumpToCameraActivity(context,photoFromCamera);}}@Overridepublic void onFailed(int requestCode, @NonNull List<String> deniedPermissions) {// 权限申请失败回调。if(requestCode ==PERMISSION_MEDIA_REQUEST_CODE) {ToastView.showToast(context,"拒绝授权");}}}).start();}}

    /*** 调用系统拍照** @param context*/public static void JumpToCameraActivity(Context context, String saveImagePathFromCamera) {/*调用系统拍照*/Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);Uri uri = null;try {File imageFile = FileUtil.getFile(saveImagePathFromCamera);//API>=24 android 7.0if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){if (intent.resolveActivity(context.getPackageManager()) != null){String imageName = imageFile.getName();//7.0以上 的拍照文件必须在storage/emulated/0/Android/data/包名/files/pictures文件夹File storageDir = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES);File file = FileUtil.getFile(storageDir+"/"+imageName);intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); //添加这一句表示对目标应用临时授权该Uri所代表的文件uri = FileProvider.getUriForFile(context,"包名.fileprovider",file);}}else {//<24 uri = Uri.fromFile(imageFile);}intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);((Activity) context).startActivityForResult(intent, CAMERA_REQUEST_CODE);} catch (IOException e) {e.printStackTrace();}}

1,在manifest.xml中加入:

 <providerandroid:name="android.support.v4.content.FileProvider"android:authorities="包名.fileprovider"android:exported="false"android:grantUriPermissions="true"><meta-dataandroid:name="android.support.FILE_PROVIDER_PATHS"android:resource="@xml/file_paths" /></provider>

2,在res中新建xml文件夹,创建file_paths.xml文件

<?xml version="1.0" encoding="utf-8"?>
<resources><paths><external-pathname="camera_photos"<!--任意-->path="Android/data/包名/files/Pictures" /><!--相机图片保存图片路径,属于APP的存储空间--></paths></resources>




这篇关于Android踩坑日记:android7.0动态相机权限的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/937531

相关文章

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

第10章 中断和动态时钟显示

第10章 中断和动态时钟显示 从本章开始,按照书籍的划分,第10章开始就进入保护模式(Protected Mode)部分了,感觉从这里开始难度突然就增加了。 书中介绍了为什么有中断(Interrupt)的设计,中断的几种方式:外部硬件中断、内部中断和软中断。通过中断做了一个会走的时钟和屏幕上输入字符的程序。 我自己理解中断的一些作用: 为了更好的利用处理器的性能。协同快速和慢速设备一起工作

动态规划---打家劫舍

题目: 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。 给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。 思路: 动态规划五部曲: 1.确定dp数组及含义 dp数组是一维数组,dp[i]代表

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

Android平台播放RTSP流的几种方案探究(VLC VS ExoPlayer VS SmartPlayer)

技术背景 好多开发者需要遴选Android平台RTSP直播播放器的时候,不知道如何选的好,本文针对常用的方案,做个大概的说明: 1. 使用VLC for Android VLC Media Player(VLC多媒体播放器),最初命名为VideoLAN客户端,是VideoLAN品牌产品,是VideoLAN计划的多媒体播放器。它支持众多音频与视频解码器及文件格式,并支持DVD影音光盘,VCD影

基于UE5和ROS2的激光雷达+深度RGBD相机小车的仿真指南(五):Blender锥桶建模

前言 本系列教程旨在使用UE5配置一个具备激光雷达+深度摄像机的仿真小车,并使用通过跨平台的方式进行ROS2和UE5仿真的通讯,达到小车自主导航的目的。本教程默认有ROS2导航及其gazebo仿真相关方面基础,Nav2相关的学习教程可以参考本人的其他博客Nav2代价地图实现和原理–Nav2源码解读之CostMap2D(上)-CSDN博客往期教程: 第一期:基于UE5和ROS2的激光雷达+深度RG

代码随想录冲冲冲 Day39 动态规划Part7

198. 打家劫舍 dp数组的意义是在第i位的时候偷的最大钱数是多少 如果nums的size为0 总价值当然就是0 如果nums的size为1 总价值是nums[0] 遍历顺序就是从小到大遍历 之后是递推公式 对于dp[i]的最大价值来说有两种可能 1.偷第i个 那么最大价值就是dp[i-2]+nums[i] 2.不偷第i个 那么价值就是dp[i-1] 之后取这两个的最大值就是d

android-opencv-jni

//------------------start opencv--------------------@Override public void onResume(){ super.onResume(); //通过OpenCV引擎服务加载并初始化OpenCV类库,所谓OpenCV引擎服务即是 //OpenCV_2.4.3.2_Manager_2.4_*.apk程序包,存

从状态管理到性能优化:全面解析 Android Compose

文章目录 引言一、Android Compose基本概念1.1 什么是Android Compose?1.2 Compose的优势1.3 如何在项目中使用Compose 二、Compose中的状态管理2.1 状态管理的重要性2.2 Compose中的状态和数据流2.3 使用State和MutableState处理状态2.4 通过ViewModel进行状态管理 三、Compose中的列表和滚动

Android 10.0 mtk平板camera2横屏预览旋转90度横屏拍照图片旋转90度功能实现

1.前言 在10.0的系统rom定制化开发中,在进行一些平板等默认横屏的设备开发的过程中,需要在进入camera2的 时候,默认预览图像也是需要横屏显示的,在上一篇已经实现了横屏预览功能,然后发现横屏预览后,拍照保存的图片 依然是竖屏的,所以说同样需要将图片也保存为横屏图标了,所以就需要看下mtk的camera2的相关横屏保存图片功能, 如何实现实现横屏保存图片功能 如图所示: 2.mtk