在较低的Android版本上捕获图像的随机崩溃

时间:2016-10-19 10:28:09

标签: android camera

在我的应用程序中,我从相机捕获图像,在棉花糖上它工作正常,但在较低版本它会随机崩溃。有时它工作正常,有时却不行。这是我在我的应用程序中使用的代码

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

onActivity结果我这样做:

 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 个答案:

答案 0 :(得分:2)

  

这是因为app重新启动并且其路径获取空值,因为路径仅在我打开相机时设置

最有可能的是,您的流程在后台处理时被终止。 This is perfectly normal behavior。如果用户旋转屏幕,您也会有类似的症状。

通过Bundle将路径保存在已保存的实例状态onSaveInstanceState()中。从BundleonCreate()中保存的实例状态onRestoreInstanceState()恢复它。然后,当控制权通过onActivityResult()返回给您时,您将获得路径。 This sample app演示了该过程,特别是ACTION_IMAGE_CAPTURE