35

i've really frustased to solve my problem, i have an application that using camera, when camera capture a photo, it will display on activity, when i'm not using cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, mPhotoUri); photo will display on activity, but the name and path file is not like what i wanted. i'm using galaxy tab for compiling it, i have follow tutorial to solve my problem from here , here and here but my application still force close and eror, this is my code :

{
    File sdCard = Environment.getExternalStorageDirectory();
    File path = new File (sdCard.getAbsolutePath() + "/android/data/spaj_foto");
    path.mkdir();
    File file = new File (path,"spaj_foto.png");
    String filePath ="/android/data/spaj_foto/spaj_foto.png";

    try {
        file.createNewFile();
    } catch (IOException e) {}       


    mPhotoUri = Uri.fromFile(file); 
    values.put(MediaStore.Images.ImageColumns.DATA, file.getPath());
    mPhotoUri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);

    Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
    cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, mPhotoUri);
    startActivityForResult(cameraIntent,TAKE_PHOTO_CODE );  

}

activityresult method :

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {  
    if (requestCode == TAKE_PHOTO_CODE && resultCode == RESULT_OK) {
        Bitmap photo = (Bitmap) data.getExtras().get("data"); 
        image_spaj.setImageBitmap(photo);


        // CALL THIS METHOD TO GET THE URI FROM THE BITMAP
        Uri tempUri = getImageUri(getApplicationContext(), photo);

        // CALL THIS METHOD TO GET THE ACTUAL PATH
        File finalFile = new File(getRealPathFromURI(tempUri));

//              System.out.println(mImageCaptureUri);
    }  
}
public String getRealPathFromURI(Uri mPhotoUri) {
    Cursor cursor = getContentResolver().query(mPhotoUri, null, null, null, null); 
    cursor.moveToFirst(); 
    int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA); 
    return cursor.getString(idx); 
}

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

this is my logcat says:

    09-27 10:59:43.186: E/AndroidRuntime(31318): java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=0, result=-1, data=null} to activity {org.example.touch/org.example.touch.FormSpaj}: java.lang.NullPointerException
09-27 10:59:43.186: E/AndroidRuntime(31318):    at android.app.ActivityThread.deliverResults(ActivityThread.java:3179)
09-27 10:59:43.186: E/AndroidRuntime(31318):    at android.app.ActivityThread.handleSendResult(ActivityThread.java:3222)
09-27 10:59:43.186: E/AndroidRuntime(31318):    at android.app.ActivityThread.access$1100(ActivityThread.java:140)
09-27 10:59:43.186: E/AndroidRuntime(31318):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1276)
09-27 10:59:43.186: E/AndroidRuntime(31318):    at android.os.Handler.dispatchMessage(Handler.java:99)
09-27 10:59:43.186: E/AndroidRuntime(31318):    at android.os.Looper.loop(Looper.java:137)
09-27 10:59:43.186: E/AndroidRuntime(31318):    at android.app.ActivityThread.main(ActivityThread.java:4895)
09-27 10:59:43.186: E/AndroidRuntime(31318):    at java.lang.reflect.Method.invokeNative(Native Method)
09-27 10:59:43.186: E/AndroidRuntime(31318):    at java.lang.reflect.Method.invoke(Method.java:511)
09-27 10:59:43.186: E/AndroidRuntime(31318):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:994)
09-27 10:59:43.186: E/AndroidRuntime(31318):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:761)
09-27 10:59:43.186: E/AndroidRuntime(31318):    at dalvik.system.NativeStart.main(Native Method)
09-27 10:59:43.186: E/AndroidRuntime(31318): Caused by: java.lang.NullPointerException
09-27 10:59:43.186: E/AndroidRuntime(31318):    at org.example.touch.FormSpaj.onActivityResult(FormSpaj.java:993)
09-27 10:59:43.186: E/AndroidRuntime(31318):    at android.app.Activity.dispatchActivityResult(Activity.java:5347)
09-27 10:59:43.186: E/AndroidRuntime(31318):    at android.app.ActivityThread.deliverResults(ActivityThread.java:3175)
09-27 10:59:43.186: E/AndroidRuntime(31318):    ... 11 more

i really hope someone can help me to solve my problem, i already stack and can't thinking anyway again, please someone help me... thank you.

