5

I am facing a problem where I am using both the Camera (lower than Lollipop devices) and CameraManager class (Lollipop and above devices).

The devices that run lower than Lollipop crashes, I believe this is because of the

import android.hardware.camera2.CameraManager;

part. How can I make this

package com.example.DeviceCommands;

import android.annotation.TargetApi;
import android.content.Context;
import android.content.pm.PackageManager;
import android.hardware.Camera;
import android.hardware.Camera.AutoFocusCallback;
import android.hardware.Camera.Parameters;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraManager;
import android.os.Build;

public class FlashController
{
    Context _context;
    boolean _is_supported = false;
    boolean _enabled = false;
    Object _camera;

    @TargetApi(Build.VERSION_CODES.L) public FlashController(Context context)
    {
        if (context.getPackageManager().hasSystemFeature(PackageManager
            .FEATURE_CAMERA_FLASH))
        {
            _context = context;
            _is_supported = true;

            if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP)
            {
                Camera camera = Camera.open();

                if (camera == null)
                {
                    _is_supported = false;
                    System.out.println("NOT SUPPORTED!");
                    return;
                }

                _camera = camera;
            }
            else
            {
                CameraManager camera = (CameraManager) _context.getSystemService(Context.CAMERA_SERVICE);
                _camera = camera;
            }
        }
    }


    @TargetApi(Build.VERSION_CODES.L) public void enableFlashLight()
    {
        if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP)
        {
            Camera camera = (Camera) _camera;
            Camera.Parameters parameters = camera.getParameters();

            if(!parameters.getFlashMode().equals(android.hardware
                                        .Camera.Parameters.FLASH_MODE_TORCH)
                                        && !_enabled)
            {  
                Parameters params = camera.getParameters();
                params.setFlashMode(Parameters.FLASH_MODE_TORCH);
                camera.setParameters(params);
                camera.startPreview();
                _enabled = true;
                camera.autoFocus(new AutoFocusCallback()
                {
                    public void onAutoFocus(boolean success, Camera camera)
                    {

                    }
                });
            }
        }
        else
        {
            //CameraManager manager =(CameraManager) _context.getSystemService(Context.CAMERA_SERVICE);

            try
            {
                CameraManager camera = (CameraManager) _camera;

                for(int i = 0; i < camera.getCameraIdList().length; i++)
                {
                    System.out.println("Camera=" + camera.getCameraCharacteristics(
                                                   camera.getCameraIdList()[i]));
                }
            }
            catch (CameraAccessException e)
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    public void disableFlashLight()
    {
        if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP)
        {
            Camera cam = Camera.open();
            Camera.Parameters parameters = cam.getParameters();

            if(parameters.getFlashMode().equals(android.hardware
                                        .Camera.Parameters.FLASH_MODE_TORCH))
            {
                parameters.setFlashMode(Parameters.FLASH_MODE_OFF);
                cam.setParameters(parameters);
                cam.release();
            }

        }
    }   

}

work if the import part will make devices running lower than Lollipop crash?

Thanks for any help and advice!

EDIT: Added the whole class above. Logcat output

06-09 19:44:30.219: E/ViewRootImpl(956): sendUserActionEvent() mView == null
06-09 19:44:31.360: E/dalvikvm(956): Could not find class 'android.hardware.camera2.CameraManager', referenced from method com.example.DeviceCommands.FlashController.<init>
06-09 19:44:31.360: W/dalvikvm(956): VFY: unable to resolve check-cast 122 (Landroid/hardware/camera2/CameraManager;) in Lcom/example/DeviceCommands/FlashController;
06-09 19:44:31.360: D/dalvikvm(956): VFY: replacing opcode 0x1f at 0x003a
06-09 19:44:31.367: E/dalvikvm(956): Could not find class 'android.hardware.camera2.CameraManager', referenced from method com.example.DeviceCommands.FlashController.enableFlashLight
06-09 19:44:31.367: W/dalvikvm(956): VFY: unable to resolve check-cast 122 (Landroid/hardware/camera2/CameraManager;) in Lcom/example/DeviceCommands/FlashController;
06-09 19:44:31.367: D/dalvikvm(956): VFY: replacing opcode 0x1f at 0x0040
06-09 19:44:31.367: W/dalvikvm(956): VFY: unable to resolve exception class 120 (Landroid/hardware/camera2/CameraAccessException;)
06-09 19:44:31.367: W/dalvikvm(956): VFY: unable to find exception handler at addr 0x6b
06-09 19:44:31.367: W/dalvikvm(956): VFY:  rejected Lcom/example/DeviceCommands/FlashController;.enableFlashLight ()V
06-09 19:44:31.367: W/dalvikvm(956): VFY:  rejecting opcode 0x0d at 0x006b
06-09 19:44:31.367: W/dalvikvm(956): VFY:  rejected Lcom/example/DeviceCommands/FlashController;.enableFlashLight ()V
06-09 19:44:31.367: W/dalvikvm(956): Verifier rejected class Lcom/example/DeviceCommands/FlashController;
06-09 19:44:31.367: D/AndroidRuntime(956): Shutting down VM
06-09 19:44:31.367: W/dalvikvm(956): threadid=1: thread exiting with uncaught exception (group=0x4100d930)
06-09 19:44:31.375: E/AndroidRuntime(956): FATAL EXCEPTION: main
06-09 19:44:31.375: E/AndroidRuntime(956): java.lang.VerifyError: com/example/DeviceCommands/FlashController
06-09 19:44:31.375: E/AndroidRuntime(956):  at com.example.babymonitorer.MainActivity.onClick(MainActivity.java:121)
06-09 19:44:31.375: E/AndroidRuntime(956):  at android.view.View.performClick(View.java:4421)
06-09 19:44:31.375: E/AndroidRuntime(956):  at android.view.View$PerformClick.run(View.java:18190)
06-09 19:44:31.375: E/AndroidRuntime(956):  at android.os.Handler.handleCallback(Handler.java:725)
06-09 19:44:31.375: E/AndroidRuntime(956):  at android.os.Handler.dispatchMessage(Handler.java:92)
06-09 19:44:31.375: E/AndroidRuntime(956):  at android.os.Looper.loop(Looper.java:175)
06-09 19:44:31.375: E/AndroidRuntime(956):  at android.app.ActivityThread.main(ActivityThread.java:5279)
06-09 19:44:31.375: E/AndroidRuntime(956):  at java.lang.reflect.Method.invokeNative(Native Method)
06-09 19:44:31.375: E/AndroidRuntime(956):  at java.lang.reflect.Method.invoke(Method.java:511)
06-09 19:44:31.375: E/AndroidRuntime(956):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102)
06-09 19:44:31.375: E/AndroidRuntime(956):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869)
06-09 19:44:31.375: E/AndroidRuntime(956):  at dalvik.system.NativeStart.main(Native Method)

