Случайный сбой при захвате изображения на более низких версиях Android

#android #camera

#Android #камера

Вопрос:

В моем приложении я снимаю изображение с камеры, на marshmallow это работает нормально, но на более низкой версии это приводит к случайному сбою. Иногда это работает нормально, иногда нет. Вот код, который я использую в своем приложении

         String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        String photoName = "Image_"   timeStamp   ".jpg";
        String imageFile = new File(extStorageDirectory, photoName);
        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        // Ensure that there's a camera activity to handle the intent
        if (takePictureIntent.resolveActivity(context.getPackageManager()) != null) {
            // Create the File where the photo should go
            try {
                SingleTon.getInstance().imageFile.createNewFile();
            } catch (IOException ex) {
                // Error occurred while creating the File
                ex.printStackTrace();
            }

            // Continue only if the File was successfully created
            if ( SingleTon.getInstance().imageFile != null) {
                Log.e("Check1 ", SingleTon.getInstance().imageFile ";");
                takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(SingleTon.getInstance().imageFile));
                ((Activity)context).startActivityForResult(takePictureIntent, Constant.CAMERA_PIC_REQUEST);
            }
        }
  

В результате бездействия я делаю это :

  Uri imagePathUri = Uri.parse(SingleTon.getInstance().imageFile.getPath());
        String picturePath =    compressImage(context, imagePathUri);
  

Для сжатия изображения

       public static String compressImage(Context context, Uri imageUri) {
    String filePath = getRealPathFromURI(context, imageUri);

    Bitmap scaledBitmap = null;
    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    Bitmap bmp = BitmapFactory.decodeFile(filePath,options);

    int actualHeight = options.outHeight;//2988
    int actualWidth = options.outWidth; //5312

    float maxHeight = 1200.0f;
    float maxWidth = 1200.0f;
    /*float maxHeight = 816.0f;
    float maxWidth = 612.0f;*/
    float imgRatio = actualWidth / actualHeight;
    float maxRatio = maxWidth / maxHeight;

    if (actualHeight > maxHeight || actualWidth > maxWidth) {
        if (imgRatio < maxRatio) {
            imgRatio = maxHeight / actualHeight;
            actualWidth = (int) (imgRatio * actualWidth);
            actualHeight = (int) maxHeight;
        } else if (imgRatio > maxRatio) {
            imgRatio = maxWidth / actualWidth;
            actualHeight = (int) (imgRatio * actualHeight);
            actualWidth = (int) maxWidth;
        } else {
            actualHeight = (int) maxHeight;
            actualWidth = (int) maxWidth;

        }
    }

    options.inSampleSize = calculateInSampleSize(options, actualWidth, actualHeight);
    options.inJustDecodeBounds = false;
    options.inDither = false;
    options.inPurgeable = true;
    options.inInputShareable = true;
    options.inTempStorage = new byte[16*1024];

    try{
        bmp = BitmapFactory.decodeFile(filePath,options);
    }
    catch(OutOfMemoryError exception){
        exception.printStackTrace();

    }
    try{
        scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight, Bitmap.Config.ARGB_8888);
    }
    catch(OutOfMemoryError exception){
        exception.printStackTrace();
    }

    float ratioX = actualWidth / (float) options.outWidth;
    float ratioY = actualHeight / (float)options.outHeight;
    float middleX = actualWidth / 2.0f;
    float middleY = actualHeight / 2.0f;

    Matrix scaleMatrix = new Matrix();
    scaleMatrix.setScale(ratioX, ratioY, middleX, middleY);

    Canvas canvas = new Canvas(scaledBitmap);
    canvas.setMatrix(scaleMatrix);
    canvas.drawBitmap(bmp, middleX - bmp.getWidth()/2, middleY - bmp.getHeight() / 2, new Paint(Paint.FILTER_BITMAP_FLAG));


    ExifInterface exif;
    try {
        exif = new ExifInterface(filePath);

        int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 0);
        Log.d("EXIF", "Exif: "   orientation);
        Matrix matrix = new Matrix();
        if (orientation == 6 || orientation == 0) {
            matrix.postRotate(90);
            Log.d("EXIF", "Exif: "   orientation);
        } else if (orientation == 3) {
            matrix.postRotate(180);
            Log.d("EXIF", "Exif: "   orientation);
        } else if (orientation == 8) {
            matrix.postRotate(270);
            Log.d("EXIF", "Exif: "   orientation);
        }
        scaledBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0,scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix, true);
    } catch (IOException e) {
        e.printStackTrace();
    }
    FileOutputStream out = null;
    String filename = getFilename();
    try {
        out = new FileOutputStream(filename);
        scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 80, out);

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

    return filename;

}
  

Пожалуйста, подскажите, что здесь не так.
Мне нужен путь к изображению (сжатый и повернутый). Иногда это работает отлично, а в других случаях при сохранении изображения оно возвращается в приложение и перезапускает вызывающую активность.

Комментарии:

1. Опубликуйте свой журнал cat, чтобы кто-то мог определить ошибку, не теряя времени.

2. i возвращает null для пути к изображению в результате onActiviyt. Это потому, что приложение перезапускается, а его путь получает нулевое значение, потому что путь устанавливается только при открытии камеры

Ответ №1:

Это потому, что приложение перезапускается, а его путь получает нулевое значение, потому что путь устанавливается только при открытии камеры

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

Сохраните свой путь в сохраненном состоянии экземпляра Bundle через onSaveInstanceState() . Восстановите его из состояния сохраненного экземпляра Bundle в onCreate() или onRestoreInstanceState() . Затем у вас будет свой путь, когда управление вернется к вам через onActivityResult() . Этот пример приложения демонстрирует процесс, в частности с ACTION_IMAGE_CAPTURE .