第一步:動(dòng)態(tài)申請(qǐng)權(quán)限
Manifest.permission.WRITE_EXTERNAL_STORAGE
Manifest.permission.READ_EXTERNAL_STORAGE
Manifest.permission.CAMERA
這個(gè)是我無(wú)意間發(fā)現(xiàn)的動(dòng)態(tài)申請(qǐng)權(quán)限框架,
引入implementation 'pub.devrel:easypermissions:1.3.0'
定義一個(gè)數(shù)組將需要申請(qǐng)的權(quán)限放進(jìn)去
private String[] permissions = {
Manifest.permission.CAMERA,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE
};
接著寫一個(gè)方法,調(diào)用該方法即可
//獲取權(quán)限
private void getPermission() {
if (EasyPermissions.hasPermissions(this, permissions)) {
//已經(jīng)打開權(quán)限
Toast.makeText(this, "已經(jīng)申請(qǐng)相關(guān)權(quán)限", Toast.LENGTH_SHORT).show();
} else {
//沒(méi)有打開相關(guān)權(quán)限炒辉、申請(qǐng)權(quán)限
EasyPermissions.requestPermissions(this, "需要獲取您的相冊(cè)豪墅、照相使用權(quán)限", 1, permissions);
}
}
Android 7.0之后,我們需要用content://uri來(lái)代替file://uri黔寇,所以需要用ContentProvider去訪問(wèn)文件偶器,FileProvider是很好的選擇。
要使用FileProvider缝裤,按照下面步驟繼續(xù)吧~~
第二步:配置清單文件
<provider
android:name="android.support.v4.content.FileProvider"http://一般不用這個(gè)了
android:name="androidx.core.content.FileProvider"
android:authorities="com.hqld.fileprovider"http://自己的包名
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
屬性值:
android:authorities 一般是"項(xiàng)目的包名 + .provider"屏轰。當(dāng)我們使用FileProvider的getUriForFile方法時(shí)參數(shù)需和 清單文件注冊(cè)時(shí)的保持一致。
android:exported 是否對(duì)外開放憋飞,除非是對(duì)第三方提供服務(wù)霎苗,否則一般為false。
android:grantUriPermissions是否授予臨時(shí)權(quán)限榛做,設(shè)置為true唁盏。
meta-data 標(biāo)簽 標(biāo)簽里面是用來(lái)指定共享的路徑。
android:resource 就是我們的共享路徑配置的xml文件瘤睹,可以自己命名升敲。該文件放在res/xml文件夾下答倡,若沒(méi)有xml文件夾轰传,自己創(chuàng)建一個(gè)。文件取名為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>等恕曲。下面給出五個(gè)的區(qū)別:
<external-path>:共享外部存儲(chǔ)卡,對(duì)應(yīng)/storage/emulated/0目錄渤涌,即Environment..getExternalStorageDirectory()
<external-files-path>:共享外部存儲(chǔ)的文件目錄佩谣,對(duì)應(yīng)/storage/emulated/0/Android/data/包名/files,即Context.getExternalFilesDir()
<external-cache-path>:共享外部存儲(chǔ)的緩存目錄实蓬,對(duì)應(yīng)/storage/emulated/0/Android/data/包名/cache茸俭,即Context.getExternalCacheDir()
<file-path>:共享內(nèi)部文件存儲(chǔ)目錄吊履,對(duì)應(yīng) /data/data/包名/files目錄,即Context.getFilesDir()
<cache-path>:共享內(nèi)部緩存目錄调鬓,對(duì)應(yīng) /data/data/包名/cache目錄艇炎,即Context.getCacheDir()
name 隨便定義
path 需要臨時(shí)授權(quán)訪問(wèn)的路徑√谖眩可以為空缀踪,表示指定目錄下的所有文件、文件夾都可以被共享
第三步:獲取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()
}
}
第四步:調(diào)起相機(jī)
//打開照相機(jī)
Intent openCameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
Uri imageUri = CameraUtil.getOutputMediaFileUri(context);
openCameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
//Android7.0添加臨時(shí)權(quán)限標(biāo)記驴娃,此步千萬(wàn)別忘了
openCameraIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
startActivityForResult(openCameraIntent, TAKE_PICTURE);
拍照后,照片就存在imageUri 位置循集,可以把它轉(zhuǎn)為絕對(duì)路徑托慨,
public static Bitmap getBitmapFormUri(Context context, Uri uri) throws FileNotFoundException, IOException {
InputStream input = context.getContentResolver().openInputStream(uri);
Bitmap bitmap = BitmapFactory.decodeStream(input);
return bitmap;
}