-1

I'm trying to crop image as soon as camera activity finishes. But onActivityResult but data.getData(); gets null value. I have declared onSaveInstanceState and onRestoreInstanceState. Here is my MainActivity.java file

package com.example.sathwik.uploadtrail1;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import com.yalantis.ucrop.UCrop;

public class MainActivity extends AppCompatActivity {
    // LogCat tag
    private static final String TAG = MainActivity.class.getSimpleName();
    // Camera activity request codes
    private static final int CAMERA_CAPTURE_IMAGE_REQUEST_CODE = 100;
    private static final int CAMERA_CAPTURE_VIDEO_REQUEST_CODE = 200;
    public static final int MEDIA_TYPE_IMAGE = 1;
    public static final int MEDIA_TYPE_VIDEO = 2;
   // public static final int REQUEST_CROP = UCrop.REQUEST_CROP;

    private Uri fileUri; // file url to store image/video
   // private Uri fileUriCrop;
    private Button btnCapturePicture, btnRecordVideo;

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

        // Changing action bar background color

        //getActionBar().setBackgroundDrawable(new ColorDrawable(Color.parseColor(getResources().getString(R.color.action_bar))));
        btnCapturePicture = (Button) findViewById(R.id.btnCapturePicture);
        btnRecordVideo = (Button) findViewById(R.id.btnRecordVideo);

