Android ACTION_IMAGE_CAPTURE 意图
我们正在尝试使用本机相机应用程序让用户拍摄新照片。如果我们省略 EXTRA_OUTPUT extra
并返回小位图图像,它就可以正常工作。但是,如果我们在启动意图之前 putExtra(EXTRA_OUTPUT,...)
,那么一切都会正常,直到您尝试点击相机应用中的“确定”按钮。 “确定”按钮什么也不做。相机应用程序保持打开状态,没有任何锁定。我们可以取消它,但文件永远不会被写入。我们究竟需要做什么才能让 ACTION_IMAGE_CAPTURE
将拍摄的图片写入文件?
编辑:这是通过 MediaStore.ACTION_IMAGE_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?
Edit: This is done via the MediaStore.ACTION_IMAGE_CAPTURE
intent, just to be clear
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(14)
这是某些 Android 版本中的有据可查的错误。也就是说,在 Android 的 google experience 版本中,图像捕获无法按照记录进行。我通常在实用程序类中使用类似的东西。
然后,当我启动图像捕获时,我创建一个意图来检查错误。
然后在我返回的活动中,我根据设备做不同的事情。
这使您不必编写新的相机应用程序,但此代码也不是很好。最大的问题是
你永远无法获得完整尺寸的图像
存在错误的设备。你得到
宽度为 512px 的图片
被插入到图像内容中
提供者。在没有的设备上
bug,一切都像文档一样工作,
你会得到一张大的正常图片。
您必须维护该列表。作为
书面的,对于设备来说是可能的
用以下版本进行刷新
android(比如 cyanogenmod 的
构建),已修复该错误。
如果发生这种情况,您的代码将
碰撞。修复方法是使用整个
设备指纹。
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.
then when i launch image capture, i create an intent that checks for the bug.
then in activity that i return to, i do different things based on the device.
this saves you having to write a new camera app, but this code isn't great either. the big problems are
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.
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.
我知道这个问题之前已经被回答过,但我知道很多人都被这个问题绊倒了,所以我要添加一条评论。
我的 Nexus One 上也出现了同样的问题。这是来自相机应用程序启动之前磁盘上不存在的文件。因此,我在启动相机应用程序之前确保该文件存在。以下是我使用的一些示例代码:
我首先使用 MD5 哈希创建一个唯一(某种程度上)的文件名,并将其放入适当的文件夹中。然后我检查它是否存在(不应该,但无论如何检查都是一个很好的做法)。如果它不存在,我会获取父目录(一个文件夹)并创建直至其的文件夹层次结构(因此,如果通向文件位置的文件夹不存在,它们将在此行之后。然后在那之后创建文件后,我会获取 Uri 并将其传递给意图,然后“确定”按钮将按预期工作,
现在,当按下相机应用程序上的“确定”按钮时,该文件将被创建。存在于给定位置,在此示例中为 /sdcard/Android/data/com.example.myapp/files/234asdioue23498ad.jpg
无需复制上面发布的“onActivityResult”中的文件。
I know this has been answered before but I know a lot of people get tripped up on this, so I'm going to add a comment.
I had this exact same problem happen on my Nexus One. This was from the file not existing on the disk before the camera app started. Therefore, I made sure that the file existing before started the camera app. Here's some sample code that I used:
I first create a unique (somewhat) file name using an MD5 hash and put it into the appropriate folder. I then check to see if it exists (shouldn't, but its good practice to check anyway). If it does not exist, I get the parent dir (a folder) and create the folder hierarchy up to it (therefore if the folders leading up to the location of the file don't exist, they will after this line. Then after that I create the file. Once the file is created I get the Uri and pass it to the intent and then the OK button works as expected and all is golden.
Now,when the Ok button is pressed on the camera app, the file will be present in the given location. In this example it would be /sdcard/Android/data/com.example.myapp/files/234asdioue23498ad.jpg
There is no need to copy the file in the "onActivityResult" as posted above.
我尝试过多种照片拍摄策略,但似乎总有一种情况、某个平台或某些设备,上述策略中的部分或全部会以意想不到的方式失败。我找到了一种使用下面的 URI 生成代码的策略,该策略似乎适用于大多数情况(如果不是所有情况)。
为了进一步促进讨论并帮助新手,我创建了一个示例/测试应用程序,其中显示了几种不同的照片捕获实施策略。绝对鼓励其他实现的贡献加入到讨论中。
https://github.com/deepwinter/AndroidCameraTester
I've been through a number of photo capture strategies, and there always seems to be a case, a platform or certain devices, where some or all of the above strategies will fail in unexpected ways. I was able to find a strategy that uses the URI generation code below which seems to work in most if not all cases.
To contribute further to the discussion and help out newcomers I've created a sample/test app that shows several different strategies for photo capture implementation. Contributions of other implementations are definitely encouraged to add to the discussion.
https://github.com/deepwinter/AndroidCameraTester
我遇到了同样的问题,相机应用程序中的“确定”按钮没有任何反应,无论是在模拟器上还是在 Nexus One 上。
在 MediaStore.EXTRA_OUTPUT 中指定一个没有空格、没有特殊字符的安全文件名后,问题就消失了。此外,如果您指定的文件位于尚未创建的目录中,你必须先创建它。相机应用程序不会为您执行 mkdir 操作。
I had the same problem where the OK button in camera app did nothing, both on emulator and on nexus one.
The problem went away after specifying a safe filename that is without white spaces, without special characters, in
MediaStore.EXTRA_OUTPUT
Also, if you are specifying a file that resides in a directory that has not yet been created, you have to create it first. Camera app doesn't do mkdir for you.您描述的工作流程应该按照您所描述的方式工作。如果您可以向我们展示有关创建 Intent 的代码,可能会有所帮助。一般来说,以下模式应该可以让您做您正在尝试的事情。
请注意,相机 Activity 将创建并保存文件,它实际上并不是应用程序的一部分,因此它不具有对应用程序文件夹的写入权限。要将文件保存到您的应用文件夹,请在 SD 卡上创建一个临时文件,并将其移至
onActivityResult
处理程序中的应用文件夹。The workflow you describe should work as you've described it. It might help if you could show us the code around the creation of the Intent. In general, the following pattern should let you do what you're trying.
Note that it is the Camera Activity that will be creating and saving the file, and it's not actually part of your application, so it won't have write permission to your application folder. To save a file to your app folder, create a temporary file on the SD card and move it to your app folder in the
onActivityResult
handler.为了跟进Yenchi上面的评论,如果相机应用程序无法写入有问题的目录,那么“确定”按钮也不会执行任何操作。
这意味着您无法在只能由您的应用程序写入的位置创建文件(例如
getCacheDir() 下的某些内容)
getExternalFilesDir()
下的某些内容应该然而,工作。如果相机应用程序无法写入指定的
EXTRA_OUTPUT
路径,那么如果相机应用程序在日志中打印一条错误消息,那就太好了,但我没有找到。To follow up on Yenchi's comment above, the OK button will also do nothing if the camera app can't write to the directory in question.
That means that you can't create the file in a place that's only writeable by your application (for instance, something under
getCacheDir())
Something undergetExternalFilesDir()
ought to work, however.It would be nice if the camera app printed an error message to the logs if it could not write to the specified
EXTRA_OUTPUT
path, but I didn't find one.要让相机写入 SD 卡,但保留在图库应用程序上的新相册中,我使用以下方法:
请注意,您每次都需要生成唯一的文件名并替换我编写的 1111.jpg。
这是用 Nexus 1 进行测试的。
uri 在私有类中声明,因此在活动结果中,如果需要,我可以将图像从 uri 加载到 imageView 进行预览。
to have the camera write to sdcard but keep in a new Album on the gallery app I use this :
Please note that you will need to generate a unique filename every time and replace teh 1111.jpg that I wrote.
This was tested with nexus one.
the uri is declared in the private class , so on activity result I am able to load the image from the uri to imageView for preview if needed.
我遇到了同样的问题,我用以下方法修复了它:
问题是,当您指定只有您的应用程序有权访问的文件时(例如通过调用
getFileStreamPath("file");
),那就是为什么我只是确保给定的文件确实存在并且每个人都对其具有写访问权限。
这样,相机应用程序就可以对给定的 Uri 进行写入访问,并且“确定”按钮可以正常工作:)
I had the same issue and i fixed it with the following:
The problem is that when you specify a file that only your app has access to (e.g. by calling
getFileStreamPath("file");
)That is why i just made sure that the given file really exists and that EVERYONE has write access to it.
This way, the camera app has write access to the given Uri and the OK button works fine :)
我建议您按照 Android 培训帖子拍摄照片。他们在示例中展示了如何拍摄小照片和大照片。您还可以从此处下载源代码
I recommend you to follow the android trainning post for capturing a photo. They show in an example how to take small and big pictures. You can also download the source code from here
我创建了简单的库,它将管理从不同来源(图库、相机)选择图像,也许将其保存到某个位置(SD 卡或内部存储器)并将图像返回,因此请随意使用它并改进它 - Android-ImageChooser。
I created simple library which will manage choosing images from different sources (Gallery, Camera), maybe save it to some location (SD-Card or internal memory) and return the image back so please free to use it and improve it - Android-ImageChooser.
正如 Praveen 指出的那样,该文件需要可由相机写入。
在我的使用中,我想将文件存储在内部存储中。我是这样做的:
这里
cacheFile
是一个全局文件,用于引用写入的文件。然后在result方法中返回的intent为null。
那么处理意图的方法如下所示:
这里
getImageFile()
是一个实用方法,用于命名和创建应存储图像的文件,而copyFile()
是一种复制文件的方法。The file needs be writable by the camera, as Praveen pointed out.
In my usage I wanted to store the file in internal storage. I did this with:
Here
cacheFile
is a global file used to refer to the file which is written.Then in the result method the returned intent is null.
Then the method for processing the intent looks like:
Here
getImageFile()
is a utility method to name and create the file in which the image should be stored, andcopyFile()
is a method to copy a file.您可以使用此代码
You can use this code
使用 Activity Result Code 解决这个问题非常简单,简单尝试一下这个方法
It is very simple to solve this problem with Activity Result Code Simple try this method