如何在安卓平台打开“前置摄像头”?
Posted
技术标签:
【中文标题】如何在安卓平台打开“前置摄像头”?【英文标题】:How do I open the "front camera" on the Android platform? 【发布时间】:2011-02-16 06:21:58 【问题描述】:更一般地说,如果设备有多个嵌入式摄像头, 有没有办法特别初始化其中一个?
我在 android 参考文档中没有找到它:
https://developer.android.com/reference/android/hardware/Camera.html https://developer.android.com/reference/android/hardware/camera2/package-summary.html https://developer.android.com/reference/android/hardware/camera2/CameraManager.html三星 SHW-M100S 有两个摄像头。如果没有提到使用两个摄像头,你知道三星是怎么做到的吗……?
【问题讨论】:
How to use Front Facing Camera on Samsung Galaxy S的可能重复 【参考方案1】:从 Android 2.1 开始,Android 在其 SDK 中仅支持单个摄像头。这很可能会在未来的 Android 版本中添加。
【讨论】:
此声明对 Android 2.2 也有效? @ozmank:是的,直到 Android 2.3 才添加多摄像头支持。【参考方案2】:public void surfaceCreated(SurfaceHolder holder)
try
mCamera = Camera.open();
mCamera.setDisplayOrientation(90);
mCamera.setPreviewDisplay(holder);
Camera.Parameters p = mCamera.getParameters();
p.set("camera-id",2);
mCamera.setParameters(p);
catch (IOException e)
// TODO Auto-generated catch block
e.printStackTrace();
【讨论】:
在 Galaxy S 上工作良好 重要的“camera-id”不是“camera_id” 永远不要假设 90 度会让你得到正确的肖像旋转。它在许多设备上有所不同。【参考方案3】:随着Android 2.3 (Gingerbread) 的发布,您现在可以使用android.hardware.Camera
类来获取摄像头的数量、特定摄像头的相关信息以及对特定Camera
的引用。查看新的Camera
API here。
【讨论】:
【参考方案4】:private Camera openFrontFacingCameraGingerbread()
int cameraCount = 0;
Camera cam = null;
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
cameraCount = Camera.getNumberOfCameras();
for (int camIdx = 0; camIdx < cameraCount; camIdx++)
Camera.getCameraInfo(camIdx, cameraInfo);
if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT)
try
cam = Camera.open(camIdx);
catch (RuntimeException e)
Log.e(TAG, "Camera failed to open: " + e.getLocalizedMessage());
return cam;
在AndroidManifest.xml
文件中添加以下权限:
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" android:required="false" />
<uses-feature android:name="android.hardware.camera.front" android:required="false" />
注意:此功能在 Gingerbread(2.3) 及以上 Android 版本中可用。
【讨论】:
是否可以通过Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
技术以某种方式使用它来打开现有的相机应用程序?
@loeschg Intent
以自己的方式处理相机动作。当您使用SurfaceView
来利用相机功能时,会使用此技术。
这就是我的想法。谢谢!
非常酷的帖子。我花了一段时间才发现相机朝向不一定与相机索引相同。例如,我的平板电脑只有一个摄像头(索引:0)但面向前方(面对索引:1)。因此使用像 Camera.open(CameraInfo.CAMERA_FACING_FRONT) 这样的简单代码是没有意义的。
@Matthias 同意你的观点。由于我们有不同的 OEM,我们的编程技术会根据我们的需要进行更改。感谢您强调。【参考方案5】:
Camera camera;
if (Camera.getNumberOfCameras() >= 2)
//if you want to open front facing camera use this line
camera = Camera.open(CameraInfo.CAMERA_FACING_FRONT);
//if you want to use the back facing camera
camera = Camera.open(CameraInfo.CAMERA_FACING_BACK);
try
camera.setPreviewDisplay("your surface holder here");
camera.startPreview();
catch (Exception e)
camera.release();
/* 这不是正确的方法,这是运行 Android 4.0 或更早版本的旧设备的解决方案。这可以用于测试目的,但不推荐用于主要开发。此解决方案只能被视为临时解决方案。但是这个解决方案帮助了很多人,所以我不打算删除这个答案*/
【讨论】:
我认为它没有记录在案的用法。 open(int id) 接受 id,而不是相机位置 请删除这个误导性的答案 @AmalanDhananjayan:例如参见@Matthias above 的评论:……我花了一段时间才发现摄像头朝向不一定与摄像头索引相同。例如,我的平板电脑只有一个摄像头(索引:0)但面向前方(面对索引:1)。因此使用像 Camera.open(CameraInfo.CAMERA_FACING_FRONT) 这样的简单代码是没有意义的。 这是秃头。甚至不要尝试使用它。 这太可怕了。永远不要这样做。这个答案应该被禁止。 Camera.open() 接受一个摄像头 ID,而不是摄像头朝向的序数值!这在极少数设备上都失败了,而且只能靠运气。【参考方案6】:Google 已弃用所有旧答案的方法(可能是因为这样的麻烦),因为 API 21 你需要 use Camera 2 API:
此类已在 API 级别 21 中弃用。我们建议使用新的 android.hardware.camera2 API 用于新应用程序。
在 the newer API 中,您对 Android 设备的摄像头和文档拥有几乎完全的权力,并明确建议
String[] getCameraIdList()
然后使用获取的CameraId打开相机:
void openCamera(String cameraId, CameraDevice.StateCallback callback, Handler handler)
99%的前置摄像头id = "1",后置摄像头id = "0" 根据这个:
不可移动的相机使用从 0 开始的整数作为它们的 标识符,而可移动相机对每个都有一个唯一的标识符 单个设备,即使它们是同一型号。
然而,这意味着如果设备情况很少见,例如只有 1 个前置摄像头的平板电脑,您需要计算您拥有多少个嵌入式摄像头,然后下订单相机的重要性(“0”)。所以 CAMERA_FACING_FRONT == 1 CAMERA_FACING_BACK == 0,这意味着后置摄像头比前置摄像头更重要。
我不知道在所有 Android 设备上识别前置摄像头的统一方法。简单地说,由于某些原因,设备内部的 Android 操作系统无法真正找出哪个摄像头的确切位置:也许唯一的摄像头硬编码 id 是一个表示其重要性的整数,或者在某些设备上,无论您转向哪一边都会是..”回来”。
文档:https://developer.android.com/reference/android/hardware/camera2/package-summary.html
显式示例:https://github.com/googlesamples/android-Camera2Basic
对于较旧的 API(不建议这样做,因为它不适用于较新的 Android 版本的现代手机,并且传输很麻烦)。只需使用相同的 Integer CameraID (1) 打开前置摄像头,就像在this answer 中一样:
cam = Camera.open(1);
如果您信任 OpenCV 来做相机部分:
里面
<org.opencv.android.JavaCameraView
../>
使用以下前置摄像头:
opencv:camera_id="1"
【讨论】:
【参考方案7】:对于 API 21 (5.0) 及更高版本,您可以使用 CameraManager API's
try
String desiredCameraId = null;
for(String cameraId : mCameraIDsList)
CameraCharacteristics chars = mCameraManager.getCameraCharacteristics(cameraId);
List<CameraCharacteristics.Key<?>> keys = chars.getKeys();
try
if(CameraCharacteristics.LENS_FACING_FRONT == chars.get(CameraCharacteristics.LENS_FACING))
// This is the one we want.
desiredCameraId = cameraId;
break;
catch(IllegalArgumentException e)
// This key not implemented, which is a bit of a pain. Either guess - assume the first one
// is rear, second one is front, or give up.
【讨论】:
【参考方案8】:build.gradle
dependencies
compile 'com.google.android.gms:play-services-vision:9.4.0+'
设置视图
CameraSourcePreview mPreview = (CameraSourcePreview) findViewById(R.id.preview);
GraphicOverlay mGraphicOverlay = (GraphicOverlay) findViewById(R.id.faceOverlay);
CameraSource mCameraSource = new CameraSource.Builder(context, detector)
.setRequestedPreviewSize(640, 480)
.setFacing(CameraSource.CAMERA_FACING_FRONT)
.setRequestedFps(30.0f)
.build();
mPreview.start(mCameraSource, mGraphicOverlay);
【讨论】:
【参考方案9】:打开后置摄像头:-
val cameraIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
startActivityForResult(cameraIntent, REQUEST_CODE_CAMERA)
打开前置摄像头:-
val cameraIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
when
Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1 && Build.VERSION.SDK_INT < Build.VERSION_CODES.O ->
cameraIntent.putExtra("android.intent.extras.CAMERA_FACING", CameraCharacteristics.LENS_FACING_FRONT) // Tested on API 24 Android version 7.0(Samsung S6)
Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ->
cameraIntent.putExtra("android.intent.extras.CAMERA_FACING", CameraCharacteristics.LENS_FACING_FRONT) // Tested on API 27 Android version 8.0(Nexus 6P)
cameraIntent.putExtra("android.intent.extra.USE_FRONT_CAMERA", true)
else -> cameraIntent.putExtra("android.intent.extras.CAMERA_FACING", 1) // Tested API 21 Android version 5.0.1(Samsung S4)
startActivityForResult(cameraIntent, REQUEST_CODE_CAMERA)
我无法使其适用于 API 28 及更高版本。此外,某些设备无法直接打开前置摄像头(取决于制造商)。
【讨论】:
对于 API 28 及更高版本,您有解决方案吗?【参考方案10】:我发现这很好用。
fun frontCamera(context: Context): Int
val cameraManager = context.getSystemService(Context.CAMERA_SERVICE) as CameraManager
return cameraManager.cameraIdList
.find id ->
cameraManager.getCameraCharacteristics(id)[LENS_FACING] == LENS_FACING_FRONT
?.toInt() ?: 0
【讨论】:
以上是关于如何在安卓平台打开“前置摄像头”?的主要内容,如果未能解决你的问题,请参考以下文章