博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android 调用相机拍照,适配到Android 10?
阅读量:2260 次
发布时间:2019-05-09

本文共 5385 字,大约阅读时间需要 17 分钟。

今天写的博客是关于Android调用手机相机拍照并显示图片。这是一个很常用的功能,并且这个功能在Android6.0、7.0、10.0等版本上实现都有所不同,需要对Android各个版本进行兼容适配,目前最新的Android版本是Android 10,所以这篇博客适配到Android 10。我自己也写了个demo,方便以后要使用的时候直接拿来。

调用相机,首先需要申请相机权限。

 

android 6.0以后,相机权限需要动态申请。

 

// 申请相机权限的requestCode   private static final int PERMISSION_CAMERA_REQUEST_CODE = 0x00000012;   /**    * 检查权限并拍照。    * 调用相机前先检查权限。    */   private void checkPermissionAndCamera() {       int hasCameraPermission = ContextCompat.checkSelfPermission(getApplication(),               Manifest.permission.CAMERA);       if (hasCameraPermission == PackageManager.PERMISSION_GRANTED) {           //有调起相机拍照。           openCamera();       } else {           //没有权限,申请权限。           ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.CAMERA},                   PERMISSION_CAMERA_REQUEST_CODE);       }   }   /**    * 处理权限申请的回调。    */   @Override   public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {       if (requestCode == PERMISSION_CAMERA_REQUEST_CODE) {           if (grantResults.length > 0                   && grantResults[0] == PackageManager.PERMISSION_GRANTED) {               //允许权限,有调起相机拍照。               openCamera();           } else {               //拒绝权限,弹出提示框。               Toast.makeText(this,"拍照权限被拒绝",Toast.LENGTH_LONG).show();           }       }   }

申请权限后,就可以调起相机拍照了。调用相机只需要调用startActivityForResult传一个Intent就可以了,但是这个Intent需要传递一个uri,用于保存拍出来的图片,创建这个uri时,各个Android版本有所不同,需要进行版本兼容。

 

//用于保存拍照图片的uri    private Uri mCameraUri;    // 用于保存图片的文件路径,Android 10以下使用图片路径访问图片    private String mCameraImagePath;    // 是否是Android 10以上手机    private boolean isAndroidQ = Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q;    /**     * 调起相机拍照     */    private void openCamera() {        Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);        // 判断是否有相机        if (captureIntent.resolveActivity(getPackageManager()) != null) {            File photoFile = null;            Uri photoUri = null;            if (isAndroidQ) {                // 适配android 10                photoUri = createImageUri();            } else {                try {                    photoFile = createImageFile();                } catch (IOException e) {                    e.printStackTrace();                }                if (photoFile != null) {                    mCameraImagePath = photoFile.getAbsolutePath();                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {                        //适配Android 7.0文件权限,通过FileProvider创建一个content类型的Uri                        photoUri = FileProvider.getUriForFile(this, getPackageName() + ".fileprovider", photoFile);                    } else {                        photoUri = Uri.fromFile(photoFile);                    }                }            }            mCameraUri = photoUri;            if (photoUri != null) {                captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);                captureIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);                startActivityForResult(captureIntent, CAMERA_REQUEST_CODE);            }        }    }    /**     * 创建图片地址uri,用于保存拍照后的照片 Android 10以后使用这种方法     */    private Uri createImageUri() {        String status = Environment.getExternalStorageState();        // 判断是否有SD卡,优先使用SD卡存储,当没有SD卡时使用手机存储        if (status.equals(Environment.MEDIA_MOUNTED)) {           return getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, new ContentValues());        } else {            return getContentResolver().insert(MediaStore.Images.Media.INTERNAL_CONTENT_URI, new ContentValues());        }    }    /**     * 创建保存图片的文件     */    private File createImageFile() throws IOException {        String imageName = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());        File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);        if (!storageDir.exists()) {            storageDir.mkdir();        }        File tempFile = new File(storageDir, imageName);        if (!Environment.MEDIA_MOUNTED.equals(EnvironmentCompat.getStorageState(tempFile))) {            return null;        }        return tempFile;    }

接收拍照结果和显示图片

 

@Override    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {        super.onActivityResult(requestCode, resultCode, data);        if (requestCode == CAMERA_REQUEST_CODE) {            if (resultCode == RESULT_OK) {                if (isAndroidQ) {                    // Android 10 使用图片uri加载                    ivPhoto.setImageURI(mCameraUri);                } else {                    // 使用图片路径加载                    ivPhoto.setImageBitmap(BitmapFactory.decodeFile(mCameraImagePath));                }            } else {                Toast.makeText(this,"取消",Toast.LENGTH_LONG).show();            }        }    }

这两需要说明一下,Android 10由于文件权限的关系,显示手机储存卡里的图片不能直接使用图片路径,需要使用图片uri加载。关于在Android 10显示手机图片的适配可以看我的另外一篇博客:

另外虽然我在这篇博客里对Android 10和10以下的手机使用了不同的方式创建uri 和加载图片,但其实Android 10创建uri的方式和使用uri加载图片的方式在10以下的手机是同样适用的。

android 7.0需要配置文件共享。

 

在res目录下创建文件夹xml ,放置一个文件file_paths.xml(文件名可以随便取),配置需要共享的文件目录,也就是拍照图片保存的目录。

 

如果想把图片放在手机的共享储存区,比如Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)文件夹下,还需要申请文件读写权限。

 

文件读写权限同样需要动态申请,申请权限的方式跟上面申请相机权限一样,这里就不再重复了。

转载地址:http://bcfcb.baihongyu.com/

你可能感兴趣的文章
如何让Git克隆到当前目录
查看>>
从Java 8中的java.util.stream.Stream检索列表
查看>>
如果我针对大小而不是速度进行优化,为什么GCC会生成15-20%的更快代码?
查看>>
在Java中使用分隔符(拆分的对立面)连接数组元素的快速简便方法
查看>>
如何使用CSS更改SVG图像的颜色(jQuery SVG图像替换)?
查看>>
JQuery .each()向后
查看>>
如何从Java中打印XML?
查看>>
Amazon SNS和Amazon SQS有什么区别?
查看>>
在MySQL中的特定列之后添加多个列
查看>>
如何禁用请求库中的日志消息?
查看>>
如何使用composer从Laravel中删除包?
查看>>
如何为某些HTML标记存储任意数据
查看>>
同步等待异步操作,为什么Wait()在这里冻结程序
查看>>
存储库访问被拒绝。通过部署密钥进行访问是只读的
查看>>
“ u”到底是做什么的? “ git push -u原始主机”与“ git push原始主机”
查看>>
如何使用RecyclerView构建Horizontal ListView?
查看>>
Java ResultSet如何检查是否有任何结果
查看>>
如何将OutputStream转换为InputStream?
查看>>
将ArrayList保存到SharedPreferences
查看>>
Python setup.py开发与安装
查看>>