赞
踩
在访问相册的时候由于是跨进程访问相册资源,所以必须具备ContentProvider的基本知识,使用相机的时候需要指定照片存储位置,需要具备FileProvider的原理和使用
由于访问相册和使用相机,所以我们需要动态申请权限。使用easypermissions
implementation 'pub.devrel:easypermissions:0.3.0'
所需权限
<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. 动态申请权限
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);
}
使用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);
}
2.使该类继承implements EasyPermissions.PermissionCallbacks
,然后重写onPermissionsGranted
和onPermissionsDenied
进行授权判断
@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();
}
2. 打开相册并且获取选中的图片
打开相册:
Intent intent = new Intent();
intent.setAction(Intent.ACTION_PICK);
intent.setType("image/*");
startActivityForResult(intent,2);
获取选中图片
@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; }
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; }
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>
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>
知识拓展Intent.ACTION_PICK
(一)、调用图库,获取所有本地图片:
Intent imageIntent = new Intent(Intent.ACTION_GET_CONTENT);
imageIntent.setType("image/*");
startActivityForResult(imageIntent, PICK_CODE); //PICK_CODE是常量
(二)、调用本地联系人:
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType(ContactsContract.Contacts.CONTENT_TYPE);
startActivityForResult(intent, PICK_CONTACT);
(三)、调用音乐,获取所有本地音乐文件:
Intent audioIntent = new Intent(Intent.ACTION_GET_CONTENT);
audioIntent.setType("audio/*");
startActivityForResult(audioIntent, PICK_AUDIO);
(四)、调用视频,获取所有本地视频文件:
Intent videoIntent = new Intent(Intent.ACTION_GET_CONTENT);
videoIntent.setType("video/*");
startActivityForResult(videoIntent, PICK_VIDEO);
参考博客:https://www.cnblogs.com/wucaiyun1/p/4933049.html
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。