在7.0以前,調用相機拍照時一般如下
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); file = new File(Environment.getExternalStorageDirectory().getAbsolutePath()
+ "/test/" + System.currentTimeMillis() + ".jpg");
file.getParentFile().mkdirs();
Uri uri = Uri.fromFile(file);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
在用Android 7.0版本時,出現了異常 FileUriExposedException,就是在傳遞uri時出錯 百度了一下,說是Android 7.0後又修改了檔案權限,可以使用FileProvider解決 1.在 res 目錄下建立檔案夾 xml 然後建立資源檔案 filepaths(随意名字)
<?xml version="1.0" encoding="utf-8"?>
<resources>
<external-path
name="images"
path="test/"/>
</resources>
其中
<files-path/> //代表的根目錄: Context.getFilesDir()
<external-path/> //代表的根目錄: Environment.getExternalStorageDirectory()
<cache-path/> //代表的根目錄: getCacheDir()
2.在manifest中添加provider
<application
......
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.xykj.customview.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths"/>
</provider>
</application>
3.在java代碼中
/**
* 使用相機
*/
private void useCamera() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
file = new File(Environment.getExternalStorageDirectory().getAbsolutePath()
+ "/test/" + System.currentTimeMillis() + ".jpg");
file.getParentFile().mkdirs();
//改變Uri com.xykj.customview.fileprovider注意和xml中的一緻
Uri uri = FileProvider.getUriForFile(this, "com.xykj.customview.fileprovider", file);
//添權重限
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
startActivityForResult(intent, REQUEST_CAMERA);
}
調用相機拍照,圖檔得存儲吧,存儲圖檔又需要權限,是以動态申請權限 AndroidManifest.xml檔案中
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
java代碼中
public void applyWritePermission() {
String[] permissions = {Manifest.permission.WRITE_EXTERNAL_STORAGE};
if (Build.VERSION.SDK_INT >= 23) {
int check = ContextCompat.checkSelfPermission(this, permissions[0]);
// 權限是否已經 授權 GRANTED---授權 DINIED---拒絕
if (check == PackageManager.PERMISSION_GRANTED) {
//調用相機
useCamera();
} else {
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
}
} else {
useCamera();
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
useCamera();
} else {
// 沒有擷取 到權限,從新請求,或者關閉app
Toast.makeText(this, "需要存儲權限", Toast.LENGTH_SHORT).show();
}
}
然後在ImageView點選事件中調用applyWritePermission()方法 并在onActivityResult中編寫顯示圖檔的代碼
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 1 && resultCode == RESULT_OK) {
Log.e("TAG", "---------" + FileProvider.getUriForFile(this, "com.xykj.customview.fileprovider", file));
imageView.setImageBitmap(BitmapFactory.decodeFile(file.getAbsolutePath()));
}
}
完成,看下FileProvider.getUriFile方法得到的Uri結果 content://com.xykj.customview.fileprovider/images/1494663973508.jpg 可以發現 name為臨時的檔案夾名 path為自己定義路徑的檔案夾名
<resources>
<external-path name="images" path="test/"/>
</resources>
4.最後發現此方法相機拍照的圖檔并沒有顯示在手機圖庫中 想要在手機相冊圖庫中顯示剛拍照的圖檔可以采用發送廣播的方式
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 1 && resultCode == RESULT_OK) {
headImageView.setImageURI(Uri.fromFile(file));
//在手機相冊中顯示剛拍攝的圖檔
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
Uri contentUri = Uri.fromFile(file);
mediaScanIntent.setData(contentUri);
sendBroadcast(mediaScanIntent);
}
}