Aoyama Nanami
  • 2,532
  • 9
  • 32
  • 50
  • This is just a null pointer exception, what is the line FormSpaj.java:993? – Yoann Hercouet Sep 27 '13 at 04:06
  • Bitmap photo = (Bitmap) data.getExtras().get("data"); – Aoyama Nanami Sep 27 '13 at 04:07
  • `getExtras()` can return null if there is no extras Bundle. You should make sure the value returned from `getExtras()` isn't `null`. – jedwards Sep 27 '13 at 04:09
  • my image is saved on my path that i wanted, i have no idea, why is this getting null – Aoyama Nanami Sep 27 '13 at 04:10
  • 1
    Also, you're setting the Extras with the "key" `MediaStore.EXTRA_OUTPUT`, but attempting to get the key `data` -- are you sure they are equal? Edit: They're not. `MediaStore.EXTRA_OUTPUT == "output"`. – jedwards Sep 27 '13 at 04:11
  • i think like that, is that false? – Aoyama Nanami Sep 27 '13 at 04:13
  • 1
    If you store the value with the "key" `MediaStore.EXTRA_OUTPUT`, you'll of course want to fetch it using the same key, but definitely not "data". – jedwards Sep 27 '13 at 04:18
  • @AoyamaNanami `android:configChanges="orientation|keyboardHidden|screenSize"` add the configChanges for particular activity. Yesterday i had same problem. after add that configChanges its working fine. try it – Murali Ganesan Sep 27 '13 at 04:57
  • android:configChanges is affected to camera result image ? i did not understand, can yo please explain it ? – Rahul Mandaliya Feb 08 '17 at 07:26

3 Answers3

22

Make sure you have both Camera Permission and READ/WRITE External Storage Permissions.

Try this is working like charm with me

private String selectedImagePath = "";
    final private int PICK_IMAGE = 1;
    final private int CAPTURE_IMAGE = 2;

public Uri setImageUri() {
        // Store image in dcim
        File file = new File(Environment.getExternalStorageDirectory() + "/DCIM/", "image" + new Date().getTime() + ".png");
        Uri imgUri = Uri.fromFile(file);
        this.imgPath = file.getAbsolutePath();
        return imgUri;
    }


    public String getImagePath() {
        return imgPath;
    }

btnGallery.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                Intent intent = new Intent();
                intent.setType("image/*");
                intent.setAction(Intent.ACTION_GET_CONTENT);
                startActivityForResult(Intent.createChooser(intent, ""), PICK_IMAGE);

            }
        });

        btnCapture.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                final Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                intent.putExtra(MediaStore.EXTRA_OUTPUT, setImageUri());
                startActivityForResult(intent, CAPTURE_IMAGE);
            }
        });

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode != Activity.RESULT_CANCELED) {
            if (requestCode == PICK_IMAGE) {
                selectedImagePath = getAbsolutePath(data.getData());
                imgUser.setImageBitmap(decodeFile(selectedImagePath));
            } else if (requestCode == CAPTURE_IMAGE) {
                selectedImagePath = getImagePath();
                imgUser.setImageBitmap(decodeFile(selectedImagePath));
            } else {
                super.onActivityResult(requestCode, resultCode, data);
            }
        }

    }


public Bitmap decodeFile(String path) {
        try {
            // Decode image size
            BitmapFactory.Options o = new BitmapFactory.Options();
            o.inJustDecodeBounds = true;
            BitmapFactory.decodeFile(path, o);
            // The new size we want to scale to
            final int REQUIRED_SIZE = 70;

            // Find the correct scale value. It should be the power of 2.
            int scale = 1;
            while (o.outWidth / scale / 2 >= REQUIRED_SIZE && o.outHeight / scale / 2 >= REQUIRED_SIZE)
                scale *= 2;

            // Decode with inSampleSize
            BitmapFactory.Options o2 = new BitmapFactory.Options();
            o2.inSampleSize = scale;
            return BitmapFactory.decodeFile(path, o2);
        } catch (Throwable e) {
            e.printStackTrace();
        }
        return null;

    }

public String getAbsolutePath(Uri uri) {
        String[] projection = { MediaColumns.DATA };
        @SuppressWarnings("deprecation")
        Cursor cursor = managedQuery(uri, projection, null, null, null);
        if (cursor != null) {
            int column_index = cursor.getColumnIndexOrThrow(MediaColumns.DATA);
            cursor.moveToFirst();
            return cursor.getString(column_index);
        } else
            return null;
    }
Community
  • 1
  • 1
Biraj Zalavadia
  • 28,348
  • 10
  • 61
  • 77
  • thank you for your help... but i have one question, why when i capture another image, this is not rewrite the image that have created before? – Aoyama Nanami Sep 27 '13 at 06:43
  • because we generate unique uri in this method setImageUri() by appending current time milliseconds. If you want to overwrite the file give static hard coded file name in setImageUri() method. – Biraj Zalavadia Sep 27 '13 at 06:49
  • i have made like this : File file = new File(Environment.getExternalStorageDirectory() +"/android/data/spaj_foto/spaj_foto.png"); Uri imgUri = Uri.fromFile(file); this.imgPath = file.getAbsolutePath(); – Aoyama Nanami Sep 27 '13 at 06:53
  • This will not work like a charm for the Android version running above Android N, only working for the Android Versions below N – rajat singh Dec 28 '18 at 13:23
