从相机捕获图片时如何修复 NullPointerException: file

How to fix NullPointerException: file when capturing picture from Camera

我正在尝试使用相机拍摄图像,但是在保存文件时出现以下错误:

java.lang.NullPointerException: file
    at android.net.Uri.fromFile(Uri.java:452)
    at com.example.denny.lostandfound.ReportFoundItem.dispatchTakePictureIntent(ReportFoundItem.java:84)
    at com.example.denny.lostandfound.ReportFoundItem.access[=10=]0(ReportFoundItem.java:39)
    at com.example.denny.lostandfound.ReportFoundItem.onClick(ReportFoundItem.java:169)
    at android.view.View.performClick(View.java:5265)
    at android.view.View$PerformClick.run(View.java:21534)
    at android.os.Handler.handleCallback(Handler.java:815)
    at android.os.Handler.dispatchMessage(Handler.java:104)
    at android.os.Looper.loop(Looper.java:207)
    at android.app.ActivityThread.main(ActivityThread.java:5728)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:679)

我想直接从相机捕获图像并将其保存到数据库中。如何解决?

AndroidManifest.xml 文件:

<uses-permission android:name="android.permission.INTERNET" />
<uses-feature android:name="android.hardware.camera"
    android:required="true" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

<application
    android:allowBackup="true"
    android:icon="@drawable/icon"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="com.example.denny.fileprovider"
        android:exported="false"
        android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/filepaths" />
    </provider>
    <activity android:name=".Home">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>....

我的ReportFoundItem.xml:

public class ReportFoundItem extends AppCompatActivity {

private DatabaseReference databaseFound;

private static final int CAPTURE_IMAGE = 1;

private Uri picUri;

private StorageReference mStorage;

private ProgressDialog mProgress;

private EditText etemail;
private EditText etphone;
private Spinner etcategory;
private Spinner etsub_category;
private Button btncapture;
private ImageView imageView;
private EditText etdate_found;
private EditText etlocation_found;
private EditText etdetails;

private void dispatchTakePictureIntent() {
    Intent i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
    File file = getOutputMediaFile(1);
    picUri = Uri.fromFile(file);
    i.putExtra(MediaStore.EXTRA_OUTPUT,picUri); // set the image file
    startActivityForResult(i, CAPTURE_IMAGE);
        }

public File getOutputMediaFile(int type) {
    File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
            Environment.DIRECTORY_PICTURES), "TRARC");


    /**Create the storage directory if it does not exist*/
    if (! mediaStorageDir.exists()){
        if (! mediaStorageDir.mkdirs()){
            return null;
        }
    }

    /**Create a media file name*/
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    File mediaFile;
    if (type == 1){
        mediaFile = new File(mediaStorageDir.getPath() + File.separator +
                "IMG_"+ timeStamp + ".png");
    } else {
        return null;
    }

    return mediaFile;
}





@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_report_found_item);

    mStorage = FirebaseStorage.getInstance().getReference();

    databaseFound = FirebaseDatabase.getInstance().getReference("found");

    etemail = (EditText)findViewById(R.id.etemail);
    etphone = (EditText)findViewById(R.id.etphone);
    etcategory = (Spinner)findViewById(R.id.etcategory);
    etsub_category = (Spinner)findViewById(R.id.etsub_category);
    btncapture = (Button)findViewById(R.id.btncapture);
    imageView = (ImageView)findViewById(R.id.imageView);
    etdate_found = (EditText) findViewById(R.id.etdate_found);
    etlocation_found = (EditText) findViewById(R.id.etlocation_found);
    etdetails = (EditText) findViewById(R.id.etdetails);

    mProgress = new ProgressDialog(this);

    btncapture.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            dispatchTakePictureIntent();
        }
    });



}



@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (requestCode == CAPTURE_IMAGE && resultCode == RESULT_OK){

        mProgress.setMessage("Uploading Image...Please wait...");
        mProgress.show();

        final StorageReference filepath = mStorage.child("Found_Photos").child(uri.getLastPathSegment());

        filepath.putFile(uri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
            @Override
            public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {

                mProgress.dismiss();

                //creating the upload object to store uploaded image details
                Upload upload = new Upload(uri.toString(),taskSnapshot.getDownloadUrl().toString());

                //adding an upload to firebase database
                String uploadId = databaseFound.push().getKey();
                databaseFound.child(uploadId).setValue(upload);

                Uri downloadUri = taskSnapshot.getDownloadUrl();

                Picasso.with(ReportFoundItem.this).load(downloadUri).fit().centerCrop().into(imageView);

                //Toast.makeText(ReportFoundItem.this, "Uploading finished...", Toast.LENGTH_LONG).show();

            }
        }).addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() {
            @Override
            public void onProgress(UploadTask.TaskSnapshot taskSnapshot) {

                double progress = (100.0 * taskSnapshot.getBytesTransferred()) / taskSnapshot.getTotalByteCount();
                mProgress.setMessage("Uploaded " + ((int) progress) + "%...");

            }
        });//add on failure listener
    }
}

