似乎这是世界上最简单的事情之一:使用默认相机活动在您的Android应用程序中拍照。然而,有许多陷阱,在StackOverflow和网络上有几篇文章对其进行了覆盖,例如传回空意图、图片方向不正确或OutOfMemoryErrors等。
我正在寻找一种解决方案,允许我
- 通过相机意图启动相机活动,
- 检索照片的Uri,并且
- 检索照片的正确方向。
此外,尽可能避免设备配置(制造商、型号、操作系统版本)的具体实现。因此,我想知道:最好的方法是什么?
似乎这是世界上最简单的事情之一:使用默认相机活动在您的Android应用程序中拍照。然而,有许多陷阱,在StackOverflow和网络上有几篇文章对其进行了覆盖,例如传回空意图、图片方向不正确或OutOfMemoryErrors等。
我正在寻找一种解决方案,允许我
此外,尽可能避免设备配置(制造商、型号、操作系统版本)的具体实现。因此,我想知道:最好的方法是什么?
更新:2014年1月2日: 我尽力避免根据设备制造商实施不同的策略。不幸的是,我无法回避它。在阅读了数百篇帖子并与几位开发人员交谈后,没有人找到一种可在所有设备上运行且无需实施特定于设备制造商的代码的解决方案。
在我在StackOverflow上发布了我的解决方案后,一些开发人员要求我将我的代码发布到github上。所以现在它在这里:AndroidCameraUtil on github
该代码已在Android API-Level >= 8的各种设备上成功测试。有关完整列表,请参见github上的Readme文件。
CameraIntentHelperActivity提供了主要功能,以下内容也对其进行了更详细的描述。
调用默认相机活动:
在两种情况下,我都记住了相机活动开始的时间。
在相机活动结果上:
此时,我已经获取了照片Uri及其方向,并将它们传递给我的UploadPhotoActivity。
图像处理
请仔细查看我的BitmapHelper类。 它基于该教程中详细描述的代码。
此外,shrinkBitmap方法还根据之前提取的方向信息旋转图像(如果需要)。
希望对你们中的一些人有所帮助。
compile 'de.ecostatic:camerautil:1.0.0'
?这将会非常非常方便 :) - jean d'arme我在使用Sony Xperia Z5时遇到了一些问题。
我添加了这个,效果好多了。
if (buildType.contains("sony")&& buildDevice.contains("e5823")) {
setPreDefinedCameraUri = true;}
但在22次测试中,有4次它重新启动了相机,还有一次它重新启动了两次。我每次测试都重启了应用程序。 有没有什么方法可以避免这种情况,或者我应该接受这个结果?
问题是,如果相机重新启动,我可以按两次返回按钮,瞬间就能在我的ImageView中看到图像并保存。
我已经在Sony Xperia Go、Samsung Galaxy SII、Samsung Galaxy SIII mini和Samsung Galaxy Y上测试了这段代码,它可以在所有设备上运行!
但是在LG E400(2.3.6)上它无法工作,你会在图库中看到重复的图片。因此,我在void startCameraIntent()中添加了manufacturer.contains("lge")以解决问题。
if(!(manufacturer.contains("samsung")) && !(manufacturer.contains("sony")) && !(manufacturer.contains("lge"))) {
String filename = System.currentTimeMillis() + ".jpg";
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE, filename);
cameraPicUri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
intent.putExtra(MediaStore.EXTRA_OUTPUT, cameraPicUri);
}
bm = BitmapFactory.decodeFileDescriptor(fileDescriptor.getFileDescriptor(), null, options);
随后我的UploadPhotoActivity在以下位置失败:
try {
photo = BitmapHelper.readBitmap(this, cameraPicUri);
if (photo != null) {
photo = BitmapHelper.shrinkBitmap(photo, 600, rotateXDegrees);
thumbnail = BitmapHelper.shrinkBitmap(photo, 100);
ImageView imageView = (ImageView) findViewById(R.id.sustainable_action_photo);
imageView.setImageBitmap(photo);
} else {
Log.e(TAG,"IMAGE ERROR 1");
}
} catch (Exception e) {
Log.e(TAG,"IMAGE ERROR 2");
e.printStackTrace();
}
在第二个日志(图像错误2)处。
尝试了几次后,我的相机坏了,并出现了“无法连接到相机”的错误。file:///storage/emulated/0/DCIM/Camera/IMG_20131023_183343.jpg
fileDescriptor返回FileNotFoundException。我检查了文件系统,发现图像未保存在此位置。TakePhotoActivity中的cameraPicUri指向一个不存在的图像。我正在检查出错的地方。
编辑2:我找到了错误:由于设备是三星设备,并告诉应用程序它是三星设备,因此应用了三星特定的修复程序。但Cyanogenmod不需要这些修复程序,最终代码会崩溃。一旦你删除
(manufacturer.contains("samsung")) &&
它就可以工作了。当然,由于这是自定义ROM,你无法计划这种情况。我正在尝试找出一种方法来检测设备是否运行Cyanogenmod,然后将其包含在你的代码中。
感谢你提供的良好相机修复!
编辑3:我已经将它修复为在Galaxy S3上运行Cyanogenmod,将你的代码更改为:好吧,现在有时候它能工作,有时候它不能。奇怪。
if (getPackageManager().hasSystemFeature("com.cyanogenmod.android") || (!(manufacturer.contains("samsung")) && !(manufacturer.contains("sony")) && !(manufacturer.contains("lge"))))