美文网首页
调用相机拍照并返回照片,坑,坑,坑我2天

调用相机拍照并返回照片,坑,坑,坑我2天

作者: 我想放假休息 | 来源:发表于2019-12-09 14:48 被阅读0次

    第一步:动态申请权限

    Manifest.permission.WRITE_EXTERNAL_STORAGE
    Manifest.permission.READ_EXTERNAL_STORAGE
    Manifest.permission.CAMERA
    

    这个是我无意间发现的动态申请权限框架,
    引入implementation 'pub.devrel:easypermissions:1.3.0'
    定义一个数组将需要申请的权限放进去

    private String[] permissions = {
       Manifest.permission.CAMERA, 
       Manifest.permission.WRITE_EXTERNAL_STORAGE, 
       Manifest.permission.READ_EXTERNAL_STORAGE
    };
    

    接着写一个方法,调用该方法即可

        //获取权限
        private void getPermission() {
            if (EasyPermissions.hasPermissions(this, permissions)) {
                //已经打开权限
                Toast.makeText(this, "已经申请相关权限", Toast.LENGTH_SHORT).show();
            } else {
                //没有打开相关权限、申请权限
                EasyPermissions.requestPermissions(this, "需要获取您的相册、照相使用权限", 1, permissions);
            }
    
        }
    

    Android 7.0之后,我们需要用content://uri来代替file://uri,所以需要用ContentProvider去访问文件,FileProvider是很好的选择。

    要使用FileProvider,按照下面步骤继续吧~~

    第二步:配置清单文件

    <provider
        android:name="android.support.v4.content.FileProvider"//一般不用这个了
    
        android:name="androidx.core.content.FileProvider"
        android:authorities="com.hqld.fileprovider"//自己的包名
    
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths" />
    </provider>
    

    属性值:
    android:authorities 一般是"项目的包名 + .provider"。当我们使用FileProvider的getUriForFile方法时参数需和 清单文件注册时的保持一致。
    android:exported 是否对外开放,除非是对第三方提供服务,否则一般为false。
    android:grantUriPermissions是否授予临时权限,设置为true。
    meta-data 标签 标签里面是用来指定共享的路径。
    android:resource 就是我们的共享路径配置的xml文件,可以自己命名。该文件放在res/xml文件夹下,若没有xml文件夹,自己创建一个。文件取名为file_paths.xml。

    file_paths.xml

    <?xml version="1.0" encoding="utf-8"?>
    <paths xmlns:android="http://schemas.android.com/apk/res/android">
        <external-path
            name="temp"
            path="Pictures" />
    </paths>
    

    external-path可被替换成<external-files-path>、<external-cache-path>、<file-path>、<cache-path>等。下面给出五个的区别:
    <external-path>:共享外部存储卡,对应/storage/emulated/0目录,即Environment..getExternalStorageDirectory()
    <external-files-path>:共享外部存储的文件目录,对应/storage/emulated/0/Android/data/包名/files,即Context.getExternalFilesDir()
    <external-cache-path>:共享外部存储的缓存目录,对应/storage/emulated/0/Android/data/包名/cache,即Context.getExternalCacheDir()
    <file-path>:共享内部文件存储目录,对应 /data/data/包名/files目录,即Context.getFilesDir()
    <cache-path>:共享内部缓存目录,对应 /data/data/包名/cache目录,即Context.getCacheDir()

    name 随便定义
    path 需要临时授权访问的路径。可以为空,表示指定目录下的所有文件、文件夹都可以被共享

    第三步:获取URI

        public static Uri getOutputMediaFileUri(Context context) {
            File mediaFile = null;
            String cameraPath;
            try {
                File mediaStorageDir = new File(Environment.getExternalStorageDirectory().getAbsolutePath());
                if (!mediaStorageDir.exists()) {
                    if (!mediaStorageDir.mkdirs()) {
                        return null;
                    }
                }
                mediaFile = new File(mediaStorageDir.getPath()
                        + File.separator
                        + "Pictures/temp.jpg");//注意这里需要和filepaths.xml中配置的一样
                cameraPath = mediaFile.getAbsolutePath();
    
            } catch (Exception e) {
                e.printStackTrace();
            }
          
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {// sdk >= 24  android7.0以上
                Uri contentUri = FileProvider.getUriForFile(context,
                        context.getApplicationContext().getPackageName() + ".provider",//与清单文件中android:authorities的值保持一致
                        mediaFile);//FileProvider方式或者ContentProvider。也可使用VmPolicy方式
                return contentUri;
    
            } else {
                return Uri.fromFile(mediaFile);//或者 Uri.isPaise("file://"+file.toString()
    
            }
        }
    

    第四步:调起相机

    //打开照相机
    Intent openCameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    Uri imageUri = CameraUtil.getOutputMediaFileUri(context);
    openCameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
    
    //Android7.0添加临时权限标记,此步千万别忘了
    openCameraIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
    startActivityForResult(openCameraIntent, TAKE_PICTURE);
    

    拍照后,照片就存在imageUri 位置,可以把它转为绝对路径,

    
     public static Bitmap getBitmapFormUri(Context context, Uri uri) throws FileNotFoundException, IOException {
            InputStream input = context.getContentResolver().openInputStream(uri);
            Bitmap bitmap = BitmapFactory.decodeStream(input);
            return bitmap;
    }
    
    

    相关文章

      网友评论

          本文标题:调用相机拍照并返回照片,坑,坑,坑我2天

          本文链接:https://www.haomeiwen.com/subject/cpbbgctx.html