7

Try this, Yesterday i had same problem. using below code i rectify problem. just try on it.

Note : And also add configChanges for particular activity. while calling the camera intent activity will be refreshed. you need to avoid that. android:configChanges="orientation|keyboardHidden|screenSize"

btnGallery.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
           intent = new Intent(Intent.ACTION_PICK);
                            intent.setType("image/*");
                            startActivityForResult(intent, 1);
        }
    });

    btnCapture.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            Intent intent = new Intent(
                                    MediaStore.ACTION_IMAGE_CAPTURE);
                            File file = new File(Environment
                                    .getExternalStorageDirectory(),
                                    "test.jpg");

                            outputFileUri = Uri.fromFile(file);
                            Log.d("TAG", "outputFileUri intent"
                                    + outputFileUri);
                            intent.putExtra(MediaStore.EXTRA_OUTPUT,
                                    outputFileUri);
                            startActivityForResult(intent, 0);
        }
    });

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // TODO Auto-generated method stub
    super.onActivityResult(requestCode, resultCode, data);

    switch (requestCode) {
    case 0:
        if (resultCode == RESULT_OK) {
            Log.d("TAG", "outputFileUri RESULT_OK" + outputFileUri);
            if (outputFileUri != null) {

                Bitmap bitmap;
                bitmap = decodeSampledBitmapFromUri(outputFileUri,
                        image.getWidth(), image.getHeight());

                if (bitmap == null) {
                    Toast.makeText(getApplicationContext(),
                            "the image data could not be decoded",
                            Toast.LENGTH_LONG).show();

                } else {
                    Toast.makeText(
                            getApplicationContext(),
                            "Decoded Bitmap: " + bitmap.getWidth() + " x "
                                    + bitmap.getHeight(), Toast.LENGTH_LONG)
                            .show();
                    image.setImageBitmap(bitmap);
                }
            }
        }
        break;
    case 1:
        if (resultCode == RESULT_OK) {
            Uri targetUri = data.getData();
            Log.d("TAG", "datae" + targetUri);
            Bitmap bitmap;
            bitmap = decodeSampledBitmapFromUri(targetUri,
                    image.getWidth(), image.getHeight());

            if (bitmap == null) {
                Toast.makeText(getApplicationContext(),
                        "the image data could not be decoded",
                        Toast.LENGTH_LONG).show();

            } else {
                Toast.makeText(
                        getApplicationContext(),
                        "Decoded Bitmap: " + bitmap.getWidth() + " x "
                                + bitmap.getHeight(), Toast.LENGTH_LONG)
                        .show();
                image.setImageBitmap(bitmap);
            }
        }
        break;

    default:
        break;
    }
}

public Bitmap decodeSampledBitmapFromUri(Uri uri, int reqWidth,
        int reqHeight) {

    Bitmap bm = null;

    try {
        // First decode with inJustDecodeBounds=true to check dimensions
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(getContentResolver()
                .openInputStream(uri), null, options);

        // Calculate inSampleSize
        options.inSampleSize = calculateInSampleSize(options, reqWidth,
                reqHeight);

        // Decode bitmap with inSampleSize set
        options.inJustDecodeBounds = false;
        bm = BitmapFactory.decodeStream(getContentResolver()
                .openInputStream(uri), null, options);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
        Toast.makeText(getApplicationContext(), e.toString(),
                Toast.LENGTH_LONG).show();
    }

    return bm;
}

public int calculateInSampleSize(BitmapFactory.Options options,
        int reqWidth, int reqHeight) {
    // Raw height and width of image
    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;

    if (height > reqHeight || width > reqWidth) {
        if (width > height) {
            inSampleSize = Math.round((float) height / (float) reqHeight);
        } else {
            inSampleSize = Math.round((float) width / (float) reqWidth);
        }
    }
    return inSampleSize;
}
Murali Ganesan
  • 2,925
  • 4
  • 20
  • 31
7

I think following line causes the issue.

Bitmap photo = (Bitmap) data.getExtras().get("data"); 

You pass the file uri already as following

cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, mPhotoUri);

When you pass EXTRA_OUTPUT with a URI, the intent you receive in onActivityResult() will be null. If you want to get image in this method, fetch image with the path you pass with EXTRA_OUTPUT.

  • This really works. I started facing crash issue on Android 7.0 and removing this line did the trick. Also removing this line didn't affect pre-nougat devices as well. Tested from Android 4.4 and above. – Andro Selva Aug 24 '17 at 07:40
  • @Jose Jithin bro u r awesome – Jeeva Aug 12 '19 at 13:55