非法 ArgumentException:Nexus 6 的 CameraProcessProvider.bindToLifecycle 中的 "No available camera can be found"

Illegal ArgumentException: "No available camera can be found" in CameraProcessProvider.bindToLifecycle for Nexus 6

问题:

我收到以下错误:

java.lang.IllegalArgumentException: No available camera can be found.

调用和实例方法时ProcessCameraProvider.bindToLifecycle()。通过搜索“------ Code Crashes Here -------------”在下面的代码上下文中查看此内容。

问题:

如何防止此错误和随后的应用程序崩溃?更具体地说,我如何确保 CameraSelector 可以 return Nexus 6 的相机实例?

假设

这次调用中使用的 CameraSelector 似乎有问题。如果我在 bindToLifecycle 行上设置一个断点,并调试到那个点并添加一个监视`cameraProvider.hasCamera(cameraSelector) 它 returns false。在调用 bindToLifecycle 方法之前,这可能不会 return 为真。如果是这样,我如何验证 cameraSelector 对象是否已成功创建(成功意味着它指向一个实际的相机对象)?

在创建 cameraSelector 对象时,我在构建器中使用了 requireLensFacing 方法,因此看起来 Nexus 6 硬件没有用这些 LENS_FACING_BACK 或 LENS_FACING_FRONT 标记任何内容因此 return 没有任何相机实例?我理解正确吗?

我应该注意到,当完全相同的代码在 Nexus 5 上 运行 时,不会发生此错误,这就是为什么我倾向于认为这是一个硬件问题。

我也尝试了LENS_FACING_FRONT int,但有同样的错误。如果我完全删除 requireLensFacing 构建组件,我会得到一个不同的错误:

java.util.NoSuchElementException

代码

package jp.oist.cameraxapp;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.camera.core.Camera;
import androidx.camera.core.CameraSelector;
import androidx.camera.core.ImageAnalysis;
import androidx.camera.core.ImageCapture;
import androidx.camera.core.ImageProxy;
import androidx.camera.core.Preview;
import androidx.camera.lifecycle.ProcessCameraProvider;
import androidx.camera.view.PreviewView;
import androidx.core.content.ContextCompat;
import androidx.lifecycle.LifecycleOwner;

import android.os.Bundle;
import android.util.Log;
import android.util.Size;

import com.google.common.util.concurrent.ListenableFuture;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class MainActivity extends AppCompatActivity {

    private ListenableFuture<ProcessCameraProvider> cameraProviderFuture;
    private ExecutorService executor;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        executor = Executors.newSingleThreadExecutor();

        PreviewView previewView = findViewById(R.id.previewView);

        cameraProviderFuture = ProcessCameraProvider.getInstance(this);

        cameraProviderFuture.addListener(() -> {
            try {
                // Camera provider is now guaranteed to be available
                ProcessCameraProvider cameraProvider = cameraProviderFuture.get();

                // Set up the view finder use case to display camera preview
                Preview preview = new Preview.Builder().build();

                // Choose the camera by requiring a lens facing
                CameraSelector cameraSelector = new CameraSelector.Builder()
                        .requireLensFacing(CameraSelector.LENS_FACING_BACK)
                        .build();

                // Connect the preview use case to the previewView
                preview.setSurfaceProvider(
                        previewView.createSurfaceProvider());

                // Set up the capture use case to allow users to take photos
                ImageCapture imageCapture = new ImageCapture.Builder()
                        .setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
                        .build();

                ImageAnalysis imageAnalysis =
                        new ImageAnalysis.Builder()
                                .build();

                imageAnalysis.setAnalyzer(executor, new ImageAnalysis.Analyzer() {
                    @Override
                    public void analyze(@NonNull ImageProxy image) {
                        int rotationDegrees = image.getImageInfo().getRotationDegrees();
                        Log.i("CameraXApp3", "Image Analyzed");
                        image.close();
                    }
                });

                // Attach use cases to the camera with the same lifecycle owner
                // ------ Code Crashes Here --------------
                Camera camera = cameraProvider.bindToLifecycle(
                        ((LifecycleOwner) this),
                        cameraSelector,
                        preview,
                        imageCapture);

            } catch (InterruptedException | ExecutionException e) {
                // Currently no exceptions thrown. cameraProviderFuture.get() should
                // not block since the listener is being called, so no need to
                // handle InterruptedException.
            }
        }, ContextCompat.getMainExecutor(this));
    }

}

完整 logcat 围绕 IllegalArgumentException

2020-07-29 13:31:57.954 7345-7345/? E/Finsky: [2] VerifyPerSourceInstallationConsentInstallTask.b(2): Package name null is not an installed package
2020-07-29 13:31:59.660 462-877/? E/cutils: Failed to open(/data/misc/profiles/cur/0/jp.oist.cameraxapp/primary.prof): No such file or directory
2020-07-29 13:31:59.660 462-877/? E/installed: Failed to prepare /data/misc/profiles/cur/0/jp.oist.cameraxapp/primary.prof: No such file or directory
2020-07-29 13:31:59.661 729-756/? E/ArtManagerService: Failed to prepare profile for jp.oist.cameraxapp:/data/app/jp.oist.cameraxapp-HSYslGAf7kOyD4tEcVKEkw==/base.apk
2020-07-29 13:32:00.305 462-877/? E/installd: Failed to delete /data/app/vmdl841803495.tmp: No such file or directory
2020-07-29 13:32:00.846 729-729/? E/LoadedApk: Unable to instantiate appComponentFactory
    java.lang.ClassNotFoundException: Didn't find class "androidx.core.app.CoreComponentFactory" on path: DexPathList[[],nativeLibraryDirectories=[/data/app/sk.baka.aedict3-FT98hpKmmu7AEcH7jl4_Lw==/lib/arm, /data/app/sk.baka.aedict3-FT98hpKmmu7AEcH7jl4_Lw==/base.apk!/lib/armeabi-v7a, /system/lib, /system/vendor/lib]]
        at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:134)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
        at android.app.LoadedApk.createAppFactory(LoadedApk.java:226)
        at android.app.LoadedApk.updateApplicationInfo(LoadedApk.java:338)
        at android.app.ActivityThread.handleDispatchPackageBroadcast(ActivityThread.java:5441)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1740)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:193)
        at com.android.server.SystemServer.run(SystemServer.java:500)
        at com.android.server.SystemServer.main(SystemServer.java:322)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:495)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:839)
2020-07-29 13:32:00.847 729-729/? E/LoadedApk: Unable to instantiate appComponentFactory
    java.lang.ClassNotFoundException: Didn't find class "androidx.core.app.CoreComponentFactory" on path: DexPathList[[],nativeLibraryDirectories=[/data/app/sk.baka.aedict3-FT98hpKmmu7AEcH7jl4_Lw==/lib/arm, /data/app/sk.baka.aedict3-FT98hpKmmu7AEcH7jl4_Lw==/base.apk!/lib/armeabi-v7a, /system/lib, /system/vendor/lib]]
        at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:134)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
        at android.app.LoadedApk.createAppFactory(LoadedApk.java:226)
        at android.app.LoadedApk.updateApplicationInfo(LoadedApk.java:338)
        at android.app.ActivityThread.handleDispatchPackageBroadcast(ActivityThread.java:5441)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1740)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:193)
        at com.android.server.SystemServer.run(SystemServer.java:500)
        at com.android.server.SystemServer.main(SystemServer.java:322)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:495)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:839)
2020-07-29 13:32:02.251 11105-11105/jp.oist.cameraxapp E/AndroidRuntime: FATAL EXCEPTION: main
    Process: jp.oist.cameraxapp, PID: 11105
    java.lang.IllegalArgumentException: No available camera can be found.
        at androidx.camera.core.CameraSelector.filter(CameraSelector.java:100)
        at androidx.camera.lifecycle.ProcessCameraProvider.bindToLifecycle(ProcessCameraProvider.java:389)
        at androidx.camera.lifecycle.ProcessCameraProvider.bindToLifecycle(ProcessCameraProvider.java:275)
        at jp.oist.cameraxapp.MainActivity.lambda$onCreate[=13=]$MainActivity(MainActivity.java:80)
        at jp.oist.cameraxapp.-$$Lambda$MainActivity$N0aObN0KVyRMowRsss_pmN8BZ44.run(Unknown Source:4)
        at android.os.Handler.handleCallback(Handler.java:873)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6698)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:495)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:859)
2020-07-29 13:32:02.367 2459-9800/ch.deletescape.lawnchair.ci E/pe.lawnchair.c: Failed to open APK '/data/app/jp.oist.cameraxapp-bhz9WJnVll-cJYJKM51yGg==/base.apk' I/O error
2020-07-29 13:32:02.368 2459-9800/ch.deletescape.lawnchair.ci E/ResourcesManager: failed to add asset path /data/app/jp.oist.cameraxapp-bhz9WJnVll-cJYJKM51yGg==/base.apk

完整 logcat 围绕 NoSuchElementException

2020-07-29 13:31:22.712 10962-10962/jp.oist.cameraxapp E/AndroidRuntime: FATAL EXCEPTION: main
    Process: jp.oist.cameraxapp, PID: 10962
    java.util.NoSuchElementException
        at java.util.LinkedHashMap$LinkedHashIterator.nextNode(LinkedHashMap.java:759)
        at java.util.LinkedHashMap$LinkedKeyIterator.next(LinkedHashMap.java:780)
        at androidx.camera.lifecycle.ProcessCameraProvider.bindToLifecycle(ProcessCameraProvider.java:415)
        at androidx.camera.lifecycle.ProcessCameraProvider.bindToLifecycle(ProcessCameraProvider.java:275)
        at jp.oist.cameraxapp.MainActivity.lambda$onCreate[=14=]$MainActivity(MainActivity.java:79)
        at jp.oist.cameraxapp.-$$Lambda$MainActivity$N0aObN0KVyRMowRsss_pmN8BZ44.run(Unknown Source:4)
        at android.os.Handler.handleCallback(Handler.java:873)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6698)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:495)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:859)
2020-07-29 13:31:22.758 382-382/? E/lowmemorykiller: Error writing /proc/10962/oom_score_adj; errno=22

编辑 1:

在 Nexus 6 上测试了标准相机应用程序,发现它也崩溃了。这指出了评论者提出的 HAL 问题。重新启动 Nexus 6 以修复 HAL。现在 logcat 出现了一组全新的错误,但如果我无法自行解决它们,我会将其保存为一个单独的问题。

由于LENS_FACING_FRONTLENS_FACING_BACK都导致找不到可用的摄像头,似乎设备上没有可用的摄像头,这有时可能是由于HAL 崩溃,可能需要重新启动设备才能使 HAL 再次正常运行。

您应该检查本机相机应用程序(或与此相关的任何其他相机应用程序),看看它们是否在 nexus 6 设备上工作。如果不是,那么您就会知道问题出在相机 HAL 中。