Search code examples
androidandroid-camera-intent

How to fix NullPointerException: file when capturing picture from Camera


I am trying to capture an image using the camera, however on saving the file I get the following error:

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$000(ReportFoundItem.java:39)
    at com.example.denny.lostandfound.ReportFoundItem$1.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)

I want to capture image directly from the camera and save it to a database. How can this be fixed?

AndroidManifest.xml file:

<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>....

My 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();
}

}

I expect to save the picture directly once I capture it from the camera.


Solution

  • Try this one ...

    Image Captured....

    private int REQUEST_IMAGE_CAPTURE = 100;
    

    on Click ....

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

    on 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);            
        }
    

    and other Method....

     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);
    }
    
    }
    

    Note:- you are getting URI null because the image you capturing doesn't have any path. So URI return null..