Ошибка при доставке результата в действие для android.media.action.IMAGE_CAPTURE на onActivityResult после первой работы - PullRequest
0 голосов
/ 26 августа 2018

У меня возникли проблемы с поиском решения моей проблемы. Это третий день работы над ним (не то, что я работаю над этим весь день), но все же я не могу это исправить. Я добавляю в мое приложение функцию, которая делает фотографии, укорачивает их, сжимает и конвертирует в Base64, чтобы я мог отправить их как часть информации для документа. Я смог сделать все это, но у меня две проблемы, которые, я полагаю, связаны друг с другом. Первая проблема, с которой у меня возникают проблемы, заключается в том, что если после успешной фотосъемки пользователь решает, что ему нужно изменить его, сделав другую фотографию во второй раз, приложение вылетает. Иногда мне удавалось сделать вторую фотографию, но в третий раз приложение зависало. Пользователь может решить, сколько снимков хочет сделать, чтобы окончательно решить, что отправлять, поэтому я не планирую ограничивать его, чтобы сделать одно. Я думаю, что это связано с утечками памяти или чем-то с жизненным циклом Activity (который, как я понимаю, также связан с памятью), который вызывает у меня проблему. Вторая проблема заключается в том, что если пользователь решает сделать фотографию и ее успешно сделали, а затем решает сделать еще одну, но позже он решает не делать ее, выдавая resultCode = 0 , как и ожидалось, активность, по-видимому, обновлены, и все данные EditText остаются без изменений, но предыдущая фотография не отображается. Я мог бы вернуть его в обратном вызове onResume , но я не уверен, что есть что-то лучше.

Вот фрагменты моего кода:

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

А это logcat:

18819-18819 E / AndroidRuntime: FATAL EXCEPTION: main Процесс: com.thesageelder.pmt.remisiones, PID: 18819 java.lang.RuntimeException: Невозможно возобновить деятельность {com.thesageelder.pmt.remisiones / com.thesageelder.pmt.remisiones.RemisionView}: java.lang.RuntimeException: ошибка доставки результата ResultInfo {кто = ноль, запрос = 2000, результат = -1, данные = ноль} к деятельности {Com.thesageelder.pmt.remisiones / com.thesageelder.pmt.remisiones.RemisionView}: java.lang.NullPointerException на android.app.ActivityThread.performResumeActivity (ActivityThread.java:2797) на android.app.ActivityThread.handleResumeActivity (ActivityThread.java:2826) на android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:2257) на android.app.ActivityThread.access $ 800 (ActivityThread.java:139) на android.app.ActivityThread $ H.handleMessage (ActivityThread.java:1200) на android.os.Handler.dispatchMessage (Handler.java:102) на android.os.Looper.loop (Looper.java:136) на android.app.ActivityThread.main (ActivityThread.java:5103) в java.lang.reflect.Method.invokeNative (родной метод) в java.lang.reflect.Method.invoke (Method.java:515) на com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run (ZygoteInit.java:790) на com.android.internal.os.ZygoteInit.main (ZygoteInit.java:606) на de.robv.android.xposed.XposedBridge.main (XposedBridge.java:132) в dalvik.system.NativeStart.main (собственный метод) Вызвано: java.lang.RuntimeException: сбой при доставке результата ResultInfo {who = null, request = 2000, result = -1, data = null} в действие {Com.thesageelder.pmt.remisiones / com.thesageelder.pmt.remisiones.RemisionView}: java.lang.NullPointerException на android.app.ActivityThread.deliverResults (ActivityThread.java:3384) на android.app.ActivityThread.performResumeActivity (ActivityThread.java:2784) на android.app.ActivityThread.handleResumeActivity (ActivityThread.java:2826) на android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:2257) на android.app.ActivityThread.access $ 800 (ActivityThread.java:139) на android.app.ActivityThread $ H.handleMessage (ActivityThread.java:1200)на android.os.Handler.dispatchMessage (Handler.java:102) на android.os.Looper.loop (Looper.java:136) на android.app.ActivityThread.main (ActivityThread.java:5103) на java.lang.refle.Method.invokeNative (собственный метод) на java.lang.reflect.Method.invoke (Method.java:515) на com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run (ZygoteInit.java:790) на ком.android.internal.os.ZygoteInit.main (ZygoteInit.java:606) в de.robv.android.xposed.XposedBridge.main (XposedBridge.java:132) в dalvik.system.NativeStart.main (собственный метод), вызванный:java.lang.NullPointerException в java.io.File.fixSlashes (File.java:185) в java.io.File. (File.java:134) в com.thesageelder.pmt.remisiones.RemisionView.onActivityResult (RemisionView.java): 749) в android.app.Activity.dispatchActivityResult (Activity.java:5467) в android.app.ActivityThread.deliverResults (ActivityThread.java:3380) в android.app.ActivityThread.performResumeActivity (ActivityThread.java:2784) в Android.app.ActivityThread.handleResumeActivity (ActivityThread.java:2826) в android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:2257) в android.app.ActivityThread.access $ 800 (ActivityThread.java:139) в android.app.ActivityThread $ H.handleMessage (ActivityThread.java:1200) на android.os.Handler.dispatchMessage (Handler.java:102) на android.os.Looper.loop (Looper.java:136) на android.app.ActivityThread.main (ActivityThread.java:5103) в java.lang.reflect.Method.invokeNative (собственный метод) в java.lang.reflect.Method.invoke (Method.java:515) в com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run (ZygoteInit.java): 790) на com.android.internal.os.ZygoteInit.main (ZygoteInit.java:606) на de.robv.android.xposed.XposedBridge.main (XposedBridge.java:132) на dalvik.system.NativeStart.main (Собственный метод)

Я поместил точку останова в самую первую строку в onActivityResult super.onActivityResult(requestCode, resultCode, data);, и приложение зависает, даже не останавливаясь там.Я понятия не имею, в чем проблема, и, поскольку я не могу отладить ее, я наконец-то решаю спросить ее здесь после нескольких дней ее поиска.Я думаю, что все остальные вопросы и ответы, которые я прочитал, связаны с неуправлением кодом result или неправильным чтением части data результата доставки для Activity.В моем случае я ожидаю resultCode , отличный от -1 от пользователя, а часть data возвращает null , так как я хочу полныйфотография (так как я не нашел способа получить ее из дополнений data ).

Любая помощь будет признательна, и извините за длинный вопрос, я надеюсь, что написание этой подробностипомогите понять мою проблему.

Не уверен, помогает ли это или нет, но я использую LG L70 с KitKat 4.4.2 для проверки.Возможно, с более мощным устройством у меня не было бы проблемы, но устройства, которые будут использовать пользователи, не будут такими более мощными.

С уважением,

Старейшина

PD1: у меня есть разрешение на <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> и <uses-permission android:name="android.permission.CAMERA"/>

PD2: я оставляю всю функцию камеры, которую я здесь использовал, для кого-то, кому может понадобиться помощь с камерой и FileProvider, в дополнение к предыдущему коду, необходимо, чтобы он был добавлен в 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>

и файл ресурсов XML file_paths.xml с этим:

<?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>

Мне потребовалось шесть часов, чтобы понять это.

...