Sathwik Gangisetty Sathwik Gangisetty - 1 month ago 7
Java Question

FileUri shows null after camera capture even after onsaveInstanceState and onRestoreInstanceState

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) 

Answer Source

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) {

            }
        }
    }