使用意图拍照后应用程序崩溃

14

使用意图(Intent)拍摄5到6张照片后,我的应用程序崩溃了。logcat没有显示任何信息,我无法找到它崩溃的原因。请帮帮我。

    private void capturePhoto() {

        File root = new File(Environment.getExternalStorageDirectory(), "Feedback");
        if (!root.exists()) {
            root.mkdirs();
        }
        File file = new File(root, Constants.PROFILE_IMAGE_NAME + ".jpeg");
        Uri outputFileUri = Uri.fromFile(file);


        Intent photoPickerIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        photoPickerIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
        photoPickerIntent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
        photoPickerIntent.putExtra("return-data", true);
        photoPickerIntent.putExtra("android.intent.extras.CAMERA_FACING", 1);
        startActivityForResult(photoPickerIntent, requestCode);


    }


    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (this.requestCode == requestCode && resultCode == RESULT_OK) {

            File root = new File(Environment.getExternalStorageDirectory(), "Feedback");
            if (!root.exists()) {
                root.mkdirs();
            }
            File file = new File(root, Constants.PROFILE_IMAGE_NAME+".jpeg");
            checkFlowIdisPresent(file);

            displayPic();


        }
    }
  private void displayPic() {

        String filePath = Environment.getExternalStorageDirectory()
                .getAbsolutePath() + File.separator + "/Feedback/" + Constants.PROFILE_IMAGE_NAME + ".jpeg";
        //  Bitmap bmp = BitmapFactory.decodeFile(filePath);
        //Bitmap scaled = Bitmap.createScaledBitmap(bmp, 300, 300, true);


        File imgFile = new File(filePath);
        Bitmap bmp = decodeFile(imgFile);

        if (imgFile.exists()) {

            dispProfilePic.setImageBitmap(bmp);
        } else {
            dispProfilePic.setBackgroundResource(R.drawable.user_image);

        }
    }

 private Bitmap decodeFile(File f) {
        try {
            // Decode image size
            BitmapFactory.Options o = new BitmapFactory.Options();
            o.inJustDecodeBounds = true;
            BitmapFactory.decodeStream(new FileInputStream(f), null, o);

            // The new size we want to scale to
            final int REQUIRED_SIZE = 70;

            // Find the correct scale value. It should be the power of 2.
            int scale = 1;
            while (o.outWidth / scale / 2 >= REQUIRED_SIZE &&
                    o.outHeight / scale / 2 >= REQUIRED_SIZE) {
                scale *= 2;
            }

            // Decode with inSampleSize
            BitmapFactory.Options o2 = new BitmapFactory.Options();
            o2.inSampleSize = scale;
            return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
        } catch (FileNotFoundException e) {
        }
        return null;
    }

以上代码是用于拍摄照片并在ImageView中显示捕获的图片。我正在使用MI平板电脑。

编辑实际上应用程序没有崩溃......它变成了白屏,如果我按任何按钮,则会崩溃,并且当它变成白屏时不执行onActivityResult。

新的编辑我能够复制这个问题。我点击Android Monitor,然后点击Monitor。然后它显示与应用程序交互时的内存利用率。现在在左侧边栏中,我点击终止应用程序图标。现在有趣的事情是,它销毁了当前的活动并移动到先前的活动。那个先前的活动变成了白屏。

请帮帮我吧。


4
您能发布崩溃日志吗?啊,Logcat 没有显示任何信息。 - abbath
1
它什么也不显示,而且很难复制。 - venkatesh gowda
2
它必须显示一些东西。如果您成功复制,请在此处发布,因为没有它,几乎不可能帮助您 :/ - Vucko
你在清单文件中声明了权限吗?例如写入外部存储和相机。 - Narender Reddy
谢谢@Lev。现在变得有趣了。感谢您在OOMException中给出的提示,让我先检查一下这个问题。 - venkatesh gowda
显示剩余12条评论
9个回答

3
尝试使用以下代码。在我的某些应用程序中我使用了它:
启动 Intent 方法:
private void launchCamera() {
        Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        startActivityForResult(cameraIntent, CAMERA_PIC_REQUEST);
    }

捕获结果:

@Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        try {
            if (requestCode == CAMERA_PIC_REQUEST) {
                if (data != null) {
                    Bundle extras = data.getExtras();
                    if (extras != null) {
                        Bitmap thumbnail = (Bitmap) extras.get("data");
                        if (thumbnail != null)
                            displayPic(thumbnail);
                    }
                }
            }
            } catch (Exception e) {
            e.printStackTrace();
            }
    }

3

你的代码没问题...

我认为你要么保存了图片,要么在同一路径上用相同的名称覆盖了图片,因此内存出现问题。所以我建议你使用 System.currentTimeMillis() 或任何随机名称来更改名称,而不是使用 Constants.PROFILE_IMAGE_NAME

还要检查权限。

 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

同时也需要在运行时检查此权限...要进行运行时检查,请遵循此链接

