2

This same code runs like a charm in other devices but in nexus 5 (OS version 5.1.1) am unable to run it.

When I run the below code in nexus 5 I get NullPointerException, and value of resultCode=0 and that of RESULT_OK=-1, thus my if condition in getActivityForResult do not run.

Whereas in other devices (other models like samsung,htc etc) the same code runs like a charm without and exception and the value of resultCode=-1 and RESULT_OK=-1, both the values come same , so the if condition runs and thus the rest of my program.

JAVA CODE mainActivity.java

public void callCamera() {

    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);

    // start the image capture Intent
    startActivityForResult(intent, 100);
    Log.i("hello", "callCamera");
}

 protected void onActivityResult(int requestCode, int resultCode, Intent data) {

        Log.i("hello", "" + requestCode);
        Log.i("hello", "" + resultCode);
        Log.i("hello", "" + this.RESULT_OK);


    if (requestCode == 100 && resultCode == RESULT_OK) {
        // fileUri=data.getExtras().get("data");
        photo = (Bitmap) data.getExtras().get("data");

        //*selectedImage = data.getData();
        //photo = (Bitmap) data.getExtras().get("data");
        Log.i("hello","onActivityResult");
        uploadImage();
    }
}

LOGCAT IN CASE OF NEXUS 5

FATAL EXCEPTION: main Process: com.google.android.GoogleCamera, PID: 24887 

java.lang.NullPointerException at com.google.common.base.Preconditions.checkNotNull(Preconditions.java:187)
at com.google.common.base.Optional.of(Optional.java:84)
at com.android.camera.captureintent.state.StateSavingPicture.onEnter(StateSavingPicture.java:77) 
at  com.android.camera.captureintent.stateful.StateMachineImpl.jumpToState(StateMachineImpl.java:62)
at com.android.camera.captureintent.stateful.StateMachineImpl.processEvent(StateMachineImpl.java:110)
at com.android.camera.captureintent.state.StateOpeningCamera$9.onClick(StateOpeningCamera.java:307)
at android.view.View.performClick(View.java:4780)
at android.view.View$PerformClick.run(View.java:19866)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
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)
Cœur
  • 37,241
  • 25
  • 195
  • 267
Bawa
  • 876
  • 10
  • 28

4 Answers4

1

Remove the intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); line from callCamera() method, this will fix the crash. As if you are getting the uri from the onActivityResult() intent then the intent will recived data as null since you are putting a extra value of uri in the intent at time of starting the camera intent, this defines that you already have a file uri for your camera image and you don't want a data intent in onActivityResult(), also i will suggest you to remove the fileuri variable used inside the callCamera() method as it is of no use.

so your callCamera method should look like:

public void callCamera() {

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, 100);
}
HAXM
  • 3,578
  • 4
  • 31
  • 38
  • This was my issue also, but it was harder for me to figure it out because I was adding an extra (It doesn't matter what extra) in my BaseActivity class and this was causing the issue. – YYamil Jun 22 '16 at 14:32
  • @YYamil, if you add any extra to camera intent, then it obvious, that you are informing the intent that you already have that value, for eg, putExtra(MediaStore.xyz, uri), it means you already defining a path to save the image and passed it to the intent, now the camera activity will get the value of uri and save the image to your defined position, and will not return any uri as the camera intent think you already have that value(Therefore you recive a null in Intent Data). – HAXM Jun 23 '16 at 04:39
  • The problem is: how do you get the actual filename of the picture in that case? – CpnCrunch Mar 23 '21 at 19:49
  • @CpnCrunch, fileUri needs to be declared as global variable or you can initialise it inside the callCamera(){ } function, so in onActivityResult you can access the fileUri variable. Check the last code snippet of this answer https://stackoverflow.com/a/36512846/4961126 , where a similar method is there to open the camera. – HAXM Mar 24 '21 at 03:42
  • But that sets the filename using intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri) which is what is causing the crash, and you just said in your answer here that it should be removed. If you remove it, you won't know the filename. – CpnCrunch Mar 24 '21 at 14:56
  • the cause of crash is you are trying to access the intent inside onActivityResult(Intent intent), Don't use the intent inside the onActivityResult(). – HAXM Mar 25 '21 at 03:28
  • @HAXM: it's not crashing in onActivityResult. If I put a breakpoint right at the beginning of my onActivityResult I see the exception has already happened. Removing the intent.putExtra is the only thing that fixes it (as per your answer), but I don't see how to get the filename in that case. The code snippet you referred to doesn't actually get the filename, it just stuffs the thumbnail (from data.getExtras().get("data")) into a bitmap and saves it. I don't want the thumbnail, I need the full picture. – CpnCrunch Mar 25 '21 at 16:08
  • in onActivityResult you can use : Uri imageUri = intent.getData(); try { InputStream ims = getContentResolver().openInputStream(imageUri); imageView.setImageBitmap(BitmapFactory.decodeStream(ims)); } catch (FileNotFoundException e) { e.printStackTrace(); } – HAXM Mar 25 '21 at 17:16
  • @HAXM: no, that doesn't work because getData() returns null when grabbing from the camera (and has always done so). It only ever returns data when picking from the gallery. Have you actually solved this problem? – CpnCrunch Mar 29 '21 at 02:24
  • I found the problem is you need to use FileProvider. I've added the correct answer. – CpnCrunch Mar 29 '21 at 18:14
