相机错误“无法连接到相机”或在某些手机中出现错误“相机正在被另一个应用程序使用”

Posted

技术标签:

【中文标题】相机错误“无法连接到相机”或在某些手机中出现错误“相机正在被另一个应用程序使用”【英文标题】:Camera Error "Can't Connect to the Camera" or in some phones the error appear "Camera is using by another app" 【发布时间】:2018-01-11 00:19:22 【问题描述】:

我已经实现了使用 android MediaRecorder 在后台录制音频

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

或在某些手机上,错误显示为

您的相机正在被其他应用程序使用

如果我停止 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 事件在图片或视频被捕获并保存在目录中时触发。任何人都知道如何解决这个问题?我想在我的应用程序中知道本机/相机应用程序何时录制视频的事件。提前致谢

【问题讨论】:

【参考方案1】:

即使我也有同样的问题。 一旦相机资源被应用程序使用,直到它被释放,您可以在其他应用程序甚至服务中使用它们。 如果任何服务正在使用相机资源,在它释放之前我们不能使用相机硬件。 您可以使用此代码仔细检查是否正在使用相机硬件:-

 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;

【讨论】:

是的,你是对的,但我不想知道相机是否在使用中,我想知道另一个应用程序是否需要设备相机,所以我停止了录像机。感谢您抽出宝贵时间调查此问题。 不幸的是,我不认为是否有任何方法可以检测任何其他应用程序是否需要相机硬件资源。 没有什么是不可能的@GAGAN 如果这个 API 不可用,那么我们将把这个东西放在谷歌人面前,将这个东西添加到他们的 SDK 中 @NaveedAhmad,直到进程不释放资源,这意味着它需要该资源。 @UddhavGautam 感谢您的消息,基本上不知道另一个应用程序需要哪个资源,我们不知道何时释放。应该有一个广播接收器消息用于请求拥有该资源的应用程序。【参考方案2】:

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吧?现在如果有人打开本机相机应用程序录制视频,那么该应用程序将出现错误无法连接到相机。 @NaveedAhmad 你为什么不展示你的 MediaRecorder 实现代码? 您必须调用yourCamera.unlock() 之前 yourMediaPlayer.pause() method,并在yourMediaPlayer.resume() 之后调用yourCamera.lock()。我建议你将 yourCamera.unlock() 和 yourCamera.relase() 放入 try-catch 块中,这样你就可以/不能锁定/解锁,然后你就不用做进一步的操作了。 @NaveedAhmad,我正在等待您的代码,以便为您提供帮助。 我在我的应用程序中使用 MediaRecorder 录制音频时正在检查相机,我只需要知道 android 启动视频时的事件,到目前为止我没有发现任何关于此的内容。

以上是关于相机错误“无法连接到相机”或在某些手机中出现错误“相机正在被另一个应用程序使用”的主要内容,如果未能解决你的问题,请参考以下文章

Tensorflow android demo出错了。无法连接到相机服务

错误:无法连接到相机服务@Android marshmallow

错误:无法连接到相机服务@Android marshmallow

无法连接到手电筒小部件中的相机服务

RuntimeException:无法连接到相机服务?

如何修复 Android 模拟器中的“无法连接到相机服务”异常