在较低的android版本上捕获图像时发生随机崩溃 [英] Random crash on capturing image on lower android versions

查看:58
本文介绍了在较低的android版本上捕获图像时发生随机崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In my application i capture image from camera, on marshmallow it works fine, but on lower version it gives random crash. Sometimes it works fine, sometimes it not . Here is code which i am using in my app

        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结果我正在这样做:

onActivity Result I am doing this :

 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;

}

在这里建议出什么问题了。
我需要图片路径(压缩和旋转)。有时,它工作得非常好,而另一些时间,它可以保存图像,然后返回到应用程序并重新开始调用活动。

Kindly suggest what is wrong here. I need picture path(compressed and rotated). Sometimes it works perfectly fine and other times on saving image it goes back to app and restart calling activity.

推荐答案


这是因为应用程序重新启动且其路径获得空值,因为仅当我打开相机时才设置路径

This is because app gets restarted and its path gets null value because path is set only when i open camera

您的进程在后台终止。 这是完全正常的行为。如果用户旋转屏幕,您也会有类似的症状。

Most likely, your process is being terminated while it is in the background. This is perfectly normal behavior. You will also have similar symptoms if the user rotates the screen.

通过 onSaveInstanceState() Bundle c $ c>。从保存的实例状态 Bundle 还原到 onCreate() onRestoreInstanceState() code>。然后,当控件通过 onActivityResult()返回给您时,您将拥有路径。 此示例应用演示了该过程,特别是使用 ACTION_IMAGE_CAPTURE

Save your path in the saved instance state Bundle via onSaveInstanceState(). Restore it from the saved instance state Bundle in onCreate() or onRestoreInstanceState(). Then, you will have your path when control returns to you via onActivityResult(). This sample app demonstrates the process, specifically with ACTION_IMAGE_CAPTURE.

这篇关于在较低的android版本上捕获图像时发生随机崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