Search code examples
javaandroidfirebasefirebaseui

NullPointerException on intent when accessing Camera Android


I am trying to call the Camera app twice as described here: https://developer.android.com/training/camera/photobasics Now when I was using this without creating a temp file this worked and I was able to call the camera twice but after adding the temp file I am only able to take one file before crashing. it is very frustrating because I can see that it is returning a full size image before crashing.

I have tried doing a second .putExtras() before the get but that is not working. I have also tried assert not null, same results.

private void takePictureAndUpload() {
        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
            // Create the File where the photo should go
            File photoFile = null;
            try {
                photoFile = createImageFile();
            } catch (IOException ex) {
                // Error occurred while creating the File

            }
            // Continue only if the File was successfully created
            if (photoFile != null) {
                Uri photoURI = FileProvider.getUriForFile(this,
                        "com.example.android.provider",
                        photoFile);
                startActivityForResult(takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI)
                        , REQUEST_IMAGE_CAPTURE);
            }
        }


    }

    protected void onActivityResult(int requestCode, int resultCode, Intent data){
        super.onActivityResult(requestCode, resultCode, data);
        if ((requestCode == REQUEST_IMAGE_CAPTURE) && (resultCode == Activity.RESULT_OK)){
            count++;
            Bundle extras = data.getExtras();
            Bitmap imageBitmap = (Bitmap) extras.get("data");
            ByteArrayOutputStream stream = new ByteArrayOutputStream();
            assert imageBitmap != null;
            imageBitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
            final byte[] imageData = stream.toByteArray();

            setuId(user);
            final String path = "posts/" + UUID.randomUUID() + ".jpg";

            FirebaseStorage storage = FirebaseStorage.getInstance();
            final StorageReference storageRef = storage.getReference();
            final StorageReference imageRef = storageRef.child(path);


            UploadTask uploadTask = imageRef.putBytes(imageData);
            uploadTask.addOnFailureListener(new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception e) {
                    String ex = e.getLocalizedMessage();
                }
            }).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
                @Override
                public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                    imageRef.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>()
                    {
                        @Override
                        public void onSuccess(Uri downloadUrl)
                        {
                            final String url = downloadUrl.toString();//do something with downloadurl
                            data.putExtra(MediaStore.EXTRA_OUTPUT, url);
                            addPhotoUrlToDatabase(post.getImageUrl_1(), post.getImageUrl_2(), path);

                        }
                    });
                }
            });
        }
    }

    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 = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
        File image = File.createTempFile(
                imageFileName,  /* prefix */
                ".jpg",         /* suffix */
                storageDir      /* directory */
        );

        // Save a file: path for use with ACTION_VIEW intents
        currentPhotoPath = image.getAbsolutePath();
        return image;
    }

This should open the camera take a picture then after accepting the first picture it should reopen camera for a second picture. However so far all it does is open camera, take a picture then when I hit accept it crashes with a nullPointerException.

LogCat:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.android, PID: 21689
    java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1, result=-1, data=null} to activity {com.example.android/com.example.android.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.os.Bundle android.content.Intent.getExtras()' on a null object reference
        at android.app.ActivityThread.deliverResults(ActivityThread.java:4491)
        at android.app.ActivityThread.handleSendResult(ActivityThread.java:4534)
        at android.app.ActivityThread.-wrap20(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1752)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6944)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
     Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.os.Bundle android.content.Intent.getExtras()' on a null object reference
        at com.example.android.MainActivity.onActivityResult(MainActivity.java:257)
        at android.app.Activity.dispatchActivityResult(Activity.java:7547)
        at android.app.ActivityThread.deliverResults(ActivityThread.java:4487)

Edit

This is the guide that I am following: https://developer.android.com/training/camera/photobasics.html#TaskPath


Solution

  • Found an answer here:https://stackoverflow.com/a/37628687/10941659. It is not made clear on the android developer training site, but when you want to get a full size image you don't use the intent that you pass to onActivityResult. You need to use the path that you generate for your image, for example:

    private void takePictureAndUpload() {
            Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
                // Create the File where the photo should go
                File photoFile = null;
                try {
                    photoFile = createImageFile();
                } catch (IOException ex) {
                    // Error occurred while creating the File
                }
                // Continue only if the File was successfully created
                if (photoFile != null) {
                    photoURI = FileProvider.getUriForFile(this,
                            "com.example.android.provider",
                            photoFile);
                    takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
                    startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
                }
            }
    
    
        }
    
        protected void onActivityResult(int requestCode, int resultCode, final Intent data){
            super.onActivityResult(requestCode, resultCode, data);
            if ((requestCode == REQUEST_IMAGE_CAPTURE) && (resultCode == Activity.RESULT_OK)){
                count++;
                Bitmap imageBitmap = null;
                try {
                    imageBitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(),photoURI);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                ByteArrayOutputStream stream = new ByteArrayOutputStream();
                imageBitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
                final byte[] imageData = stream.toByteArray();
    
                setuId(user);
                final String path = "posts/" + UUID.randomUUID() + ".jpg";
    
                FirebaseStorage storage = FirebaseStorage.getInstance();
                final StorageReference storageRef = storage.getReference();
                final StorageReference imageRef = storageRef.child(path);
    
                UploadTask uploadTask = imageRef.putBytes(imageData);
                uploadTask.addOnFailureListener(new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception e) {
                        String ex = e.getLocalizedMessage();
                    }
                }).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
                    @Override
                    public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                        imageRef.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>()
                        {
                            @Override
                            public void onSuccess(Uri downloadUrl)
                            {
                                final String url = downloadUrl.toString();//do something with downloadurl
                                 addPhotoUrlToDatabase(post.getImageUrl_1(), post.getImageUrl_2(), path);
                            }
                        });
                    }
                });
            }
        }