        /**
        * Capture image button click event
        */
        btnCapturePicture.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            captureImage();
         }
        });
        /**
          Record video button click event
         */
        btnRecordVideo.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            // record video
            recordVideo();
            }
            });
        // Checking camera availability
        if (!isDeviceSupportCamera()) {
        Toast.makeText(getApplicationContext(),
        "Sorry! Your device doesn't support camera",
        Toast.LENGTH_LONG).show();
        // will close the app if the device does't have camera
        finish();
        }
        }
    /**
      checking device has camera hardware or not
       */
    private boolean isDeviceSupportCamera() {
    if (getApplicationContext().getPackageManager().hasSystemFeature(
    PackageManager.FEATURE_CAMERA)) {
    // this device has a camera
    return true;
    } else {
    // no camera on this device
    return false;
    }
    }
    /**
          * Launching camera app to capture image
          */
    private void captureImage() {
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
        // start the image capture Intent
        startActivityForResult(intent, CAMERA_CAPTURE_IMAGE_REQUEST_CODE);

    }


    /**
          * Launching camera app to record video
          */
    private void recordVideo() {
        Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
        fileUri = getOutputMediaFileUri(MEDIA_TYPE_VIDEO);
        // set video quality
        intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);// set the image file
        // name
        // start the video capture Intent
        startActivityForResult(intent, CAMERA_CAPTURE_VIDEO_REQUEST_CODE);
    }

   /* *//** Perform UCrop *//*
    public void performUcrop(){
        UCrop.of(fileUri, fileUri).start(this);

    }*/
    private void performcrop(){
        UCrop.of(fileUri, fileUri).start(this);
    }


    /**
              * Here we store the file url as it will be null after returning from camera
              * app
              */
        @Override
        protected void onSaveInstanceState(Bundle outState) {
            super.onSaveInstanceState(outState);
            // save file url in bundle as it will be null on screen orientation
            // changes
            outState.putParcelable("file_uri", fileUri);
        }
        @Override
        protected void onRestoreInstanceState (@NonNull Bundle savedInstanceState){
            super.onRestoreInstanceState(savedInstanceState);
            // get the file url
            fileUri = savedInstanceState.getParcelable("file_uri");
        }
        /**
              * Receiving activity result method will be called after closing the camera
              * */
        @Override
        protected void onActivityResult ( int requestCode, int resultCode, Intent data){
            // if the result is capturing Image
            if (requestCode == CAMERA_CAPTURE_IMAGE_REQUEST_CODE) {
                if (resultCode == RESULT_OK ) {
                    // successfully captured the image
                    //Log.d("ucrop", "error log" + fileUri);
                   // performUcrop();
                    //final Uri fileUri = UCrop.getOutput(data);
                    fileUri = data.getData();
                    performcrop();
                    // launching upload activity
                    launchUploadActivity(true);
                } else if (resultCode == RESULT_CANCELED) {
                    // user cancelled Image capture
                    Toast.makeText(getApplicationContext(),
                            "Sorry! Failed to capture image", Toast.LENGTH_SHORT).show();
                }
            } else if (requestCode == CAMERA_CAPTURE_VIDEO_REQUEST_CODE) {
                if (resultCode == RESULT_OK) {
                    // video successfully recorded
                    //launching upload activity
                    launchUploadActivity(false);
                } else if (resultCode == RESULT_CANCELED) {
                    // user cancelled recording
                    Toast.makeText(getApplicationContext(), "Sorry! Failed to record video", Toast.LENGTH_SHORT).show();
                }
            }
        }
    private void launchUploadActivity(boolean isImage){
        Intent i = new Intent(MainActivity.this, UploadActivity.class);
        i.putExtra("filePath", fileUri.getPath());
        i.putExtra("isImage", isImage);
        startActivity(i);
    }

    /**
          * Creating file uri to store image/video
          */
    public Uri getOutputMediaFileUri(int type) {
    return Uri.fromFile(getOutputMediaFile(type));
    }

    /**
          * returning image / video
          */
    private static File getOutputMediaFile(int type) {

        // External sdcard location
        File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
                Config.IMAGE_DIRECTORY_NAME);

        // Create the storage directory if it does not exist
        if (!mediaStorageDir.exists()) {
            if (!mediaStorageDir.mkdirs()) {
                Log.d(TAG, "Oops! Failed create "+ Config.IMAGE_DIRECTORY_NAME + " directory");
                return null;
            }
        }
        // Create a media file name
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss",Locale.getDefault()).format(new Date());
        File mediaFile;
        if (type == MEDIA_TYPE_IMAGE) {
            mediaFile = new File(mediaStorageDir.getPath() + File.separator+ "IMG_" + timeStamp + ".jpg");
        } else if (type == MEDIA_TYPE_VIDEO) {
            mediaFile = new File(mediaStorageDir.getPath() + File.separator+ "VID_" + timeStamp + ".mp4");
        } else {
            return null;
        }
        return mediaFile;
    }

    //Logout function
    private void logout(){
        //Creating an alert dialog to confirm logout
        android.support.v7.app.AlertDialog.Builder alertDialogBuilder = new android.support.v7.app.AlertDialog.Builder(this);
        alertDialogBuilder.setMessage("Are you sure you want to logout?");
        alertDialogBuilder.setPositiveButton("Yes",
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface arg0, int arg1) {

                        //Getting out sharedpreferences
                        SharedPreferences preferences = getSharedPreferences(Config.SHARED_PREF_NAME, Context.MODE_PRIVATE);
                        //Getting editor
                        SharedPreferences.Editor editor = preferences.edit();

                        //Puting the value false for loggedin
                        editor.putBoolean(Config.LOGGEDIN_SHARED_PREF, false);

                        //Putting blank value to email
                        editor.putString(Config.EMAIL_SHARED_PREF, "");

                        //Saving the sharedpreferences
                        editor.commit();

                        //Starting login activity
                        Intent intent = new Intent(MainActivity.this, LoginActivity.class);
                        startActivity(intent);
                    }
                });

        alertDialogBuilder.setNegativeButton("No",
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface arg0, int arg1) {

                    }
                });

        //Showing the alert dialog
        android.support.v7.app.AlertDialog alertDialog = alertDialogBuilder.create();
        alertDialog.show();

    }

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

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.menuLogout) {
            logout();
        }
        return super.onOptionsItemSelected(item);
    }

}

This is my error log

