Android 7.0使用FileProvider获取相机拍照的图片路径
这里主要是基于Android 7.0,Nougat 实现一个获取相机拍照的图片后,使用FileProvider把图片转换为实际的路径。
首先需要在AndroidManifest.xml声明调用相机的权限
<manifest>
...
<uses-feature android:name="android.hardware.camera"
android:required="true" />
...
</manifest>
接着在Activity里实现打开相机拍照
private static final int REQUEST_CAPTURE_IMAGE = 100;
private void openCameraIntent() {
Intent pictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if(pictureIntent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(pictureIntent,REQUEST_CAPTURE_IMAGE);
}
}
在onActivityResult处理拍照捕获图片的结果
@Override
protected void onActivityResult(int requestCode, int resultCode,
Intent data) {
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
if (data != null && data.getExtras() != null) {
Bitmap imageBitmap = (Bitmap) data.getExtras().get("data");
imageView.setImageBitmap(imageBitmap);
}
}
}
这里在ImageView里直接显示Bitmap。如果需要上传图片到服务器,需要把图片保存为临时文件。
创建文件需要声明对外部存储的写权限,在AndroidManifest.xml声明如下:
<manifest>
...
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
...
</manifest>
创建用于保存图片的临时文件createImageFile:
String imageFilePath;
private File createImageFile() throws IOException{
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
String imageFileName = "IMG_" + timeStamp + "_";
File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(imageFileName, ".jpg", storageDir);
imageFilePath = image.getAbsolutePath();
return image;
}
其中imageFilePath用于保存文件的路径。
打开相机时,设置把捕获到的图片Extra保存到FileProvider获取的Uri路径里。openCameraIntent修改如下:
private static final int REQUEST_CAPTURE_IMAGE = 100;
private void openCameraIntent() {
Intent pictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if(pictureIntent.resolveActivity(getPackageManager()) != null){
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
e.printStackTrace();
return;
}
if (photoFile != null) {
Uri photoURI = FileProvider.getUriForFile(this,getPackageName() +".provider",photoFile);
pictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,photoURI);
startActivityForResult(pictureIntent,REQUEST_CAPTURE_IMAGE);
}
}
}
在打开相机时做了这几件事:
- 新建了临时文件phoneFile
- 使用FileProvider获取文件的Uri
- 设置pictureIntent的Extra输出URI
- 打开相机
使用FileProvider需要在AndroidManifest.xml声明provider:
<application>
...
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths">
</meta-data>
</provider>
...
</application>
在res/xml/创建file_paths.xml文件,如容如下:
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="my_images"
path="Android/data/com.example.package.name/files/Pictures" />
</paths>
onActivityResult处理拍照捕获图片的结果修改如下:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_IMAGE) {
if (resultCode == RESULT_OK) {
imageView.setImageURI(Uri.parse(imageFilePath));
}
else if (resultCode == RESULT_CANCELED) {
Toast.makeText(this, "取消拍照", Toast.LENGTH_SHORT).show();
}
}
}
它不再是直接使用Bitmap,而是使用URI来访问图片。