Android中的FileProvider路径创建和BitmapFactory.decodefile问题

我试图使用BitmapFactory.decodefile()来创建缩小
相机照片的版本,并将其设置为我的framelayout中的imageview.
遵循Android开发者的以下说明:
https://developer.android.com/training/camera/photobasics.html
在这些指令中,文件被创建并存储在fileprovider中,该文件提供器包含一些以xml格式化的元数据文件.不知何故,BitmapFactory.decodefile()似乎无法访问此文件,该文件存储内容uri驻​​留在fileprovider中的图片.
fileprovider是在androidmanifest文件中创建的,如下所示:

<provider
android:authorities="mypackagename.fileprovider"
android:name="android.support.v4.content.FileProvider"
android:exported="false" android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths"  >
</meta-data>
</provider>

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/mypackagename/files/Pictures/" />
</paths>

通过以下方法生成图片所在的文件名:

private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(imageFileName,".jpg",storageDir);

// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = image.getAbsolutePath();
Log.d("absolute",""+image.getAbsolutePath());
return image;
}

代码启动一个意图,以便使用startactivityforresult()拍照,如下所示:

Intent i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Ensure that there's a camera activity to handle the intent
if (i.resolveActivity(getPackageManager()) != null) {
// Create the File where the photo should go
photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
// Error occurred while creating the File

}
// Continue only if the File was successfully created
if (photoFile != null) {
Uri photoURI = FileProvider.getUriForFile  (this,"mypackagename.fileprovider",photoFile);

i.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(i,TAKE_PICTURE);
}
}

现在,onActivityForResult()方法启动,但是如果我像这样设置我的if语句
    if(requestCode == TAKE_PICTURE&& resultCode == RESULT_OK)
它不起作用.我不知道为什么.
通过阅读fileprovider类上的android参考文档,我看到了
我必须打开photoUri,这是我的意图中的额外传递.
根据文档,我必须使用ContentResolver.openFileDescriptor打开它,它将返回一个ParcelFileDescriptor.不知何故,这就是相机刚刚拍摄的照片.不知何故,我需要从这个ParcelFileDescriptor对象访问文件名并将其传递给BitmapFactory.decode文件,以缩小图片位图并将其设置在我的imageview上.我不知道怎么回事

当我尝试缩放图片位图时,我有以下代码返回-1,这意味着“根据用于BitmapFactory类的android参考文档”“解码文件时出现问题”.我不知道为什么会有问题.这是返回-1的代码:

BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);

int photoW = bmOptions.outWidth;
int photoH = bmOptions.outHeight;

photoW和photoH都返回-1.请记住,变量mCurrentPhotoPath在方法CreateImageFile()中初始化,一直在这个问题的顶部.

我也尝试过,

BitmapFactory.decodeFile(photoFile.getAbsolutePath(), bmOptions);

但结果仍然相同,实际上mCurrentPhotoPath和photoFile.getAbsolutePath()是相等的字符串.

我认为以某种方式,fileprovider及其元数据xml文件以某种方式隐藏了来自BitmapFactory.decodefile()的文件路径.

我测试应用程序时拍摄的照片也存储在手机图片库中.

请提供任何建议或建议,因为我需要继续使用tess-two库并使用相机中的图片执行OCR.

谢谢你的建议

解决方法:

我遇到了完全相同的问题,这就是我如何处理它:首先设置i.setFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);如上所述,在启动相机之前.然后,不要使用BitmapFactory.decodeFile()方法,因为它只适用于使用Uri.fromFile()检索的文件:///类型的Uris,但不适用于使用FileProvider.getUriForFile检索的内容:// Uris类型()这是API> = 24的必需方式.

而是使用ContentResolver打开InputStream并解码图像,如下所示:

BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
ContentResolver cr = getActivity().getContentResolver();
InputStream input = null;
InputStream input1 = null;
try {
    input = cr.openInputStream(photoUri);
    BitmapFactory.decodeStream(input, null, bmOptions);
    if (input != null) {
        input.close();
    }
} catch (Exception e) {
    e.printStackTrace();
}

int photoW = bmOptions.outWidth;
int photoH = bmOptions.outHeight;
try {
    input1 = cr.openInputStream(photoUri);
    Bitmap takenImage = BitmapFactory.decodeStream(input1);                
    if (input1 != null) {
        input1.close();
    }
} catch (Exception e) {
    e.printStackTrace();
}

注意,为了获得Bitmap,您必须打开第二个输入流,因为第一个输入流不能重复使用.

上一篇:我可以在桌面应用程序中使用Android SDK类吗?


下一篇:android – 无法解析IntelliJ中的符号BitmapFactory.decodeResource