Search code examples
javaandroidandroid-cameraxnexus6

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


Issue:

I am getting the following error:

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

when calling and instance method ProcessCameraProvider.bindToLifecycle(). See this in the context of the code below by searching for "------ Code Crashes Here --------------".

Question:

How do I prevent this error and subsequent crashing of the app? More specifically, how do I ensure the CameraSelector can return a camera instance for the Nexus 6?

Hypothesis

It appears there is something wrong with the CameraSelector used in this call. If I set a breakpoint on the bindToLifecycle line, and debug up to that point and add a watch for `cameraProvider.hasCamera(cameraSelector) it returns false. Maybe this is not intended to return true until the bindToLifecycle method has been called. If so, how can I verify the cameraSelector object has been created sucessfully (successfully meaning it points to an actual camera object)?

In the creation of the cameraSelector object, I use the requireLensFacing method in the builder, so it appears the Nexus 6 hardware does not tag anything with these LENS_FACING_BACK or LENS_FACING_FRONT and therefore does not return any camera instance? Do I understand this correctly?

I should note that this error did not occur when the exact same code was run on a Nexus 5, which is why I am inclined to think it is a hardware issue.

I also tried the LENS_FACING_FRONT int, but had the same error. If I remove the requireLensFacing build component altogether I get a different error:

java.util.NoSuchElementException

Code

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));
    }

}

Full logcat surrounding the 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$0$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

Full logcat surrounding the 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$0$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

Edit1:

Tested standard camera app on the Nexus 6 and found that it also crashed. This pointed to a HAL issue presented by a commenter. Restarted the Nexus 6 in an effort to fix the HAL. Now logcat presents a whole new set of errors, but I will save that for a seperate question if I cannot resolve them on my own.


Solution

  • With both LENS_FACING_FRONT and LENS_FACING_BACK resulting in a no available camera can be found, it seems as though no cameras on the device are available for use, this may be caused at times by a HAL crash, and might require a device reboot for the HAL to function correctly again.

    You should check the native camera app (or any other camera app for that matter) to see if they are working on the nexus 6 device. If they aren't, then you'll know the issue is in the camera HAL.