文件提供程序中的空指针异常

Null Pointer Exception in File Provider

我设计了一个简单的片段来拍摄图片,然后使用文件提供程序将相应的图片加载到屏幕上的 ImageView 上。我目前在访问它时遇到空指针异常,尽管它在那里并且在正确的标题下。我已经检查了我的所有设置并确保它们对应,但我的应用程序无法找到我的文件提供程序。我的代码如下

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.Image;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.app.Fragment;
import android.support.v4.content.FileProvider;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import java.io.File;
import java.util.Date;
import android.net.Uri;
import android.widget.ImageView;
import java.io.IOException;
import java.text.SimpleDateFormat;

/**
 * A simple {@link Fragment} subclass.
 * Use the {@link StudentID#newInstance} factory method to
 * create an instance of this fragment.
 */
public class StudentID extends Fragment {
    String mCurrentPhotoPath;
    Uri mPhotoURI;
    static final int REQUEST_IMAGE_CAPTURE = 1;
    static final int REQUEST_TAKE_PHOTO = 1;
    ImageView picView;
    FloatingActionButton button;
    public StudentID() {
        // Required empty public constructor
    }

    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @return A new instance of fragment StudentID.
     */
    // TODO: Rename and change types and number of parameters
    public static StudentID newInstance() {
        StudentID fragment = new StudentID();
        Bundle args = new Bundle();
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_student_id, container, false);
        picView = (ImageView)view.findViewById(R.id.idPic);
        button = (FloatingActionButton)view.findViewById(R.id.picButton);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                takePicture();
            }
        });
        //updateImage();
        return view;
    }
    public void takePicture() {
        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        if (takePictureIntent.resolveActivity(getContext().getPackageManager()) != null) {
            startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
        }
        File photoFile = null;
        try {
            photoFile = createImageFile();
        } catch (IOException ex) {
        }
        // Continue only if the File was successfully created
        if (photoFile != null) {
            mPhotoURI = FileProvider.getUriForFile(getContext(),
                    "com.tble.brgo.fileprovider",
                    photoFile);
            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, mPhotoURI);
            startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
        }
    }
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == getActivity().RESULT_OK) {
            picView.setImageURI(mPhotoURI);
        }
    }
    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 = getContext().getExternalFilesDir(Environment.DIRECTORY_PICTURES);
        File image = File.createTempFile(
                imageFileName,  /* prefix */
                ".jpg",         /* suffix */
                storageDir      /* directory */
        );
        mCurrentPhotoPath = "file:" + image.getAbsolutePath();
        return image;
    }


}

Android 清单

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.tble.brgo">
    <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="com.tble.brgo.fileprovider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths.xml"></meta-data>
    </provider>
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-feature android:name="android.hardware.camera" android:required="false" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
        android:maxSdkVersion="18"/>

文件提供者:

<?xml version="1.0" encoding="utf-8"?>
<paths xmnls="http://schemas.android.com/apk/res/android">
    <external-path name="my_images" path="Android/data/com.tble.brgo.BRGO/files/Pictures" />
</paths>

我刚刚使用这一小段代码完成了这项任务。

String imageName = String.valueOf(System.currentTimeMillis());
                filename = Environment.getExternalStorageDirectory().getPath() + "/YourFolder/" + imageName + ".jpg";
                imageUri = Uri.fromFile(new File(filename));
                // start default camera
                Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
                cameraIntent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT,
                        imageUri);
                startActivityForResult(cameraIntent, 100);

onActivityResult

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if(requestCode != 100 || filename == null)
        return;
    bitmap = BitmapFactory.decodeFile(imageUri.getPath()); //set bitmap to your imageview.

}

在附加文件中设置文件路径之前,您已经启动了 Action Image Capture Intent。

这是对您的代码的修改。

public void takePicture() {
        File photoFile = null;
        try {
            photoFile = createImageFile();
        } catch (IOException ex) {
        }
        // Continue only if the File was successfully created
        if (photoFile != null) {
            mPhotoURI = FileProvider.getUriForFile(getContext(),
                    "com.tble.brgo.fileprovider",
                    photoFile);
            Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            if (takePictureIntent.resolveActivity(getContext().getPackageManager()) != null) {
                takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, mPhotoURI);
                startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
            }
        }
    }

如果您使用 getExternalFilesDir() 创建文件,那么您应该在文件提供者 xml 文件中使用 external-files-path 而不是 external-path