从相机捕获照片时获取FileNotFoundException [英] Getting FileNotFoundException while capturing photo from Camera

查看:120
本文介绍了从相机捕获照片时获取FileNotFoundException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将FileProvider.getUriForFile与给定的 provider_paths.xml 文件一起使用.我做错了什么我没明白.

I am using FileProvider.getUriForFile with given provider_paths.xml file. I am doing something wrong which I am not getting.

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
  <external-path name="StrengGeheim" path="."/>
</paths>

我在 标签内的AndroidManifest.xml文件中添加了此标签:

This I added in my AndroidManifest.xml inside tag:

<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/provider_paths"/>
    </provider>

这是我的相机意图代码:

This is my camera Intent code:

private void cameraIntent() {
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    fileUri = getOutputMediaFileUri();
    intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
    startActivityForResult(intent, CAMERA);
}

private Uri getOutputMediaFileUri() {
    try {
        File file = getOutputMediaFile();
        return FileProvider.getUriForFile(getActivity(), BuildConfig.APPLICATION_ID + ".provider", file);
    }
    catch (IOException ex){
        ex.printStackTrace();
        Toast.makeText(getContext(), MESSAGE_FAILED, Toast.LENGTH_SHORT).show();
    }
    return null;
}

private File getOutputMediaFile() throws IOException {
    File encodeImageDirectory =
            new File(Environment.getExternalStorageDirectory() + IMAGE_DIRECTORY);

    if (!encodeImageDirectory.exists()) {
        encodeImageDirectory.mkdirs();
    }
    String uniqueId = UUID.randomUUID().toString();
    File mediaFile = new File(encodeImageDirectory, uniqueId + ".png");
    mediaFile.createNewFile();
    return mediaFile;
}

在文件Uri中,路径类似于此/StrengGeheim/StrengGeheim/21a70d51-3375-4d44-b698-0727b6f90065.png ,同时创建媒体文件来存储捕获的图像,但是存储图像的路径来自库的是/storage/emulated/0/StrengGeheim/06673da7-876f-4a53-9a3d-288ae033f7ac .捕获照片且应用程序关闭时出现错误消息.

In file Uri the path is something like this /StrengGeheim/StrengGeheim/21a70d51-3375-4d44-b698-0727b6f90065.png while creating the media file to store captured image but the path of storing image from gallery is /storage/emulated/0/StrengGeheim/06673da7-876f-4a53-9a3d-288ae033f7ac. I am getting below error while capturing photo and app is closing.

 E/BitmapFactory: Unable to decode stream: java.io.FileNotFoundException: /StrengGeheim/StrengGeheim/21a70d51-3375-4d44-b698-0727b6f90065.png (No such file or directory)
W/System.err: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.graphics.Bitmap.compress(android.graphics.Bitmap$CompressFormat, int, java.io.OutputStream)' on a null object reference
W/System.err:     at com.stegano.strenggeheim.fragment.FragmentEncode.saveImage(FragmentEncode.java:166)
W/System.err:     at com.stegano.strenggeheim.fragment.FragmentEncode.onActivityResult(FragmentEncode.java:143)
W/System.err:     at android.support.v4.app.FragmentActivity.onActivityResult(FragmentActivity.java:151)
W/System.err:     at android.app.Activity.dispatchActivityResult(Activity.java:7235)
W/System.err:     at android.app.ActivityThread.deliverResults(ActivityThread.java:4320)
W/System.err:     at android.app.ActivityThread.handleSendResult(ActivityThread.java:4367)
W/System.err:     at android.app.ActivityThread.-wrap19(Unknown Source:0)
W/System.err:     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1649)
W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:105)
W/System.err:     at android.os.Looper.loop(Looper.java:164)
W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:6541)
W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
W/System.err:     at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

这是我处理OnActivityResult的方式:

This is how I am handling OnActivityResult:

 @Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == getActivity().RESULT_CANCELED) {
        return;
    }
    try {
        if (requestCode == GALLERY && data != null) {

                    Bitmap bitmap = getBitmapFromData(data, getContext());
                    File mediaFile = getOutputMediaFile();
                    String path = saveImage(bitmap, mediaFile);
                    Log.println(Log.INFO, "Message", path);
                    Toast.makeText(getContext(), MESSAGE_IMAGE_SAVED, Toast.LENGTH_SHORT).show();
                    loadImage.setImageBitmap(bitmap);
                    imageTextMessage.setVisibility(View.INVISIBLE);

        } else if (requestCode == CAMERA) {
                File file =  new File(fileUri.getPath());
                final Bitmap bitmap = BitmapFactory.decodeFile(fileUri.getPath());
                loadImage.setImageBitmap(bitmap);
                saveImage(bitmap, file);
                Toast.makeText(getContext(), MESSAGE_IMAGE_SAVED, Toast.LENGTH_SHORT).show();
                imageTextMessage.setVisibility(View.INVISIBLE);
        }
    } catch (Exception ex) {
        ex.printStackTrace();
        Toast.makeText(getContext(), MESSAGE_FAILED, Toast.LENGTH_SHORT).show();
    }
}

private Bitmap getBitmapFromData(Intent intent, Context context){
    Uri selectedImage = intent.getData();
    String[] filePathColumn = { MediaStore.Images.Media.DATA };
    Cursor cursor = context.getContentResolver().query(selectedImage,filePathColumn, null, null, null);
    cursor.moveToFirst();
    int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
    String picturePath = cursor.getString(columnIndex);
    cursor.close();
    return BitmapFactory.decodeFile(picturePath);
}

private String saveImage(Bitmap bmpImage, File mediaFile) {
    ByteArrayOutputStream bytes = new ByteArrayOutputStream();
    bmpImage.compress(Bitmap.CompressFormat.PNG, 100, bytes);
    try {
        FileOutputStream fo = new FileOutputStream(mediaFile);
        fo.write(bytes.toByteArray());
        MediaScannerConnection.scanFile(getContext(),
                new String[]{mediaFile.getPath()},
                new String[]{"image/png"}, null);
        fo.close();

        return mediaFile.getAbsolutePath();
    } catch (IOException ex) {
        ex.printStackTrace();
    }
    return "";
}

请问有人可以帮忙吗?

推荐答案

File file =  new File(fileUri.getPath());

正如我之前指出的,这是错误的.摆脱这一行.

As I pointed out previously, this is wrong. Get rid of this line.

您需要的File是在创建要放入EXTRA_OUTPUTUri值时使用的那个.与其在字段中按住fileUri,不如在字段中按住File.

The File that you need is the one that you that you are using as part of creating the Uri value that you are putting into EXTRA_OUTPUT. Instead of holding onto fileUri in a field, hold onto that File in a field.

也:

  • 请加载位图并在后台线程上执行磁盘I/O

  • Please load bitmaps and do disk I/O on background thread

请不要浪费用户的时间来创建 second 图像文件,因为您已经拥有一个(IOW,在拥有该文件时请勿调用saveImage())

Please do not waste the user's time creating a second image file, since you already have one (IOW, do not call saveImage() when you already have the file)

这篇关于从相机捕获照片时获取FileNotFoundException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