MainActivity line 121: FlashController fc = new FlashController(this);

Araw
  • 2,410
  • 3
  • 29
  • 57
  • 1
    The import does not make your app crash. Include your logcat. – ianhanniballake Jun 09 '15 at 17:11
  • `import` statements are not executable statements and cannot directly cause a crash. Use LogCat to examine the Java stack trace associated with your crash: https://stackoverflow.com/questions/23353173/unfortunately-myapp-has-stopped-how-can-i-solve-this If you do not understand the stack trace, paste it into your question and indicate what lines of code from your code snippet correspond to lines referenced in the stack trace. – CommonsWare Jun 09 '15 at 17:12
  • @ianhanniballake Logcat added. – Araw Jun 09 '15 at 17:26
  • What device/API version are you testing this on? – ianhanniballake Jun 09 '15 at 18:35
  • @ianhanniballake Samsung Galaxy Tab 2/Android 4.2.2...It has a camera but not flash so I thought it crashed because of that but I have added a check in the functions to check if it supports the flash feature (_is_supported boolean in the code above) and it should return if that is not the case. But still no luck. – Araw Jun 09 '15 at 18:45
  • I also get a similar warning message: `W/dalvikvm: VFY: unable to resolve virtual method 1216: Landroid/hardware/camera2/CameraManager;.setTorchMode (Ljava/lang/String;Z)V` – argenkiwi Nov 30 '15 at 21:13
  • I am running into the same issue on a Samsung Galaxy S3 running 4.3, however a Note 2 with 4.4 works fine. Samsung bug? just not sure how to get around it.. – xceph Jun 15 '16 at 12:58

2 Answers2

0

I have faced similar issue. The only difference was I have updated the SDK version to Android M (API 23).

  1. First update your SDK to API 23.

  2. Then add check for: Build.VERSION.SDK_INT >= Build.VERSION_CODES.M instead of Lollipop version.

  3. Then possibly you can try below code for Android M version and above:

if (context.checkSelfPermission(Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {

    CameraManager camera = (CameraManager) _context.getSystemService(Context.CAMERA_SERVICE);

}

Hope this helps.

gre_gor
  • 6,669
  • 9
  • 47
  • 52
udai
  • 3,723
  • 4
  • 16
  • 20
  • I tried this with no luck. I am currently using reflection to avoid crashes in Lollipop and bellow, but I'd like to avoid it if possible. – argenkiwi Nov 30 '15 at 22:39
0

Just divide your class into two: one for API2, another for API1. First check what android version installed and then run appropriate class. Do it like this:

    // Start Camera capture Image display
public void intentStartCamera() {
    if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        Intent myIntent = new Intent(CaptureDetailsActivity.this, CaptureActivityCAPI2.class);
        startActivityForResult(myIntent, OPEN_CAMERA_REQUEST);
    } else {
        Intent myIntent = new Intent(CaptureDetailsActivity.this, CaptureActivityCAPI1.class);
        startActivityForResult(myIntent, OPEN_CAMERA_REQUEST);
    }
}

It's my solution in such project.

RevakoOA
  • 601
  • 1
  • 9
  • 20