0

UPDATE I don't find it similar to the subject of the post that they declared a duplicate. It's more I find it more similar to:

https://github.com/nguyenhoanglam/ImagePicker/issues/9

or

Camera is not working in Nougat 7.0

In any case, looking at those posts I couldn't find a solution to the problem. When I make the changes suggested in those links, and start working with a File Provider, the problem stops happening. But when I enable the permission to write to external storage, it happens again. If I don't enable this permission outputFileUri is null and never throws me error.


I've seen similar problems, but I haven't found a satisfactory result to the problem I'm facing, maybe I'm not pointing to the right point in the code. It works well with the previous API but not with API 24 (Android 7.0). I have tried various modifications of it but I always end up with the same problem. If someone could give me a hand where I should modify the code, I'd be grateful.

Logcat

E/AndroidRuntime: FATAL EXCEPTION: main
                  Process: com.example.admin.eventappb, PID: 2415
                  java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=65736, result=-1, data=Intent {  }} to activity {com.example.admin.eventappb/com.example.admin.eventappb.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object android.os.Bundle.get(java.lang.String)' on a null object reference
                      at android.app.ActivityThread.deliverResults(ActivityThread.java:4053)
                      at android.app.ActivityThread.handleSendResult(ActivityThread.java:4096)
                      at android.app.ActivityThread.-wrap20(ActivityThread.java)
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1516)
                      at android.os.Handler.dispatchMessage(Handler.java:102)
                      at android.os.Looper.loop(Looper.java:154)
                      at android.app.ActivityThread.main(ActivityThread.java:6077)
                      at java.lang.reflect.Method.invoke(Native Method)
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)
                   Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object android.os.Bundle.get(java.lang.String)' on a null object reference
                      at com.example.admin.eventappb.Dialog.DCreateEvent.onActivityResult(DCreateEvent.java:336)
                      at android.support.v4.app.FragmentActivity.onActivityResult(FragmentActivity.java:151)
                      at com.example.admin.eventappb.MainActivity.onActivityResult(MainActivity.java:367)
                      at android.app.Activity.dispatchActivityResult(Activity.java:6915)
                      at android.app.ActivityThread.deliverResults(ActivityThread.java:4049)
                      at android.app.ActivityThread.handleSendResult(ActivityThread.java:4096) 
                      at android.app.ActivityThread.-wrap20(ActivityThread.java) 
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1516) 
                      at android.os.Handler.dispatchMessage(Handler.java:102) 
                      at android.os.Looper.loop(Looper.java:154) 
                      at android.app.ActivityThread.main(ActivityThread.java:6077) 
                      at java.lang.reflect.Method.invoke(Native Method) 
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866) 
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756) 

Code:

public Intent getPickImageChooserIntent() {

        // Determine Uri of camera image to save.
        Uri outputFileUri = getCaptureImageOutputUri();

        List<Intent> allIntents = new ArrayList<>();
        PackageManager packageManager = getActivity().getPackageManager();

        // collect all camera intents
        Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
        List<ResolveInfo> listCam = packageManager.queryIntentActivities(captureIntent, 0);
        for (ResolveInfo res : listCam) {
            Intent intent = new Intent(captureIntent);
            intent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
            intent.setPackage(res.activityInfo.packageName);
            if (outputFileUri != null) {
                intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
            }
            allIntents.add(intent);
        }

        // collect all gallery intents
        Intent galleryIntent = new Intent(Intent.ACTION_GET_CONTENT);
        galleryIntent.setType("image/*");
        List<ResolveInfo> listGallery = packageManager.queryIntentActivities(galleryIntent, 0);
        for (ResolveInfo res : listGallery) {
            Intent intent = new Intent(galleryIntent);
            intent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
            intent.setPackage(res.activityInfo.packageName);
            allIntents.add(intent);
        }

        // the main intent is the last in the list (android) so pickup the useless one
        Intent mainIntent = allIntents.get(allIntents.size() - 1);
        for (Intent intent : allIntents) {
            if (intent.getComponent().getClassName().equals("com.android.documentsui.DocumentsActivity")) {
                mainIntent = intent;
                break;
            }
        }
        allIntents.remove(mainIntent);

        // Create a chooser from the main intent
        Intent chooserIntent = Intent.createChooser(mainIntent, "Select source");

        // Add all other intents
        chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, allIntents.toArray(new Parcelable[allIntents.size()]));

        return chooserIntent;
    }

    /**
     * Get URI to image received from capture by camera.
     */
    private Uri getCaptureImageOutputUri() {
        Uri outputFileUri = null;
        File getImage = getActivity().getExternalCacheDir();
        if (getImage != null) {
            outputFileUri = Uri.fromFile(new File(getImage.getPath(), "profile.png"));
        }
        return outputFileUri;
    }

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

        Bitmap bitmap;
        if (resultCode == Activity.RESULT_OK) {

            ImageView imageView =  v.findViewById(R.id.header_cover_image);

            if (getPickImageResultUri(data) != null) {
                picUri = getPickImageResultUri(data);

                try {
                    myBitmap = MediaStore.Images.Media.getBitmap(getActivity().getContentResolver(), picUri);
                    myBitmap = rotateImageIfRequired(myBitmap, picUri);
                    myBitmap = getResizedBitmap(myBitmap, 500);

                    CircleImageView croppedImageView = v.findViewById(R.id.user_profile_photo);
                    croppedImageView.setImageBitmap(myBitmap);
                    imageView.setImageBitmap(myBitmap);

                } catch (IOException e) {
                    e.printStackTrace();
                }


            } else {


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

                myBitmap = bitmap;
                CircleImageView croppedImageView = v.findViewById(R.id.user_profile_photo);
                if (croppedImageView != null) {
                    croppedImageView.setImageBitmap(myBitmap);
                }

                imageView.setImageBitmap(myBitmap);

            }

        }

    }

    public Uri getPickImageResultUri(Intent data) {
        boolean isCamera = true;
        if (data != null) {
            String action = data.getAction();
            isCamera = action != null && action.equals(MediaStore.ACTION_IMAGE_CAPTURE);
        }


        return isCamera ? getCaptureImageOutputUri() : data.getData();
    }

