我的应用程序的功能之一是允许用户分配存储在数据库中的项目的照片。这可以通过使用内置相机拍摄新照片或从图库中选择图像来完成。然后,app调整捕获图像的大小,检索完整大小的图像URI,并将两者存储在数据库中。如果用户希望使用默认图像查看器加载完整尺寸的图像,则存储完整尺寸的图像URI供以后使用。一切正常,除了查看者无法在拍摄照片后立即从捕获的图像URI中加载图像,但只有从库中选择了相同的图像时,才可以加载该图像。好的,这是代码:
表现:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.packagename.inventoryapp.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/fileprovider" />
</provider>
fileprovider.xml
<external-files-path
name="images"
path="Pictures" />
处理相机:
@NeedsPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
public void onLaunchCamera(){
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
photoFileName = String.valueOf(System.currentTimeMillis()) + ".jpg";
photoFile = getPhotoFileUri(photoFileName);
Uri fileProvider = FileProvider.getUriForFile(this,
ProductContract.CONTENT_AUTHORITY + ".fileprovider", photoFile);
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileProvider);
if (intent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
}
}
public File getPhotoFileUri(String fileName){
File mediaStorageDir = new File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), APP_TAG);
if (!mediaStorageDir.exists() && !mediaStorageDir.mkdirs()){
Log.d(APP_TAG, "failed to create directory");
}
return new File(mediaStorageDir.getPath() + File.separator + fileName);
}
onActivtiyResult(takeImage-全局Bitmap变量; mPicUri-全局Uri变量):
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
/* User chose to take a new photo */
if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
File takenPhotoUri = getPhotoFileUri(photoFileName);
mPicUri = FileProvider.getUriForFile
(this, ProductContract.CONTENT_AUTHORITY + ".fileprovider", photoFile);
Bitmap fullSizeImage = BitmapFactory.decodeFile(takenPhotoUri.getAbsolutePath());
takenImage = BitmapScaler.scaleToFitWidth
(fullSizeImage, mProductImageView.getWidth() / 100 * 50);
} else { // Result was a failure
Toast.makeText(this, getString(R.string.no_picture_taken),
Toast.LENGTH_SHORT).show();
}
}
/* User chose to take an an existing photo from the gallery */
else if (requestCode == PICK_PHOTO_CODE){
if (resultCode == RESULT_OK) {
mPicUri = data.getData();
try {
Bitmap fullSizeImage = MediaStore.Images.Media.getBitmap
(getContentResolver(), mPicUri);
takenImage = BitmapScaler.scaleToFitWidth
(fullSizeImage, mProductImageView.getWidth() / 100 * 60);
} catch (IOException e) {
e.printStackTrace();
}
}
}
mProductImageView.setImageBitmap(takenImage);
/* Save image and it's URi to the database */
if (takenImage != null){
ContentValues values = new ContentValues();
values.put(ProductEntry.COLUMN_IMAGE, DbBitmapUtility.getBytesArray(takenImage));
values.put(ProductEntry.COLUMN_IMAGE_URL, mPicUri.toString());
int rows = getContentResolver().update(mProductUri, values, null, null);
}
}
打开默认的图像查看器以从Uri加载完整尺寸的图像:
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(mPicUri);
startActivity(intent);
我意识到问题出在所拍摄照片的Uri路径中。当我以上述方式检索它时,我得到如下信息:
content://com.packagename.inventoryapp.fileprovider/images/InventoryApp/1526632674426.jpg
并且图像查看器正在启动,并且黑屏指示它正在搜索图像而没有成功。我尝试使用getAbsolutePath()方法获取mPicUri,这导致应用程序在启动带有该消息的意图时崩溃:
android.content.ActivityNotFoundException:找不到用于处理Intent的活动{act = android.intent.action.VIEW dat = / storage / emulated / 0 / Android / data / com.packagename.inventoryapp / files / Pictures / InventoryApp / 1526635391354.jpg }
相反,从现有库中获取图像效果很好,图像Uri看起来像:
content://com.google.android.apps.photos.contentprovider/0/1/content%3A%2F%2Fmedia%2Fexternal%2Fimages%2Fmedia%2F2504/ORIGINAL/NONE/1872082740
因此,问题是有可能以某种方式检索不是应用程序专用的捕获图像Uri,并且可能被图像查看器显示为红色吗?
android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.VIEW dat=/storage/emulated/0/Android/data/com.packagename.inventoryapp/files/Pictures/InventoryApp/1526635391354.jpg }
那是无效的Uri
。
AUri
有一个方案。你的不是。您的文件类似于裸露的文件系统路径。原则上,您可以将其转换为Uri
using Uri.fromFile()
。但是,在Android 7.0+上,使用Uri
会失败,并带有FileUriExposedException
。
而是使用File
with FileProvider.getUriForFile()
,并将其提供Uri
给您ACTION_VIEW
Intent
。此外,请务必打电话addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
上Intent
,允许第三方应用程序读取由该标识的内容Uri
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句