摘要:拍照相机使用意图和显示正确方向的照片(适用于希望所有设备)(Summary: Take a p

2019-08-31 07:00发布

这似乎是世界上最简单的事情:使用默认的相机拍摄的活动Android应用中的图片。 不过,也有被覆盖在整个StackOverflow的几个职位,并在网上为,例如很多陷阱,空意图传递回的照片的方向不会是正确或OutOfMemoryError异常。

我正在寻找一个解决方案,可以让我

  1. 通过摄像机意图启动摄像头活动,
  2. 取回照片的URI和
  3. 取回照片的正确方向。

此外,我想避免的设备配置(制造商,型号,操作系统版本)具体实施尽可能。 所以我想知道:什么是实现这一目标的最佳途径?

Answer 1:

更新:2014年1月2日:我真的是竭尽全力地避免实施基于设备制造商不同的策略。 不幸的是,我没有得到解决它。 通过数百个职位的打算再跟几个开发商,没人发现,在所有设备上工作没有实现设备制造商的特定代码的解决方案。

我在这里张贴在计算器上我的解决方案后,一些开发商要求我发布在GitHub上我的代码。 因此,这里现在是: AndroidCameraUtil在github

该代码是在各种各样的与Android API级别> = 8,有关完整列表的设备测试成功,请在Github上查看自述文件。

所述CameraIntentHelperActivity提供的主要功能,其也被更详细地描述如下。

调用默认的摄像头活动:

  • 三星和索尼的设备 :我请与方法调用startActivityForResult相机活动。 我只设置不变CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE。 我没有设置任何其他额外的意图。
  • 对于所有其他设备 :我请与方法调用startActivityForResult如前摄像头活动。 然而这一次,我还设置了额外的意图和MediaStore.EXTRA_OUTPUT提供一个URI,在这里我希望存储图像。

在这两种情况下,我记得相机活动开始的时间。


在摄像头的活动结果:

  1. Mediastore:首先,我尝试读取从MediaStore被捕获的照片。 使用在MediaStore内容mangedQuery,我检索所采取的最新的图像,以及它的定向性和它的时间戳。 如果我发现图像并没有采取相机意图调用之前,这是我一直在寻找的图像。 否则,我解雇的结果,请尝试以下方法之一。
  2. 额外的意向:第二,我尝试返回意图摆脱intent.getData图像URI()。 如果这要么是没有成功,我继续第3步。
  3. 默认图片网址 :如果所有上述步骤没有工作,我用的是图像的Uri我传递到相机的活动。

在这一点上,我检索到的照片URI和它的方向,我传递给我的UploadPhotoActivity。


图像处理

请把我的BitmapHelper类的密切关注。 它是基于在详细描述的代码在该教程 。

此外,该方法shrinkBitmap也旋转,如果基于先前提取出的方位信息所需的图像。


我希望这是有帮助的一些你。



Answer 2:

我已经测试此代码与索尼的Xperia围棋,三星Galaxy SII,三星Galaxy SIII Mini和三星银河Ÿ它的工作在所有设备上!

但在LG E400(2.3.6)没有工作,你会得到在画廊双画面。 所以我已经添加在虚空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);
}


Answer 3:

在银河S3与CM 10.1我得到了一个BitmapHelper异常空指针:

BM = BitmapFactory.decodeFileDescriptor(fileDescriptor.getFileDescriptor(),NULL,选项);

随后我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(); } 

在第二日志(IMAGE ERROR 2)。 多试几次后我的相机坏了,我得到了一个“无法连接到相机”误差。

测试它在Nexus 7和它完美的作品。

编辑:把范围缩小到这一点:

文件描述符= context.getContentResolver()openAssetFileDescriptor(selectedImage, “R”)。

虽然selectedImage包含此:

文件:///storage/emulated/0/DCIM/Camera/IMG_20131023_183343.jpg

该文件描述符返回一个FileNotFoundException异常。 我检查了文件系统和图像没有在这个位置保存。 该cameraPicUri在TakePhotoActivity指向一个不存在的图像。 我目前正在检查的地方一切都错了。

EDIT2:我想通了错误:由于该设备是三星,并告诉应用程序,这是一个三星的设备,应用三星的具体修正。 的CyanogenMod并不需要这些补丁虽然,最终的代码中断。 一旦你删除

(manufacturer.contains( “三星”))&&

有用。 由于这是一个定制的ROM你不能规划那当然。 我试图找出一个办法,如果设备运行CyanogenMod的检测,然后包括这个在你的代码。

感谢您一个不错的相机装!

EDIT3: 我固定它通过改变你的代码,这对银河S3的CyanogenMod运行:好了,现在有时有效,有时却不行。 奇怪。

如果(getPackageManager()。hasSystemFeature( “com.cyanogenmod.android”)||(!(manufacturer.contains( “三星”))&&!(manufacturer.contains( “索尼”))&&!(manufacturer.contains(” LGE“))))



Answer 4:

我用这与索尼的Xperia Z5时遇到了一些问题。

我加了这一点,它有很多更好。

if (buildType.contains("sony")&& buildDevice.contains("e5823")) {
                setPreDefinedCameraUri = true;}

但4次中有22是摄像机重新启动,一旦它重新启动两次。 我重新启动应用程序,由于每个测试。 是否有某种方式来解决这个问题还是我接受这个结果呢?

问题是,如果相机重新启动我可以两次热潮按后退按钮,图像会出现在我的ImageView和保存



文章来源: Summary: Take a picture utilizing Camera Intent and display the photo with correct orientation (works on hopefully all devices)