我在Android参考文档中没有找到相关信息: 三星SHW-M100S手机有两个摄像头。如果没有任何关于如何使用两个摄像头的参考信息,那么你有什么想法吗?
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
以其自己的方式处理相机操作。当您使用SurfaceView
来利用相机功能时,就会使用这种技术。 - user456118所有旧的答案方法都已被Google弃用(据说是因为像这样的麻烦),自API 21起,您需要使用相机2 API:
此类已于API级别21中过时。我们建议新应用程序使用新android.hardware.camera2 API。
在较新的API中,您几乎可以完全控制Android设备相机,并且文档明确建议如下:
String[] getCameraIdList()
然后使用获得的CameraId打开相机:
void openCamera(String cameraId, CameraDevice.StateCallback callback, Handler handler)
前置摄像头99%的ID为"1",后置摄像头ID为"0",根据以下内容:
不可拆卸的相机使用从0开始的整数作为其标识符,而可拆卸的相机则对每个单独的设备具有唯一的标识符,即使它们是相同的型号。
然而,这意味着如果设备情况很少,比如只有一个前置摄像头的平板电脑,您需要计算您有多少内置摄像头,并按其重要性(“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版本上工作,并且传输起来很麻烦)。只需像这个答案中一样使用相同的整数CameraID(1)打开前置摄像头即可。
cam = Camera.open(1);
如果您信任 OpenCV 处理相机部分:
内部:
<org.opencv.android.JavaCameraView
../>
使用以下内容来使用前置摄像头:
opencv:camera_id="1"
从Android 2.1版本开始,Android SDK 只支持单个摄像头。未来的Android版本可能会增加支持多个摄像头的功能。
打开后置相机:
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及以上版本中正常工作。此外,直接打开前置摄像头在某些设备上不可能(取决于制造商)。
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();
}
}
对于API 21(5.0)及更高版本,您可以使用CameraManager API
来处理与相机有关的事务。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.
}
}
}
android.hardware.Camera
类来获取相机数量、有关特定相机的信息以及引用特定的Camera
。请查看新的Camera
API 这里。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);
我发现这个很好用。
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
}
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 或更早版本的旧设备的解决方案。这可以用于测试目的,但不建议用于主要开发。这个解决方案只能被视为临时解决方案。但是这个解决方案已经帮助了很多人,所以我不打算删除这个答案 */