相片动辄5-6MB,所以存储在SQLite中是绝对不合适的,那就应该构建一个内容提供器,暴露相片访问接口,并将实体相片文件保存在沙盒目录下,即包名目录下。
谷歌支持库中提供了FileProvider,我们局不需要自己构建内容提供器了。
仅仅需要声明
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.bignerdranch.android.criminalintent.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/files" />
</provider>
xml文件下的file文件内容如下:
<?xml version="1.0" encoding="utf-8"?>
<paths>
<files-path name="crime_photos" path="."/>
</paths>
目的在于告知Provider应该暴露哪些文件。
一个相片对应一个对象实例,比如一次犯罪活动,就在Crime类中提供定位照片文件的方法
public String getPhotoFilename() {
return "IMG_" + getId().toString() + ".jpg";
}
public File getPhotoFile(Crime crime) {
File firlDir = mContext.getFilesDir();
return new File(firlDir, crime.getPhotoFilename());
}
然后就是调用相机的关键代码了,
final Intent captureImage = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
boolean canTakePhoto = mPhotoFile != null &&
captureImage.resolveActivity(packageManager) != null;
mPhotoButton.setEnabled(canTakePhoto);
mPhotoButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Uri uri = FileProvider.getUriForFile(getActivity(),
"com.bignerdranch.android.criminalintent.fileprovider",
mPhotoFile);
captureImage.putExtra(MediaStore.EXTRA_OUTPUT, uri);
List<ResolveInfo> cameraActivities = getActivity()
.getPackageManager().queryIntentActivities(captureImage,
PackageManager.MATCH_DEFAULT_ONLY);
for (ResolveInfo activity : cameraActivities) {
getActivity().grantUriPermission(activity.activityInfo.packageName,
uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
}
startActivityForResult(captureImage, REQUEST_PHOTO);
}
});
ACTION_IMAGE_CAPTURE打开相机应用,默认只能返回缩略图,并将其包括在onActivityResult返回的intent中。
要获取全尺寸照片,就要制定EXTRA_OUTPUT所match的uri,照片会存在对应uri指向的位置。
获取照片
public void onActivityResult(int requestCode, int resultCode, Intent data) {
...
else if (requestCode == REQUEST_PHOTO) {
Uri uri = FileProvider.getUriForFile(getActivity(),
"com.bignerdranch.android.criminalintent.fileprovider",
mPhotoFile);
getActivity().revokeUriPermission(uri,
Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
updatePhotoView();
}
private void updatePhotoView() {
if (mPhotoFile == null || !mPhotoFile.exists()) {
mPhotoView.setImageDrawable(null);
} else {
Bitmap bitmap = PictureUtils.getScaledBitmap(
mPhotoFile.getPath(), getActivity());
mPhotoView.setImageBitmap(bitmap);
}
}
//最后方法的核心是
BitmapFactory.decodeFile(path, options);
可见和郭婶的相机调用方案接近。
demo地址
网友评论