相机错误“无法连接到相机”,或在某些手机上出现错误“相机正在被其他应用程序使用”

10

我已经实现了使用Android MediaRecorder在后台记录音频,如果正在进行音频录制并且用户打开本机相机录制视频,它会出现

相机错误“无法连接到相机”

或者在一些手机上,错误信息显示为

您的相机正被另一个应用程序使用

enter image description here

如果我停止mediarecorder,那么本机相机视频录制就可以正常工作。我搜索了事件以了解何时相机将开始录制视频,然后在我的应用中停止mediarecorder,我找到了带有过滤器的BroadcastReceiver

        <receiver android:name=".receiver.CameraReceiver">
            <intent-filter android:priority="10000">
            <action android:name="android.Medintent.action.CAMERA_BUTTON" />
            <action android:name="android.hardware.action.NEW_PICTURE" />
            <action android:name="android.hardware.action.NEW_VIDEO" />
            <category android:name="android.intent.category.DEFAULT" />
            <data android:mimeType="image/*" />
            <data android:mimeType="video/*" />
        </intent-filter>
    </receiver>

NEW_VIDEONEW_PICTURE事件在照片或视频被拍摄并保存到目录中时触发。有人知道如何解决这个问题吗?我想在我的应用程序中了解本机/相机应用程序即将录制视频的事件。谢谢提前。

2个回答

0

CameraManager.AvailabilityCallback 提供了 onCameraAvailable(String cameraId) 方法来检测相机是否可用。 https://developer.android.com/reference/android/hardware/camera2/CameraManager.AvailabilityCallback.html

获取所有相机 ID 的方法与上述相同,如 @GAGAN 所示。

CameraManager camManager = (CameraManager) mContext.getSystemService(Context.CAMERA_SERVICE);
        // Usually front mCamera is at position 0.
        try {
            cameraId = camManager.getCameraIdList()[0];
        }  catch (CameraAccessException e) {
            Log.e(TAG, Log.getStackTraceString(e));
            Log.cat("Error: ", e.getReason() + "");
            if (e.CAMERA_DISABLED) { /* ENABLE CAMERA */ }
            else if ( /* ... you can go to the link below to do various logic */ ) {
                //...
            }
            else { /* do nothing */ }
        }

https://developer.android.com/reference/android/hardware/camera2/CameraAccessException.html#CAMERA_IN_USE

注意:在其他应用程序使用您的相机硬件之前,它们正在有目的地使用它们。因此,在这些应用程序不释放您的硬件之前,您无法使用它,这是明确的。您无法知道这些应用程序是否实际需要相机。我们相信进程在需要时会保留硬件。

但是,我们可以设置侦听器以在相机可用(空闲)时立即使用它。

CameraManager.AvailabilityCallback availabilityCallback = new CameraManager.AvailabilityCallback() {
    @Override 
    public void onCameraAvailable(String cameraId) {
        // your further stuffs. You must put all of your camera related logic here. 
    }

    public void onCameraUnavailable(String cameraId) {
        //you can logcat camera not available 
    }
};

使用 CameraManager.AvailabilityCallback 抽象类的时候,当您实例化对象时,您可以进行匿名实例化并实现回调函数,例如 onCameraAvailable(),它实际上是从相机 Observer 获取的一个 listener

答案:如果您将相机处理命令放在 onCameraAvailable() 回调函数中,我保证您不会遇到您所显示的错误。

如果相机在后台被其他应用程序使用,这意味着那些其他应用程序有点问题,因为相机需要前台预览;即使他们完成了相机的使用,他们也没有释放相机。没有人在后台使用相机。即使在这种情况下,您也不应该强制杀死相机进程,因为可能会发生内存泄漏。因为您不知道其他进程如何使用相机。


兄弟,我现在正在使用MediaRecorder,如果有人打开本机相机应用程序录制视频,则该应用程序会出现错误,无法连接到相机。 - Naveed Ahmad
@NaveedAhmad 为什么不展示你的MediaRecorder实现代码呢? - Uddhav P. Gautam
在调用 yourMediaPlayer.pause() 方法之前,您必须先调用 yourCamera.unlock() 方法,并在 yourMediaPlayer.resume() 方法之后调用 yourCamera.lock() 方法。我建议您将 yourCamera.unlock()yourCamera.release() 方法放在 try-catch 块中,以便在进行进一步操作时可以/不能锁定/解锁。 - Uddhav P. Gautam
@NaveedAhmad,我正在等待你的代码,这样我才能帮助你。 - Uddhav P. Gautam
我正在我的应用程序中使用MediaRecorder录制音频时检查相机,我只需要知道Android开始录制视频的事件,到目前为止我还没有找到任何相关信息。 - Naveed Ahmad

0

我也遇到了同样的问题。 一旦相机资源被应用程序使用,除非它被释放,否则您无法在其他应用程序或服务中使用它们。 如果任何服务正在使用相机资源,除非它释放相机硬件,否则我们无法使用它。 您可以使用以下代码双重检查是否正在使用相机硬件:-

 private boolean isCameraInUse() {
    Log.v(TAG, "isCameraInUse()");
    boolean isCameraInUse = false;
    if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)//Use Camera Api for Version Code < 23 and mCamera manager above it.
    {
        String cameraId = null;
        CameraManager camManager = (CameraManager) mContext.getSystemService(Context.CAMERA_SERVICE);
        // Usually front mCamera is at 0 position.
        try {
            cameraId = camManager.getCameraIdList()[0];
        } catch (CameraAccessException e) {
            Log.e(TAG, Log.getStackTraceString(e));
            isCameraInUse = true;
        }
        try {
            camManager.setTorchMode(cameraId, true);
            camManager.setTorchMode(cameraId, false);
        } catch (CameraAccessException e) {
            Log.e(TAG, Log.getStackTraceString(e));
            isCameraInUse = true;
        }
    } else {
        Camera c = null;
        try {
            c = Camera.open();
        } catch (RuntimeException e) {
            Log.e(TAG, Log.getStackTraceString(e));
            turnFlashOff(mContext);
            isCameraInUse = true;
        } finally {
            if (c != null) c.release();
        }
    }
    return isCameraInUse;
}

是的,你说得对,但我不想知道相机是否正在使用,我想知道其他应用程序是否需要设备相机,以便我停止录制器。感谢您抽出时间来研究此问题。 - Naveed Ahmad
很遗憾,我不认为有任何方法可以检测到其他应用程序是否想要使用相机硬件资源。 - GAGAN BHATIA
如果这个API不可用,那么我们会向谷歌的开发者提出请求,让他们将这个功能添加到他们的SDK中。无所不能 @GAGAN - Naveed Ahmad
@NaveedAhmad,在进程不释放资源之前,这意味着它需要该资源。 - Uddhav P. Gautam
@UddhavGautam 感谢您的信息,基本上如果不知道另一个应用程序需要哪些资源,我们就无法知道何时发布。请求应用程序应该有一个广播接收器消息,其中包含持有该资源的信息。 - Naveed Ahmad

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接