private static Bitmap rotateImageIfRequired(Bitmap img, Uri selectedImage) throws IOException {

        ExifInterface ei = new ExifInterface(selectedImage.getPath());
        int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);

        switch (orientation) {
            case ExifInterface.ORIENTATION_ROTATE_90:
                return rotateImage(img, 90);
            case ExifInterface.ORIENTATION_ROTATE_180:
                return rotateImage(img, 180);
            case ExifInterface.ORIENTATION_ROTATE_270:
                return rotateImage(img, 270);
            default:
                return img;
        }
    }

    private static Bitmap rotateImage(Bitmap img, int degree) {
        Matrix matrix = new Matrix();
        matrix.postRotate(degree);
        Bitmap rotatedImg = Bitmap.createBitmap(img, 0, 0, img.getWidth(), img.getHeight(), matrix, true);
        img.recycle();
        return rotatedImg;
    }

    public Bitmap getResizedBitmap(Bitmap image, int maxSize) {
        int width = image.getWidth();
        int height = image.getHeight();

        float bitmapRatio = (float) width / (float) height;
        if (bitmapRatio > 0) {
            width = maxSize;
            height = (int) (width / bitmapRatio);
        } else {
            height = maxSize;
            width = (int) (height * bitmapRatio);
        }
        return Bitmap.createScaledBitmap(image, width, height, true);
    }

@Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);

        // save file url in bundle as it will be null on scren orientation
        // changes
        outState.putParcelable("pic_uri", picUri);
    }
Javier Coronel
  • 133
  • 4
  • 12
  • So you have a `NullPointerException`. On line 367 according your logcat. – greenapps Dec 25 '17 at 23:10
  • Yes, on the method onAcivityResult in this line : bitmap = (Bitmap) data.getExtras().get("data"); I think that is because of this: data=Intent { } – Javier Coronel Dec 25 '17 at 23:38
  • In the previous API it works just fine, but API 24 forward this happens – Javier Coronel Dec 25 '17 at 23:40
  • Well what is null there? – greenapps Dec 26 '17 at 00:13
  • I think that the intent come backs null, dont know how to fix it. – Javier Coronel Dec 26 '17 at 11:54
  • I bet the platform version is not the problem here. This is simply a different device with different Camera app, different set of background services, etc. The root cause is that the OS decides that it is tight on memory, so it shuts down your app while the Camera is busy. See https://stackoverflow.com/a/5280053/192373 and a detailed [tutorial](https://www.androidhive.info/2013/09/android-working-with-camera-api/) (scroll to section *Avoiding NullPointerException after taking camera picture*) – Alex Cohn Dec 26 '17 at 16:37
  • ok, thank you very much for the explination. I will check that out. – Javier Coronel Dec 26 '17 at 18:01
  • @AlexCohn i was checking the tutorial, and i am working with a fragment so i dont have a onRestoreInstanceState so the problem should not come from there. And i already have a onSaveInstanceState. I will add that to the code above. – Javier Coronel Dec 26 '17 at 21:43
  • When i start to work with a FileProvider the problem goes away but when i give permission to write in the external storage it returns – Javier Coronel Dec 26 '17 at 22:39
  • Sorry for misleading you. `data.getExtras().get("data")` is a different kind of a NPE, not related to memory. But the [*duplicate* link](https://stackoverflow.com/questions/5279809/) is correct. Please check the answer at https://stackoverflow.com/a/5829936/192373. – Alex Cohn Dec 28 '17 at 11:50
  • The bottom line is, the camera will let you to `get("data")` only if you don't set `MediaStore.EXTRA_OUTPUT` (see also https://stackoverflow.com/a/18420862/192373). I agree that this subtle detail is not very clear from the [official documantation](https://developer.android.com/training/camera/photobasics.html#TaskPath). See the offical doc for [MediaStore.ACTION_IMAGE_CAPTURE](https://developer.android.com/reference/android/provider/MediaStore.html#ACTION_IMAGE_CAPTURE): *If the EXTRA_OUTPUT is not present, then a small sized image is returned as a Bitmap object in the extra field* – Alex Cohn Dec 28 '17 at 12:00
  • Finally, to clarify your experience: a image capture Intent is fulfilled by a Camera app that is currently chosen on the device. Each vendor preinstalls a different app on their device, and the end user is free to install and use a third-party app. Level of compliance of these apps with the official contract for MediaStore.ACTION_IMAGE_CAPTURE may vary. Some app could decide to return the thumbnail data even when you set preferred image location. This is not directly related to the platform version. – Alex Cohn Dec 28 '17 at 12:08

0 Answers0