-1
/*** Created by wildcoder on 06/06/16.*/
import android.Manifest;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.Intent;
import android.media.CameraProfile;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.widget.Toast;
public class FragmentVideoRecorder extends BaseFragment {

private Uri fileUri;
private static final int CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE = 200;
public static Activity ActivityContext = null;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ActivityContext = getActivity();
}


/**
 * @param parentDirectory Your folder name
 */
protected void startRecording(File parentDirectory) {
    if (Utilities.isGranted(getActivity(), Manifest.permission.RECORD_AUDIO) && Utilities.isGranted(getActivity(), Manifest.permission.CAMERA)) {
        Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
        // create a file to save the video
        fileUri = getOutputMediaFileUri(parentDirectory);
        // set the image file name
        intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
        intent.putExtra(MediaStore.EXTRA_SIZE_LIMIT, 10000000);
        // set the video image quality to high
        intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, CameraProfile.QUALITY_LOW);
        // start the Video Capture Intent
        startActivityForResult(intent, CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE);
    } else {
        Utilities.openAppSetting(ActivityContext);
    }

}


/**
 * @param contentResolver
 * @param file            to delete
 */
public void deleteFileFromMediaStore(final ContentResolver contentResolver, final File file) {
    String canonicalPath;
    try {
        canonicalPath = file.getCanonicalPath();
    } catch (IOException e) {
        canonicalPath = file.getAbsolutePath();
    }
    final Uri uri = MediaStore.Files.getContentUri("external");
    final int result = contentResolver.delete(uri,
            MediaStore.Files.FileColumns.DATA + "=?", new String[]{canonicalPath});
    if (result == 0) {
        final String absolutePath = file.getAbsolutePath();
        if (!absolutePath.equals(canonicalPath)) {
            contentResolver.delete(uri,
                    MediaStore.Files.FileColumns.DATA + "=?", new String[]{absolutePath});
        }
    }
}

/**
 * Create a file Uri for saving an image or video
 */
private Uri getOutputMediaFileUri(File parent) {
    return Uri.fromFile(getOutputMediaFile(parent));
}

/**
 * Create a File for saving an image or video
 */
private File getOutputMediaFile(File mediaStorageDir) {
    // Check that the SDCard is mounted
    // Create the storage directory(MyCameraVideo) if it does not exist
    if (!mediaStorageDir.exists()) {
        if (!mediaStorageDir.mkdirs()) {
            Toast.makeText(ActivityContext, "Failed to create directory MyCameraVideo.",
                    Toast.LENGTH_LONG).show();
            Log.d("MyCameraVideo", "Failed to create directory MyCameraVideo.");
            return null;
        }
    }
    File mediaFile = new File(mediaStorageDir, "intro_video.mp4");
    if (mediaFile.exists()) {
        deleteFileFromMediaStore(ActivityContext.getContentResolver(), mediaFile);
    }
    return mediaFile;
}


@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    // After camera screen this code will excuted
    if (requestCode == CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE) {
        if (resultCode == Activity.RESULT_OK) {
            // Video captured and saved to fileUri specified in the Intent
            Toast.makeText(ActivityContext, "Video saved to: " + data.getData(), Toast.LENGTH_LONG).show();

        } else if (resultCode == Activity.RESULT_CANCELED) {

            // User cancelled the video capture
            Toast.makeText(ActivityContext, "User cancelled the video capture.",
                    Toast.LENGTH_LONG).show();

        } else {
            // Video capture failed, advise user
            Toast.makeText(ActivityContext, "Video capture failed.",
                    Toast.LENGTH_LONG).show();
        }
    }
}

}

Anuj J Pandey
  • 656
  • 1
  • 4
  • 17
-1

Make sure that after the video is captured you click on the tick mark (blue in Nexus 5, Android 8). It is only after the tick that the result is set to RESULT_OK. If you click on any other button, the result code is not set appropriately.

G..
  • 1
  • 1
-1

The problem is that Android 11 requires that you use Fileprovider. Solution:

[1] Make sure you use FileProvider to generate fileUri, e.g.:

File outputDir = getExternalCacheDir();
File out = File.createTempFile("android_upload", ".jpg", outputDir);
fileUri = FileProvider.getUriForFile(this, "com.your.app.id.fileprovider", out);

(replace com.your.app.id with your application id).

[2] Add to your AndroidManifest.xml:

 <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="com.your.app.id.fileprovider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_provider_paths"/>
 </provider>

[3] Create a file res/xml/file_provider_paths.xml:

<paths>
    <external-cache-path name="cache" path="/" />
</paths>
CpnCrunch
  • 4,831
  • 1
  • 33
  • 31