当前位置:   article > 正文

android访问相册、拍照_android 开发如何打开照片和视频权限

android 开发如何打开照片和视频权限

在访问相册的时候由于是跨进程访问相册资源,所以必须具备ContentProvider的基本知识,使用相机的时候需要指定照片存储位置,需要具备FileProvider的原理和使用

由于访问相册和使用相机,所以我们需要动态申请权限。使用easypermissions

implementation 'pub.devrel:easypermissions:0.3.0'
  • 1

所需权限

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
  • 1
  • 2
  • 3

1. 动态申请权限

private String[] permissions = {Manifest.permission.CAMERA,
								Manifest.permission.READ_EXTERNAL_STORAGE,
								Manifest.permission.WRITE_EXTERNAL_STORAGE};
								
if(EasyPermissions.hasPermissions(this,permissions)){
}
else{
	EasyPermissions.requestPermissions(this,"访问相册权限",1,permissions);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

使用easypermissions步骤
1.重写onRequestPermissionsResult,在内部调用EasyPermissions.onRequestPermissionsResult

@Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        EasyPermissions.onRequestPermissionsResult(requestCode,permissions,grantResults,this);
    }
  • 1
  • 2
  • 3
  • 4
  • 5

2.使该类继承implements EasyPermissions.PermissionCallbacks,然后重写onPermissionsGrantedonPermissionsDenied进行授权判断

	@Override
    public void onPermissionsGranted(int requestCode, List<String> perms) {
        Toast.makeText(this, "相关权限获取成功", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onPermissionsDenied(int requestCode, List<String> perms) {
        Toast.makeText(this, "请同意相关权限,否则功能无法使用", Toast.LENGTH_SHORT).show();
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

2. 打开相册并且获取选中的图片
打开相册:

Intent intent = new Intent();
intent.setAction(Intent.ACTION_PICK);
intent.setType("image/*");
startActivityForResult(intent,2);
  • 1
  • 2
  • 3
  • 4

获取选中图片

 @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(requestCode == 2 &&resultCode == RESULT_OK){
            String imagePath = null;
            Uri uri = data.getData();

            if(DocumentsContract.isDocumentUri(MainActivity.this,uri)){
                String docId = DocumentsContract.getDocumentId(uri);
                if("com.android.providers.media.documents".equals(uri.getAuthority())) {
                    String id=docId.split(":")[1];
                    String selection= MediaStore.Images.Media._ID+"="+id;
                    imagePath = getImagePath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,selection);
                }else if("com.android.providers.downloads.documents".equals(uri.getAuthority())){
                    Uri contentUri= ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"),Long.valueOf(docId));
                    imagePath = getImagePath(contentUri,null);
                }
            }
            else if("content".equalsIgnoreCase(uri.getScheme())){
                imagePath = getImagePath(uri,null);
            }
            else if("file".equalsIgnoreCase(uri.getScheme())){
                imagePath = uri.getPath();
            }
			
			//展示选中的图片
            if(imagePath != null) {
                Intent intent = new Intent(MainActivity.this, PictureActivity.class);
                intent.putExtra("url", imagePath);
                startActivity(intent);
            }

        }
    }

private String getImagePath(Uri uri,String selection) {
        String path = null;
        Cursor cursor = getContentResolver().query(uri, null, selection, null, null);
        if (cursor != null) {
            if (cursor.moveToFirst()) {
                path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
            }
            cursor.close();
        }
        return path;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46

3.使用相机拍照并且存储到指定文件
打开相机设定存储位置

Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);//用来打开相机的Intent
	if(takePhotoIntent.resolveActivity(getPackageManager())!=null){//这句作用是如果没有相机则该应用不会闪退,要是不加这句则当系统没有相机应用的时候该应用会闪退
	File imageFile = createImageFile();//创建用来保存照片的文件
	Uri ImageUri = null;
	if(imageFile!=null){
		if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.N){
			/*7.0以上要通过FileProvider将File转化为Uri*/
	        ImageUri = FileProvider.getUriForFile(this,"com.example.qsbk.fileProvider",imageFile);
			}else {
				/*7.0以下则直接使用Uri的fromFile方法将File转化为Uri*/
            	ImageUri = Uri.fromFile(imageFile);
            	}
        }
                        //设置文件存储位置
	takePhotoIntent.putExtra(MediaStore.EXTRA_OUTPUT,ImageUri);
    startActivityForResult(takePhotoIntent,3);//启动相机
}

private File createImageFile() {
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        String imageFileName = "JPEG_"+timeStamp+"_";
        File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
        File imageFile = null;
        try {
            imageFile = File.createTempFile(imageFileName,".jpg",storageDir);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return imageFile;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

FileProvider的源码部分(这里不做讲解,具体请参考FileProvider的原理和使用

<provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="com.example.qsbk.fileProvider"
            android:grantUriPermissions="true"
            android:exported="false">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths" />
        </provider>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

file_paths.xml

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <!--代表的目录即为:Environment.getExternalStorageDirectory()/Android/data/包名/-->
    <external-path
        name="files_root"
        path="Android/data/com.example.qsbk/" />

    <!--代表的目录即为:Environment.getExternalStorageDirectory()-->
    <external-path
        name="external_storage_root"
        path="." />

    <!--代表的目录即为:Environment.getExternalStorageDirectory()/pics -->
    <external-path
        name="external"
        path="pics" />

</paths>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

知识拓展Intent.ACTION_PICK

(一)、调用图库,获取所有本地图片:

Intent imageIntent = new Intent(Intent.ACTION_GET_CONTENT); 
imageIntent.setType("image/*"); 
startActivityForResult(imageIntent, PICK_CODE); //PICK_CODE是常量
  • 1
  • 2
  • 3

(二)、调用本地联系人:

 Intent intent = new Intent(Intent.ACTION_PICK); 
 intent.setType(ContactsContract.Contacts.CONTENT_TYPE); 
 startActivityForResult(intent, PICK_CONTACT); 
  • 1
  • 2
  • 3

(三)、调用音乐,获取所有本地音乐文件:

Intent audioIntent = new Intent(Intent.ACTION_GET_CONTENT); 
audioIntent.setType("audio/*"); 
startActivityForResult(audioIntent, PICK_AUDIO); 
  • 1
  • 2
  • 3

(四)、调用视频,获取所有本地视频文件:

Intent videoIntent = new Intent(Intent.ACTION_GET_CONTENT); 
videoIntent.setType("video/*"); 
startActivityForResult(videoIntent, PICK_VIDEO); 
  • 1
  • 2
  • 3

参考博客:https://www.cnblogs.com/wucaiyun1/p/4933049.html

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/502786
推荐阅读
相关标签
  

闽ICP备14008679号