0

I am having a bit of trouble finding the solution to my problem. This is the third day working on it (not that I work on it all day) but still I am unable to fix it. I am adding a function to my app which is taking a photography, shorten it, compressing it and converting it to Base64 so I can send it as part of the information for a document. I have been able to do all of it but I am having two problems that I suppose are related to each other. The first one and the one I am having troubles with is that if after taking the photography successfully the user decides that he needs to change it by taking another photography a second time, the app crashes. Sometimes I have been able to take a second photography but a third time the app crashes. The user can decide how many pictures wants to take for finally deciding what to send, so I am not planing on limiting him to just take one. I am thinking that it has to do with memory leaks or something with the Activity lifecycle (which is also related to the memory as I understand) that gives me the problem. The second problem is that if the user decides to take a photography and is taken successfully, then decides to take another but later he decides to not take it giving a resultCode = 0 as expected, the Activity seems to be refreshed and all the EditText data stays intact but the previous photography is not shown. I could get it back in the onResume callback but I am not sure if there is something better to do.

Here are the snippets to my code:

public void tomarFotografia(View view) {
    Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    if (cameraIntent.resolveActivity(getPackageManager()) != null) {
        File photoFile = null;
        try {
            photoFile = createImageFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (photoFile != null) {
            Uri photoURI = FileProvider.getUriForFile(this, "com.thesageelder.pmt.remisiones", photoFile);
            cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
//              cameraIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
//              cameraIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);

            List<ResolveInfo> resolvedIntentActivities = getPackageManager().queryIntentActivities(cameraIntent, PackageManager.MATCH_DEFAULT_ONLY);
            for (ResolveInfo resolvedIntentInfo : resolvedIntentActivities) {
                String packageName = resolvedIntentInfo.activityInfo.packageName;
                grantUriPermission(packageName, photoURI, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
            }

            startActivityForResult(cameraIntent, CAMERA_REQUEST);
        }
    }
}

private File createImageFile() throws IOException {
    File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
    File image = File.createTempFile(
            "RemisionPMT" + new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss", Locale.US).format(Calendar.getInstance().getTime()),
            ".jpg",
            storageDir
    );
    currentPhotoFile = image.getAbsolutePath();
    return image;
}

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == CAMERA_REQUEST && resultCode == Activity.RESULT_OK) {
        File photoFile = new File(currentPhotoFile);
        try {
            Bitmap fullPhoto = MediaStore.Images.Media.getBitmap(getContentResolver(), Uri.fromFile(photoFile));

            float aspectRatio = fullPhoto.getWidth() / (float) fullPhoto.getHeight();
            int w = 1024;
            int h = Math.round(w / aspectRatio);

            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            Bitmap.createScaledBitmap(fullPhoto, w, h, true).compress(Bitmap.CompressFormat.JPEG, 70, byteArrayOutputStream);
            byte[] byteArray = byteArrayOutputStream.toByteArray();

            EncodedPhoto = Base64.encodeToString(byteArray, Base64.DEFAULT);

            try {
                ExifInterface exif = new ExifInterface(currentPhotoFile);
                int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1);
                int rotationDegrees = 0;
                switch (orientation) {
                    case ExifInterface.ORIENTATION_ROTATE_90:
                        rotationDegrees = 90;
                        break;
                    case ExifInterface.ORIENTATION_ROTATE_180:
                        rotationDegrees = 180;
                        break;
                    case ExifInterface.ORIENTATION_ROTATE_270:
                        rotationDegrees = 270;
                        break;
                }

                Bitmap photoThumnail = ThumbnailUtils.extractThumbnail(BitmapFactory.decodeFile(currentPhotoFile), fullPhoto.getScaledWidth(getResources().getDisplayMetrics()) / 4, fullPhoto.getScaledHeight(getResources().getDisplayMetrics()) / 4);

                if (rotationDegrees != 0) {
                    Matrix matrix = new Matrix();
                    matrix.postRotate(rotationDegrees);
                    photoThumnail = Bitmap.createBitmap(photoThumnail, 0, 0, photoThumnail.getWidth(), photoThumnail.getHeight(), matrix, true);
                }

                ivFotoPreview.setImageBitmap(photoThumnail);
            } catch (Exception e) {
                e.printStackTrace();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

And this is the logcat:

18819-18819 E/AndroidRuntime: FATAL EXCEPTION: main Process: com.thesageelder.pmt.remisiones, PID: 18819 java.lang.RuntimeException: Unable to resume activity {com.thesageelder.pmt.remisiones/com.thesageelder.pmt.remisiones.RemisionView}: java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=2000, result=-1, data=null} to activity {com.thesageelder.pmt.remisiones/com.thesageelder.pmt.remisiones.RemisionView}: java.lang.NullPointerException at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2797) at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2826) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2257) at android.app.ActivityThread.access$800(ActivityThread.java:139) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1200) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:136) at android.app.ActivityThread.main(ActivityThread.java:5103) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:606) at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:132) at dalvik.system.NativeStart.main(Native Method) Caused by: java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=2000, result=-1, data=null} to activity {com.thesageelder.pmt.remisiones/com.thesageelder.pmt.remisiones.RemisionView}: java.lang.NullPointerException at android.app.ActivityThread.deliverResults(ActivityThread.java:3384) at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2784) at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2826)  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2257)  at android.app.ActivityThread.access$800(ActivityThread.java:139)  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1200)  at android.os.Handler.dispatchMessage(Handler.java:102)  at android.os.Looper.loop(Looper.java:136)  at android.app.ActivityThread.main(ActivityThread.java:5103)  at java.lang.reflect.Method.invokeNative(Native Method)  at java.lang.reflect.Method.invoke(Method.java:515)  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:606)  at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:132)  at dalvik.system.NativeStart.main(Native Method)  Caused by: java.lang.NullPointerException at java.io.File.fixSlashes(File.java:185) at java.io.File.(File.java:134) at com.thesageelder.pmt.remisiones.RemisionView.onActivityResult(RemisionView.java:749) at android.app.Activity.dispatchActivityResult(Activity.java:5467) at android.app.ActivityThread.deliverResults(ActivityThread.java:3380) at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2784)  at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2826)  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2257)  at android.app.ActivityThread.access$800(ActivityThread.java:139)  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1200)  at android.os.Handler.dispatchMessage(Handler.java:102)  at android.os.Looper.loop(Looper.java:136)  at android.app.ActivityThread.main(ActivityThread.java:5103)  at java.lang.reflect.Method.invokeNative(Native Method)  at java.lang.reflect.Method.invoke(Method.java:515)  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:606)  at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:132)  at dalvik.system.NativeStart.main(Native Method)

