今天写的博客是关于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加载手机本地图片

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

android 7.0需要配置文件共享。

 

    

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

 

<?xml version="1.0" encoding="utf-8"?>                        

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

 

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

更多相关文章

  1. android Webview 上传图片兼容各android版本
  2. Android
  3. Android(安卓)WebView上传图片到h5
  4. 【Android】6.0 运行时权限申请 整理
  5. ImageView的属性android:scaleType,即ImageView.setScaleType(Ima
  6. Android(安卓)访问权限设置
  7. android下访问sd卡和网络的权限
  8. LinearLayout按下(pressed)或获取焦点(focused)时背景设置不同颜
  9. Android根据图片Uri获取图片绝对路径

随机推荐

  1. Android(安卓)相关属性
  2. Android知识体系总结之Android部分View绘
  3. Android(安卓)studio 3.1.4 无法获取pom
  4. Android自动完成文本框
  5. Android概述
  6. Android中ExpandableListView控件基本使
  7. android ApiDemo学习(一)service总结
  8. 不用SDK manager 下载 Android(安卓)sdk
  9. Android横屏预竖屏
  10. android中数据存储