private static final int REQUEST_RUNTIME_PERMISSION = 123;


    if (CheckPermission(demo.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {


        capturePhoto();

    } else {
        // you do not have permission go request runtime permissions
        RequestPermission(demo.this, Manifest.permission.WRITE_EXTERNAL_STORAGE, REQUEST_RUNTIME_PERMISSION);
    }



public void RequestPermission(Activity thisActivity, String Permission, int Code) {
        if (ContextCompat.checkSelfPermission(thisActivity,
                Permission)
                != PackageManager.PERMISSION_GRANTED) {
            if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
                    Permission)) {
                capturePhoto();

            } else {
                ActivityCompat.requestPermissions(thisActivity,
                        new String[]{Permission},
                        Code);
            }
        }
    }

    public boolean CheckPermission(Activity context, String Permission) {
        if (ContextCompat.checkSelfPermission(context,
                Permission) == PackageManager.PERMISSION_GRANTED) {
            return true;
        } else {
            return false;
        }
    }

常量.PROFILE_IMAGE_NAME 是随机流 ID。 - venkatesh gowda

3

如果在log cat上没有显示任何内容,很难猜测问题出在哪里,但请检查是否存在在模拟器上使用时而不是在真实设备上的问题。您还可以通过使模拟器容量更小(RAM和内存)来检查是否可以重新创建问题。如果是这种情况,请增加模拟器的内存或RAM,它应该可以正常工作。然后,您需要优化图像处理任务以适应低规格设备。

希望这可以帮助您。


2
这可能是内存问题,你正在拍照并将它们存储在位图中。请检查你的Android监视器以检测应用程序的内存使用情况。只需将此方法设为静态即可。
private static Bitmap decodeFile(File f) {
        try {
            // Decode image size
            BitmapFactory.Options o = new BitmapFactory.Options();
            o.inJustDecodeBounds = true;
            BitmapFactory.decodeStream(new FileInputStream(f), null, o);

            // The new size we want to scale to
            final int REQUIRED_SIZE = 70;

            // Find the correct scale value. It should be the power of 2.
            int scale = 1;
            while (o.outWidth / scale / 2 >= REQUIRED_SIZE &&
                    o.outHeight / scale / 2 >= REQUIRED_SIZE) {
                scale *= 2;
            }

            // Decode with inSampleSize
            BitmapFactory.Options o2 = new BitmapFactory.Options();
            o2.inSampleSize = scale;
            return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
        } catch (FileNotFoundException e) {
        }
        return null;
    }

将文件用不同的名称保存,例如用时间戳作为名称保存


2
可能会出现这种情况,是因为操作系统处理通过相机捕获的位图时需要大量内存,导致调用活动被杀死并重新启动解决方案:保存图像的文件路径,并在调用onActivityResult方法时使用它。您可以使用onSavedInstanceStateonRestoreInstanceState方法来保存和检索活动的IMAGE_PATH和其他字段。
您可以参考此链接如何使用 onSavedInstanceState 和 onRestoreInstanceState

2

由于您在UI线程中进行了大量处理,导致您面临的问题,请尝试在异步任务中完成。

有关Async任务实现的更多帮助,请参见此处


1

尝试使用以下代码。对我来说它很好用。

 private static final int REQUEST_CAMERA = 1;

 @Override
 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (resultCode == RESULT_OK)
    {
        if (requestCode == REQUEST_CAMERA)
        {
            Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
            ByteArrayOutputStream bytes = new ByteArrayOutputStream();
            thumbnail.compress(Bitmap.CompressFormat.JPEG, 90, bytes);

            File destination = new File(Environment.getExternalStorageDirectory(), System.currentTimeMillis() + ".jpg");

            FileOutputStream fos;

            try
            {
                destination.createNewFile();
                fos = new FileOutputStream(destination);
                fos.write(bytes.toByteArray());
                fos.close();
            }
            catch (FileNotFoundException fnfe)
            {
                fnfe.printStackTrace();
            }
            catch (IOException ioe)
            {
                ioe.printStackTrace();
            }
            ivSetImage.setImageBitmap(thumbnail);

        }
   }
}

在给定的代码片段中,我压缩了捕获的图像,从而解决了应用崩溃的问题。
在您的情况下,由于捕获的图像质量可能很高,因此在设置ImageView上的图像时,应用程序会崩溃。
只需尝试压缩图像即可解决问题!
不要忘记在清单文件中添加权限。
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

1

请检查您的Manifest.xml文件权限 外部存储

和相机权限。

<uses-permission android:name="android.permission.CAMERA" />    
<uses-feature android:name="android.hardware.camera" />  <uses-feature
android:name="android.hardware.camera.autofocus" />

如果您的应用运行在Marshenter code heremallow上,请检查运行时权限


0

尝试使用以下代码:

private void launchCamera() {
    Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    startActivityForResult(cameraIntent, CAMERA_PIC_REQUEST);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    try {
        if (requestCode == CAMERA_PIC_REQUEST) {
            if (data != null) {
                Bundle extras = data.getExtras();
                if (extras != null) {
                    Bitmap thumbnail = (Bitmap) extras.get("data");
                    if (thumbnail != null)
                        displayPic(thumbnail);
                }
            }
        }
        } catch (Exception e) {
        e.printStackTrace();
        }
}

请不要发布与您的答案无关的链接! - mraron

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接