private void reportFoundItem() {
    String email = etemail.getText().toString().trim();
    String phone = etphone.getText().toString().trim();
    String category = etcategory.getSelectedItem().toString().trim();
    String sub_category = etsub_category.getSelectedItem().toString().trim();
    String date_found = etdate_found.getText().toString().trim();
    String location_found = etlocation_found.getText().toString().trim();
    String details = etdetails.getText().toString().trim();
    //check if empty
    if (!TextUtils.isEmpty(email)){
        //getting the key
        String id = databaseFound.push().getKey();
        //save the data under lost
        Found found = new Found(id, email, phone, category, sub_category, date_found, location_found, details);
        //set the value under the id
        databaseFound.child(id).setValue(found);
        Toast.makeText(this, "Found Item added successfully!", Toast.LENGTH_SHORT).show();
    } else {
        Toast.makeText(this, "Please enter all Fields!", Toast.LENGTH_SHORT).show();
    }

}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.savetodb, menu);
    return super.onCreateOptionsMenu(menu);

}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.save:
            reportFoundItem();
            ClearEditTextAfterDoneTask();
    }
    return true;
}

@Override
public void onBackPressed()
{
    super.onBackPressed();
    startActivity(new Intent(ReportFoundItem.this, Home.class));
    finish();

}

public void ClearEditTextAfterDoneTask() {
    etemail.getText().clear();
    etphone.getText().clear();
    etdate_found.getText().clear();
    etlocation_found.getText().clear();
    etdetails.getText().clear();
}

}

我希望在从相机拍摄后直接保存图片。

 @Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (resultCode == Activity.RESULT_OK) {
        if (requestCode == SELECT_FILE)
            onSelectFromGalleryResult(data);
        else if (requestCode == REQUEST_CAMERA)
            onCaptureImageResult(data);
    }
}

  private void onCaptureImageResult(Intent data) {
    Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
    ByteArrayOutputStream bytes = new ByteArrayOutputStream();
    thumbnail.compress(Bitmap.CompressFormat.JPEG, 90, bytes);

    File destination = new File(Environment.getExternalStorageDirectory(),
            System.currentTimeMillis() + ".jpg");

    FileOutputStream fo;
    try {
        destination.createNewFile();
        fo = new FileOutputStream(destination);
        fo.write(bytes.toByteArray());
        fo.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

    user_image.setImageBitmap(thumbnail);
  }




   private void onSelectFromGalleryResult(Intent data) {

    Bitmap bm = null;
    if (data != null) {
        try {
            bm = 
MediaStore.Images.Media.getBitmap(getApplicationContext().getContentResolver(), 
data.getData());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    user_image.setImageBitmap(bm);
}

检查数据是否为 ​​!=null 以避免空指针异常

试试这个...

已拍摄图像....

private int REQUEST_IMAGE_CAPTURE = 100;

点击....

Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
   if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
       startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
    }

关于 ActivityResult ....

if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
        // Bundle extras = data.getExtras();
        Bitmap bitmap =  ImageUtils.getBitmapFromIntent(this, data);
        mImage.setImageBitmap(bitmap);// mImage is a ImageView which is bind previously.
        String imgPath = ImageUtils.createFile(this, bitmap);
        File imageFile = new File(imgPath);            
    }

和其他方法....

 public class ImageUtils {

   public static Bitmap getBitmapFromIntent(Context context,Intent data) {
    Bitmap bitmap = null;

    if (data.getData() == null) {
        bitmap = (Bitmap) data.getExtras().get("data");
    } else {
        try {
            bitmap = MediaStore.Images.Media.getBitmap(context.getContentResolver(), data.getData());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    return bitmap;
}


public static String createFile(Context context, Bitmap data) {
    Uri selectedImage = getImageUri(context,data);
    String[] filePath = {MediaStore.Images.Media.DATA};
    Cursor c = context.getContentResolver().query(selectedImage, filePath, null, null, null);
    c.moveToFirst();
    c.getColumnIndex(filePath[0]);
    int columnIndex = c.getColumnIndex(filePath[0]);
    String picturePath = c.getString(columnIndex);
    c.close();

    return picturePath;
}

public static Uri getImageUri(Context context, Bitmap inImage) {
    ByteArrayOutputStream bytes = new ByteArrayOutputStream();
    inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
    String path = MediaStore.Images.Media.insertImage(context.getContentResolver(), inImage, "Pet_Image", null);
    return Uri.parse(path);
}

}

注意:- 您得到的 URI 为空,因为您捕获的图像没有任何路径。所以 URI return 为空..

我在项目中就是这样做的。

public void openCamera() {
    Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
    File file = createImageFile();
    boolean isDirectoryCreated = file.getParentFile().mkdirs();
    Log.d("===PickFragment", "openCamera: isDirectoryCreated: " + isDirectoryCreated);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        Uri tempFileUri = FileProvider.getUriForFile(getActivity().getApplicationContext(),
                "com.scanlibrary.provider", // As defined in Manifest
                file);
        cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, tempFileUri);
    } else {
        Uri tempFileUri = Uri.fromFile(file);
        cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, tempFileUri);
    }
    startActivityForResult(cameraIntent, ScanConstants.START_CAMERA_REQUEST_CODE);
}

private File createImageFile() {
    clearTempImages();
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new
            Date());
    File file = new File(Environment
        .getExternalStorageDirectory().getPath(), "IMG_" + timeStamp +
            ".jpg");
    fileUri = Uri.fromFile(file);
    return file;
}