Захват изображения с помощью камеры, файл создан, но не возвращается в ActivityResult

Я рассмотрел большую часть связанного с этим вопроса о том, что результат активности возвращает значение null с использованием камеры Intent. Вот мой код ниже:

String filepath;
File file;
Bitmap bitmap;
int previewcount=0;
@OnClick(R.id.lnrcamera)
public void opencamera()
{
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    if (intent.resolveActivity(this.getPackageManager()) != null)
    {
        try
        {
            file = createImageFile();
        }
        catch (IOException ex)
        {
            // Error occurred while creating the File
        }
        // Continue only if the File was successfully created
        if (file != null)
        {
            intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
            startActivityForResult(intent, FILE_CAMERA);
        }
    }
}

private File createImageFile() throws IOException {
    // Create an image file name
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    String imageFileName = "JPEG_" + timeStamp + "_";
    File storageDir = Environment.getExternalStoragePublicDirectory(
            Environment.DIRECTORY_PICTURES);
    File image = File.createTempFile(
            imageFileName,  // prefix
            ".jpg",         // suffix
            storageDir      // directory
    );

    // Save a file: path for use with ACTION_VIEW intents
    filepath = "file:" + image.getAbsolutePath();
    return image;
}

На ActivityResult

 else if (requestCode==FILE_CAMERA && resultCode == RESULT_OK)
    {
        try
        {
            Log.d("sdfasdfasdf", "onActivityResult: "+filepath.isEmpty());
            bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), Uri.parse(filepath));
            int newHeight = (bitmap.getHeight() * 500)/bitmap.getWidth();
            bitmap = Bitmap.createScaledBitmap(bitmap, 500, newHeight, false);
            list_bitmap.add(bitmap);
            lnrpreview.setVisibility(View.VISIBLE);
            Adapter_Image adapter_expenseCategory=new Adapter_Image(this, 0, list_bitmap, new RecyclerCallback() {
                @Override
                public void onPreviewDelete(List<Bitmap> list_bitmap)
                {
                    Log.d("hereornot", "onPreviewDelete: "+list_bitmap.size());
                    previewcount--;
                    if (list_bitmap.size()==0)
                    {
                        lnrpreview.setVisibility(View.GONE);
                        imgpreviewcount.setImageResource(R.drawable.flagoff);
                    }
                    btxtpreviewcount.setBadgeCount(previewcount);
                }
            });
            recycler.setAdapter(adapter_expenseCategory);
            previewcount++;
            btxtpreviewcount.setBadgeCount(previewcount);
            imgpreviewcount.setImageResource(R.drawable.flagon);
        }
        catch (OutOfMemoryError e)
        {
            Toast.makeText(Activity_NewExpense.this, "Your device is out of Memory. Please free up some space.", Toast.LENGTH_SHORT).show();
        }
        catch (IndexOutOfBoundsException e)
        {
            Log.d("hereornot", "onPreviewDelete: "+e.getMessage());
        }
        catch (FileNotFoundException e)
        {
            Log.d("hereornot", "onPreviewDelete: "+e.getMessage());
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }

Теперь вопрос в том, что всякий раз, когда я пытался открыть камеру и сделать несколько фотографий, снимки делаются, и они тоже находятся в памяти, но действие не возвращает мне путь к файлу. Тестирующему устройству не хватает памяти. Тем не менее, для 1 или двух щелчков он отлично работает с камерой, но более чем для двух щелчков происходит сбой и выдается эта ошибка:

Невозможно возобновить действие java.lang.RuntimeException: сбой доставки результата ResultInfo{who=null, request=2, result=-1, data=null} для действия java.lang.NullPointerException в android.app.ActivityThread.performResumeActivity(ActivityThread. java:2996) в android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3025) в android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2396) в android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3974) в android.app.ActivityThread.access$1000(ActivityThread.java:166) в android.app.ActivityThread$H.handleMessage(ActivityThread.java:1287)

Поскольку изображение может быть большим, я изменил его размер и установил largeheap=true, но, к сожалению, это не сработало. Может ли кто-нибудь указать мне, где я сделал неправильно?


person Joshan Tandukar    schedule 11.09.2018    source источник
comment
Чтобы избежать ошибок oom, попробуйте использовать библиотеку загрузки изображений, например Glide или Picasso.   -  person Ivan Wooll    schedule 11.09.2018


Ответы (2)


Скорее всего, ваш процесс завершается, когда он находится в фоновом режиме. Вам нужно сохранить местоположение вашего файла в сохраненном состоянии экземпляра Bundle, чтобы при необходимости вы могли его вернуть.

Этот пример проекта (из эта книга) иллюстрирует, как использовать сохраненное состояние экземпляра Bundle для удержания местоположения файла. Он также демонстрирует, как использовать FileProvider, который вам понадобится, если вы хотите, чтобы ваше приложение работало на устройствах Android 7.0+, как Uri.fromFile() не будет работать.

person CommonsWare    schedule 11.09.2018
comment
Да, это то, что происходило все время. Но есть ли способ предотвратить уничтожение моей активности, несмотря ни на что? - person Joshan Tandukar; 12.09.2018
comment
Нет, у вас нет контроля над системой. Если приложению камеры требуется больше памяти для захвата изображения, Android убьет любое фоновое приложение, чтобы освободить ресурсы. - person Alex Cohn; 12.09.2018
comment
@JoshanTandukar: Что еще более важно, это не ограничивается простым запуском приложения камеры. Каждый раз, когда ваше приложение больше не находится на переднем плане, Android может завершить ваш процесс, чтобы освободить оперативную память для использования другими приложениями. - person CommonsWare; 12.09.2018
comment
Понял, спасибо. Думал, что я ничего не могу сделать, когда это происходит, но я попытался воссоздать экземпляр пакета, сохранив его перед запуском камеры и вернув его обратно, если возникло исключение. Спасибо бро, очень помогло. Я застрял там на 5 дней. - person Joshan Tandukar; 13.09.2018

Если пользователь отменяет запрос, данные будут возвращены как NULL. Поток выдаст исключение nullPointerException при вызове data.getExtras().get("data");. Я думаю, вам просто нужно добавить условие, чтобы проверить, являются ли возвращаемые данные нулевыми.

person Anubhav Gupta    schedule 11.09.2018
comment
Извините, сэр, я должен упомянуть, что данные всегда возвращают ноль, но я анализирую путь к файлу, но изображение уже сохранено в памяти, но пока file.getAbsolutePath ничего не возвращает. И отмена работает нормально. - person Joshan Tandukar; 11.09.2018