jublikon
jublikon

Reputation: 3437

Android default camera crashes

I am using the systems default camera to take a picture and save the image to the SD card.

The app is working excellent on a Nexus 5 with Android 6.0. But on a Samsung Galaxy S4 with Android 5.0.1 the app crashes when I press 'save' with the issue:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.jublikon.example/com.jublikon.example.ReviewMaschine.ReviewActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.Integer.intValue()' on a null object reference

Why does the camera Activity try to start another Activity? It should just save the image and finish() itself.

my capture image method looks like that:

 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);
    }

The fileUri generated by code:

file:///storage/emulated/0/Pictures/ImageDokumentation/IMG_20151214_214131.jpg

I have noticed that the app saves the images on the Samsung Galaxy S4 locally and not on SD card. Perhaps this is the mistake I am doing? I have realized that sometimes pictures are saved and sometimes not. The app stops in each case.

The app crashes without running into onActivityResult.

I really do not understand what I am doing wrong. The app works on the physical Nexus device without any problem.

EDIT: Because it seems to be a more complex problem, here the fragment's shortened code:

public class FragmentReview extends Fragment {

    // some initialization (...)

    private static final int CAMERA_CAPTURE_IMAGE_REQUEST_CODE = 100;
    public static final int MEDIA_TYPE_IMAGE = 1;

    private static final String IMAGE_DIRECTORY_NAME = "ImageDokumentation";

    private Uri fileUri; // file url to store image/video

    // Permission Strings
    private  static final String PERMISSION_HARDWARE_CAMERA = "android.permission.CAMERA";
    private  static final String PERMISSION_WRITE_EXTERNAL_STORAGE = "android.permission.WRITE_EXTERNAL_STORAGE";

    private static final String IMAGE_URI_BUNDLE = "fileUri";

    public FragmentReview() {

    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        //Adding some data

        setRetainInstance(true);

    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putParcelable(IMAGE_URI_BUNDLE, fileUri);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        List<ReviewItem> currentData = mAdapter.getCurrentData();

        DatabaseHandler db = new DatabaseHandler(getActivity());
        Maschine updateMaschine = new Maschine();
        updateMaschine = db.getMaschineForKeyMaschineAndAnlage(getIdForSelectedAnlage(), getIdForSelectedMaschine());

        switch (item.getItemId()) {
            case R.id.action_save:

               //saving some data 

                return true;
            case R.id.action_photo:

                if (isDeviceSupportCamera()) {

                    boolean checkcamera = hasPermission(PERMISSION_HARDWARE_CAMERA);
                    boolean checkstorage = hasPermission(PERMISSION_WRITE_EXTERNAL_STORAGE);

                    if(hasPermission(PERMISSION_HARDWARE_CAMERA) == true && hasPermission(PERMISSION_WRITE_EXTERNAL_STORAGE)){

                        try {
                            captureImage();
                        } catch (Exception e) {
                            new MaterialDialog.Builder(getActivity())
                                    .title("Berechtigungen nicht aktiviert")
                                    .content("Bitte lassen Sie in den Einstellungen die notwendigen Berechtigungen zu")
                                    .positiveText("OK")
                                    .show();
                        }

                    } else {
                        new MaterialDialog.Builder(getActivity())
                                .title("Berechtigungen nicht aktiviert")
                                .content("Bitte lassen Sie in den Einstellungen die notwendigen Berechtigungen zu")
                                .positiveText("OK")
                                .show();
                    }

                } else {
                    new MaterialDialog.Builder(getActivity())
                            .title("Fehler")
                            .content("Kamera konnte nicht geöffnet werden")
                            .positiveText("OK")
                            .show();
                }

                return false;

            case R.id.action_gallery:

               // starting gallery activity

                return true;
            default:
                break;
        }
        return false;
    }