07-02 19:09:13.093 20749-20749/com.example.sathwik.uploadtrail1 E/AndroidRuntime: FATAL EXCEPTION: main
                                                                                  Process: com.example.sathwik.uploadtrail1, PID: 20749
                                                                                  java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=100, result=-1, data=null} to activity {com.example.sathwik.uploadtrail1/com.example.sathwik.uploadtrail1.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.net.Uri android.content.Intent.getData()' on a null object reference
                                                                                      at android.app.ActivityThread.deliverResults(ActivityThread.java:3574)
                                                                                      at android.app.ActivityThread.handleSendResult(ActivityThread.java:3617)
                                                                                      at android.app.ActivityThread.access$1300(ActivityThread.java:151)
                                                                                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1352)
                                                                                      at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                                      at android.os.Looper.loop(Looper.java:135)
                                                                                      at android.app.ActivityThread.main(ActivityThread.java:5254)
                                                                                      at java.lang.reflect.Method.invoke(Native Method)
                                                                                      at java.lang.reflect.Method.invoke(Method.java:372)
                                                                                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
                                                                                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
                                                                                   Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.net.Uri android.content.Intent.getData()' on a null object reference
                                                                                      at com.example.sathwik.uploadtrail1.MainActivity.onActivityResult(MainActivity.java:166)
                                                                                      at android.app.Activity.dispatchActivityResult(Activity.java:6192)
                                                                                      at android.app.ActivityThread.deliverResults(ActivityThread.java:3570)
                                                                                      at android.app.ActivityThread.handleSendResult(ActivityThread.java:3617) 
                                                                                      at android.app.ActivityThread.access$1300(ActivityThread.java:151) 
                                                                                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1352) 
                                                                                      at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                                                      at android.os.Looper.loop(Looper.java:135) 
                                                                                      at android.app.ActivityThread.main(ActivityThread.java:5254) 
                                                                                      at java.lang.reflect.Method.invoke(Native Method) 
                                                                                      at java.lang.reflect.Method.invoke(Method.java:372) 
                                                                                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903) 
                                                                                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698) 
Phantômaxx
  • 37,901
  • 21
  • 84
  • 115

1 Answers1

1

Remove this line:

fileUri = data.getData();

The fileUri already contains the image location you captured. Use data.getData() when you picking image from gallery, not when you capturing it using camera.

Change onActivityResults function to something like this:

@Override
    protected void onActivityResult ( int requestCode, int resultCode, Intent data){
        // if the result is capturing Image
        if (requestCode == CAMERA_CAPTURE_IMAGE_REQUEST_CODE) {
            if (resultCode == RESULT_OK ) {
                // successfully captured the image
                //Log.d("ucrop", "error log" + fileUri);
                // performUcrop();
                //final Uri fileUri = UCrop.getOutput(data);
                performcrop();
            } else if (resultCode == RESULT_CANCELED) {
                // user cancelled Image capture
                Toast.makeText(getApplicationContext(),
                        "Sorry! Failed to capture image", Toast.LENGTH_SHORT).show();
            }
        } else if (requestCode == CAMERA_CAPTURE_VIDEO_REQUEST_CODE) {
            if (resultCode == RESULT_OK) {
                // video successfully recorded
                //launching upload activity
                launchUploadActivity(false);
            } else if (resultCode == RESULT_CANCELED) {
                // user cancelled recording
                Toast.makeText(getApplicationContext(), "Sorry! Failed to record video", Toast.LENGTH_SHORT).show();
            }
        }
        else if (requestCode == UCrop.REQUEST_CROP) {
            if(resultCode == RESULT_OK) {
                fileUri=UCrop.getOutput(data);
                launchUploadActivity(true);
            }
            else if(resultCode == UCrop.RESULT_ERROR) {

            }
        }
    }
Alex
  • 9,102
  • 3
  • 31
  • 35
  • If I do that performcrop(); function gets skipped. I cannot call that function. Don't know why. – Sathwik Gangisetty Jul 02 '17 at 12:39
  • I don't know what performcrop(); should do, but next line is starting other activity, so you should move starting activity to other place, after performcrop(); is finished – Alex Jul 02 '17 at 12:43
  • After looking into uCrop library, you should add another state to onActivityResults: if (resultCode == RESULT_OK && requestCode == UCrop.REQUEST_CROP) { final Uri resultUri = UCrop.getOutput(data); //Start your activity here after the cropping } else if (resultCode == UCrop.RESULT_ERROR) { final Throwable cropError = UCrop.getError(data); } – Alex Jul 02 '17 at 12:46
  • See the updated answer – Alex Jul 02 '17 at 12:56