android.hardware.Camera 每次都打不开
android.hardware.Camera fails to open every second time
问题背景
我正在 Unreal Engine 4 上开发一个 VR 项目,该项目需要使用 Android 的原生相机。由于 UE4 中没有内置函数可以与 Android 的本地方法进行交互,因此我根据需要自定义了 this plugin。
原始插件使用 JNI 接口与 C++ 代码进行交互。它在 UE4 的 EventBeginPlay
上调用 camera.open()
和 camera.startPreview()
,在 UE4 的 EventEndPlay
上调用 camera.stopPreview()
和 camera.Release()
。由于 known issue EventEndPlay
永远不会在 Android 平台上启动,我决定在 onResume()
和 onPause()
方法中操纵相机。这是代码:
<gameActivityClassAdditions>
<insert>
/* Unrelevant code goes here */
...
...
/* End of unrelevant code */
public void AndroidThunkJava_startCamera()
{
surfaceTexture = new SurfaceTexture(10);
surfaceTexture.setDefaultBufferSize(preferredWidth, preferredHeight);
if (camera == null){
try {
camera = Camera.open();
} catch (RuntimeException exc) {
return;
}
}
try {
camera.setPreviewTexture(surfaceTexture);
} catch (IOException t) {
return;
}
Parameters cameraParam = camera.getParameters();
cameraParam.setPreviewFormat(ImageFormat.NV21);
cameraParam.setPreviewSize(preferredWidth, preferredHeight);
cameraParam.setPreviewFpsRange(preferredFPS, preferredFPS);
cameraParam.setFocusMode(Camera.Parameters.FOCUS_MODE_MACRO);
if (cameraParam.isVideoStabilizationSupported()) {
cameraParam.setVideoStabilization(false);
}
if (cameraParam.isAutoWhiteBalanceLockSupported()) {
cameraParam.setAutoWhiteBalanceLock(false);
}
camera.setParameters(cameraParam);
camera.setPreviewCallback(new PreviewCallback() {
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
int Height = camera.getParameters().getPreviewSize().height;
int Width = camera.getParameters().getPreviewSize().width;
// calling C++ function via JNI interface
processFrameData(Width, Height, data);
}
});
camera.startPreview();
}
public void AndroidThunkJava_stopCamera()
{
if (camera != null)
{
camera.stopPreview();
camera.release();
camera = null;
}
}
</insert>
</gameActivityClassAdditions>
<gameActivityOnPauseAdditions>
<insert>
AndroidThunkJava_stopCamera();
</insert>
</gameActivityOnPauseAdditions>
<gameActivityOnResumeAdditions>
<insert>
AndroidThunkJava_startCamera();
</insert>
</gameActivityOnResumeAdditions>
问题
相机每两次都正常。这意味着:
我打开应用程序,相机正在工作。我按下主页按钮(触发 onPause()
方法),然后切换回应用程序(触发 onResume()
方法)。再次按下主页按钮,然后切换回来 - 相机工作。以此类推,相机每隔一秒工作一次。
有人知道这个问题吗?这与 android.hardware.Camera
被弃用的事实有关吗?我使用的是 API 版本 19,因此无法使用更新的 android.hardware.camera2
.
这是我的 onStop 和 onResume 方法。我没有使用 onPause。它完美地工作:
@Override
protected void onResume() {
super.onResume();
if (mCamera == null) {
restartPreview();
}
}
@Override
public void onStop() {
// stop the preview
if (mCamera != null) {
stopCameraPreview();
mCamera.release();
mCamera = null;
}
super.onStop();
}
private void restartPreview() {
if (mCamera != null) {
stopCameraPreview();
mCamera.release();
mCamera = null;
}
getCamera(mCameraID);
startCameraPreview();
}
private void startCameraPreview() {
try {
mCamera.setPreviewDisplay(mSurfaceHolder);
mCamera.startPreview();
setSafeToTakePhoto(true);
setCameraFocusReady(true);
} catch (IOException e) {
Log.d("st", "Can't start camera preview due to IOException " + e);
e.printStackTrace();
}
}
private void stopCameraPreview() {
setSafeToTakePhoto(false);
setCameraFocusReady(false);
// Nulls out callbacks, stops face detection
mCamera.stopPreview();
mPreviewView.setCamera(null);
}
也许有些实现不等于你的,但我认为它对你有帮助。
问题背景
我正在 Unreal Engine 4 上开发一个 VR 项目,该项目需要使用 Android 的原生相机。由于 UE4 中没有内置函数可以与 Android 的本地方法进行交互,因此我根据需要自定义了 this plugin。
原始插件使用 JNI 接口与 C++ 代码进行交互。它在 UE4 的 EventBeginPlay
上调用 camera.open()
和 camera.startPreview()
,在 UE4 的 EventEndPlay
上调用 camera.stopPreview()
和 camera.Release()
。由于 known issue EventEndPlay
永远不会在 Android 平台上启动,我决定在 onResume()
和 onPause()
方法中操纵相机。这是代码:
<gameActivityClassAdditions>
<insert>
/* Unrelevant code goes here */
...
...
/* End of unrelevant code */
public void AndroidThunkJava_startCamera()
{
surfaceTexture = new SurfaceTexture(10);
surfaceTexture.setDefaultBufferSize(preferredWidth, preferredHeight);
if (camera == null){
try {
camera = Camera.open();
} catch (RuntimeException exc) {
return;
}
}
try {
camera.setPreviewTexture(surfaceTexture);
} catch (IOException t) {
return;
}
Parameters cameraParam = camera.getParameters();
cameraParam.setPreviewFormat(ImageFormat.NV21);
cameraParam.setPreviewSize(preferredWidth, preferredHeight);
cameraParam.setPreviewFpsRange(preferredFPS, preferredFPS);
cameraParam.setFocusMode(Camera.Parameters.FOCUS_MODE_MACRO);
if (cameraParam.isVideoStabilizationSupported()) {
cameraParam.setVideoStabilization(false);
}
if (cameraParam.isAutoWhiteBalanceLockSupported()) {
cameraParam.setAutoWhiteBalanceLock(false);
}
camera.setParameters(cameraParam);
camera.setPreviewCallback(new PreviewCallback() {
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
int Height = camera.getParameters().getPreviewSize().height;
int Width = camera.getParameters().getPreviewSize().width;
// calling C++ function via JNI interface
processFrameData(Width, Height, data);
}
});
camera.startPreview();
}
public void AndroidThunkJava_stopCamera()
{
if (camera != null)
{
camera.stopPreview();
camera.release();
camera = null;
}
}
</insert>
</gameActivityClassAdditions>
<gameActivityOnPauseAdditions>
<insert>
AndroidThunkJava_stopCamera();
</insert>
</gameActivityOnPauseAdditions>
<gameActivityOnResumeAdditions>
<insert>
AndroidThunkJava_startCamera();
</insert>
</gameActivityOnResumeAdditions>
问题
相机每两次都正常。这意味着:
我打开应用程序,相机正在工作。我按下主页按钮(触发 onPause()
方法),然后切换回应用程序(触发 onResume()
方法)。再次按下主页按钮,然后切换回来 - 相机工作。以此类推,相机每隔一秒工作一次。
有人知道这个问题吗?这与 android.hardware.Camera
被弃用的事实有关吗?我使用的是 API 版本 19,因此无法使用更新的 android.hardware.camera2
.
这是我的 onStop 和 onResume 方法。我没有使用 onPause。它完美地工作:
@Override
protected void onResume() {
super.onResume();
if (mCamera == null) {
restartPreview();
}
}
@Override
public void onStop() {
// stop the preview
if (mCamera != null) {
stopCameraPreview();
mCamera.release();
mCamera = null;
}
super.onStop();
}
private void restartPreview() {
if (mCamera != null) {
stopCameraPreview();
mCamera.release();
mCamera = null;
}
getCamera(mCameraID);
startCameraPreview();
}
private void startCameraPreview() {
try {
mCamera.setPreviewDisplay(mSurfaceHolder);
mCamera.startPreview();
setSafeToTakePhoto(true);
setCameraFocusReady(true);
} catch (IOException e) {
Log.d("st", "Can't start camera preview due to IOException " + e);
e.printStackTrace();
}
}
private void stopCameraPreview() {
setSafeToTakePhoto(false);
setCameraFocusReady(false);
// Nulls out callbacks, stops face detection
mCamera.stopPreview();
mPreviewView.setCamera(null);
}
也许有些实现不等于你的,但我认为它对你有帮助。