    private boolean isDeviceSupportCamera() {
        if (getActivity().getPackageManager().hasSystemFeature(
                PackageManager.FEATURE_CAMERA)) {
            // this device has a camera
            return true;
        } else {
            // no camera on this device
            return false;
        }

    }

    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);
    }

    public Uri getOutputMediaFileUri(int type) {
        return Uri.fromFile(getOutputMediaFile(type));
    }

    private static File getOutputMediaFile(int type) {
        File mediaStorageDir = new File(       Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + File.separator + IMAGE_DIRECTORY_NAME);

        // Create the storage directory if it does not exist
        if (!mediaStorageDir.exists()) {
            mediaStorageDir.mkdirs();

            if (!mediaStorageDir.mkdirs()) {
                Log.d(IMAGE_DIRECTORY_NAME, "Fehler beim Erstellen der Datei: "
                        + 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 {
            return null;
        }

        return mediaFile;
    }

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

        try{

            // if the result is capturing Image
            if (requestCode == CAMERA_CAPTURE_IMAGE_REQUEST_CODE) {
                if (resultCode == Activity.RESULT_OK) {


                    DatabaseHandler db = new DatabaseHandler(getActivity());


                    db.addImage(getIdForSelectedAnlage(), getIdForSelectedMaschine(), fileUri.toString());

                    Toast.makeText(getActivity(),
                            "Bild wurde gespeichert" + fileUri.toString(), Toast.LENGTH_SHORT)
                            .show();

                    //previewCapturedImage();
                } else if (resultCode == Activity.RESULT_CANCELED) {
                    // user cancelled Image capture
                /* Toast.makeText(getActivity(),
                        "User cancelled image capture", Toast.LENGTH_SHORT)
                        .show(); */
                } else {
                    // failed to capture image
                /* Toast.makeText(getActivity(),
                        "Sorry! Failed to capture image", Toast.LENGTH_SHORT)
                        .show(); */
                }
            }

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

            Toast.makeText(getActivity(),
                    "Datei konnte nicht in Datenbank gespeichert werden", Toast.LENGTH_SHORT)
                    .show();
        }


    }

    public boolean hasPermission(String permission)
    {
        try {
            PackageInfo info = getActivity().getPackageManager().getPackageInfo(getActivity().getPackageName(), PackageManager.GET_PERMISSIONS);
            if (info.requestedPermissions != null) {
                for (String p : info.requestedPermissions) {
                    if (p.equals(permission)) {
                        return true;
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }
}

Upvotes: 1

Views: 1880

Answers (3)

northerngirl
northerngirl

Reputation: 225

I have faced with this problem. Samsung Galaxy S4 with os 5.0.1 has specific issue, when camera stream is open, screen orientation is changed several times,and our activity is recreating, this is the rootcause.

Try to save and restore imageUri:

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (savedInstanceState != null) {
        imageUri = savedInstanceState.getParcelable(IMAGE_URI_BUNDLE);
    }
}
@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putParcelable(IMAGE_URI_BUNDLE, imageUri);
}

You should initialize imageUri before starting camera intent

private void captureImage() {
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

    imageUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);

    intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri );

    // start the image capture Intent
    startActivityForResult(intent, CAMERA_CAPTURE_IMAGE_REQUEST_CODE);
}

Be carefull with capturing image from camera in fragment, in this case you should also save and restore imageUri in fragment and add in activity:

fragment.setRetainInstance(true);

Upvotes: 2

Daniel Kng
Daniel Kng

Reputation: 796

With a look at your code, it seems like the Activity get killed before it really starts.

Check if the Camera works in Landscapemode or try running an adb log and look if the App crashes because of heavy Memory usage or some weird coded stuff. You can do that with

adb logcat -s com.jublikon.example.ReviewMaschine.ReviewActivity

After that - if you found the Crash not by yourself, post it here, i will try to help you! :) And check where your Application starts.

Edit: Try using Breakpoints in Eclispe and Debugg your stuff! :)

Upvotes: 0

marcinj
marcinj

Reputation: 50026

Is this your activty? package and activity name:

com.jublikon.example.ReviewMaschine.ReviewActivity

NPE is comming from withing it

it looks like on this device your activity is being destroyed before camera app has finished. Your activity might get destroyed for various reasons - ie. camera app works only in landscape, or requires lots of memory and destroys your activity.

Now, after returning - before onActivityResult, android will call onCreate and onStart on your activity. So this is where you should put breakpoints to find where you read some data from null object.

Upvotes: 0

Related Questions