Android的ACTION_IM​​AGE_CAPTURE意向意向、Android、ACTION_IM、AGE_CAPTURE

2023-09-11 10:29:28 作者:比女王还傲

我们要使用本机摄像头的应用程序,让用户拍摄新照片。它工作得很好,如果我们离开了 EXTRA_OUTPUT额外键,返回小位图图像。但是,如果我们 putExtra(EXTRA_OUTPUT,...)在启动之前的意图,一切正常,直到您尝试点击确定按钮,在相机应用。 确定按钮少了点什么。摄像头的应用程序保持打开状态,并没有锁定。我们可以取消它,但文件永远不会被写入。究竟是什么,我们必须做的就是 ACTION_IM​​AGE_CAPTURE 写带到了一个文件了吗?

We are trying to use the native camera app to let the user take a new picture. It works just fine if we leave out the EXTRA_OUTPUT extra and returns the small Bitmap image. However, if we putExtra(EXTRA_OUTPUT,...) on the intent before starting it, everything works until you try to hit the "Ok" button in the camera app. The "Ok" button just does nothing. The camera app stays open and nothing locks up. We can cancel out of it, but the file never gets written. What exactly do we have to do to get ACTION_IMAGE_CAPTURE to write the picture taken to a file?

编辑:这是通过 MediaStore.ACTION_IM​​AGE_CAPTURE 故意做的,仅仅是明确的。

This is done via the MediaStore.ACTION_IMAGE_CAPTURE intent, just to be clear

推荐答案

这是一个的有据可查的错误在某些版本的Andr​​oid系统。也就是说,在谷歌的经验建立的Andr​​oid,图像采集不作为记录工作。我所通常使用的是这样的一个实用工具类。

this is a well documented bug in some versions of android. that is, on google experience builds of android, image capture doesn't work as documented. what i've generally used is something like this in a utilities class.

public boolean hasImageCaptureBug() {

    // list of known devices that have the bug
    ArrayList<String> devices = new ArrayList<String>();
    devices.add("android-devphone1/dream_devphone/dream");
    devices.add("generic/sdk/generic");
    devices.add("vodafone/vfpioneer/sapphire");
    devices.add("tmobile/kila/dream");
    devices.add("verizon/voles/sholes");
    devices.add("google_ion/google_ion/sapphire");

    return devices.contains(android.os.Build.BRAND + "/" + android.os.Build.PRODUCT + "/"
            + android.os.Build.DEVICE);

}

然后当我启动图像捕捉,我创建检查错误的意图。

then when i launch image capture, i create an intent that checks for the bug.

Intent i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
if (hasImageCaptureBug()) {
    i.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File("/sdcard/tmp")));
} else {
    i.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
}
startActivityForResult(i, mRequestCode);

那么的活动,我回,我做基础设备上不同的东西。

then in activity that i return to, i do different things based on the device.

protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
     switch (requestCode) {
         case GlobalConstants.IMAGE_CAPTURE:
             Uri u;
             if (hasImageCaptureBug()) {
                 File fi = new File("/sdcard/tmp");
                 try {
                     u = Uri.parse(android.provider.MediaStore.Images.Media.insertImage(getContentResolver(), fi.getAbsolutePath(), null, null));
                     if (!fi.delete()) {
                         Log.i("logMarker", "Failed to delete " + fi);
                     }
                 } catch (FileNotFoundException e) {
                     e.printStackTrace();
                 }
             } else {
                u = intent.getData();
            }
    }

这可以节省您不必编写一个新的相机应用程序,但这种code是不算很好。大问题是

this saves you having to write a new camera app, but this code isn't great either. the big problems are

你永远不会得到全尺寸的图像从 该设备与错误。你得到 图片是512PX宽的 被插入到图像内容 供应商。在没有设备 臭虫,一切正常文件, 你会得到一个很大的正常图像。

you never get full sized images from the devices with the bug. you get pictures that are 512px wide that are inserted into the image content provider. on devices without the bug, everything works as document, you get a big normal picture.

您必须维护该列表。如 写的,它有可能为设备 同一个版本的闪现 机器人(比如的CyanogenMod的 建立),有固定的bug。 如果出现这种情况,您的code会 崩溃。解决方法是使用整个 设备的指纹。

you have to maintain the list. as written, it is possible for devices to be flashed with a version of android (say cyanogenmod's builds) that has the bug fixed. if that happens, your code will crash. the fix is to use the entire device fingerprint.