I have placed a breakpoint in the very first line in the onActivityResult super.onActivityResult(requestCode, resultCode, data); and the app crashes without even stopping there. I have no idea what is the problem and being unable to debug it, I finally decide to ask here after some days searching for it. I think that all the other questions and answers I have read are related to not managing the result code or not reading correctly the data portion of the delivery result for the Activity. In my case I am expecting a resultCode different to -1 from the user and the data portion returns null since I want the full photography (since I found no way to having it from the data's extras).

Any help would be appreciated and sorry for the long question, I hope that writing this much detail would help understand my problem.

Not sure if it helps or not, but I am using an LG L70 with KitKat 4.4.2 to test it. Maybe with a more powerful device I would not have the problem, but the devices that the users are going to use wont be that more powerful.

Regards,

Elder

PD1: I do have the permission for <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> and <uses-permission android:name="android.permission.CAMERA"/>

PD2: I am leaving the entire camera function that I used here for some one that may need help with the camera and the FileProvider, additional to the previous code, it is needed that this is added to the Manifest:

<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="[package]"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_paths"></meta-data>
</provider>

and a XML resource file file_paths.xml with this:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="RemisionesPMT" path="Android/data/[package]/files/Pictures" />
</paths>

It took me six hours to figure it out.

Elder
  • 1
  • 1
  • The given stack trace is saying that `currentPhotoFile` is null at `File photoFile = new File(currentPhotoFile);`. From what I can gather from your description, it's possible that your `Activity` is being destroyed when the camera app starts, and you lose the `currentPhotoFile` that was created beforehand. You should be doing something similar to what is shown in [this answer](https://stackoverflow.com/a/45388858), where they're saving and retrieving the previously created `File` via the `Activity`'s instance state, with their `EXTRA_FILENAME` key. – Mike M. Aug 26 '18 at 08:14
  • Beyond that, I do appreciate your desire to provide as much information as possible, but your question is a rather daunting wall of text, with some likely irrelevant detail. Please do try to make your questions succinct and specific. – Mike M. Aug 26 '18 at 08:15
  • Thank you Mike, I will be careful next time I ask a question. I will work with the answer you shared and update here the progress. – Elder Aug 28 '18 at 19:49
  • Thank you @MikeM. the problem was exactly what you suggested. I had been expecting the Activity to be destroyed but it never popped up with the debugger and now I know I did not notice that the debugger was being disconnected at some point. Since you did not wrote an answer, how can I give you the positive feedback? – Elder Aug 28 '18 at 20:56
  • Sorry if I write so much, how did you knew that `currentPhotoFile` was **null**? I been reading the logcat and as far as I see, it is no explicit that `currentPhotoFile` is the cause of the _NullPointerException_ – Elder Aug 28 '18 at 21:00

0 Answers0