低于Android Lollipop版本的设备上的CameraManager

5
我遇到一个问题,我同时使用相机(低于棒棒糖的设备)和CameraManager类(棒棒糖及以上的设备)。运行低于棒棒糖的设备会崩溃,我认为这是由于
import android.hardware.camera2.CameraManager;

部分。我该如何制作这个?

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

        }
    }   

}

如果import部分会导致低于Lollipop版本的设备崩溃,该怎么解决?

感谢任何帮助和建议!

编辑: 上面添加了整个类。 Logcat输出

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第121行:FlashController fc = new FlashController(this);

该行代码创建了一个名为fc的FlashController对象,并将当前活动作为参数传递给它。FlashController是一个类,可以控制设备的闪光灯。

1
导入不会使您的应用程序崩溃。请包含您的logcat。 - ianhanniballake
import语句不是可执行语句,不能直接导致崩溃。请使用LogCat来检查与您的崩溃相关的Java堆栈跟踪:https://dev59.com/iGAg5IYBdhLWcg3wpMSz 如果您不理解堆栈跟踪,请将其粘贴到您的问题中,并指出代码片段中哪些代码行对应于堆栈跟踪中引用的行。 - CommonsWare
@ianhanniballake 已添加日志记录。 - Araw
你正在测试哪个设备/ API 版本? - ianhanniballake
@ianhanniballake 三星Galaxy Tab 2/Android 4.2.2...它有一个相机但没有闪光灯,所以我认为它崩溃是因为这个原因,但我已经在函数中添加了一个检查来检查它是否支持闪光灯功能(代码中的_is_supported布尔值),如果不支持就应该返回。但仍然没有运气。 - Araw
显示剩余2条评论
2个回答

0

将您的类分为两个部分:一个用于API2,另一个用于API1。首先检查安装的Android版本,然后运行适当的类。 像这样做:

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

这是我在这个项目中的解决方案。


0

我曾经遇到过类似的问题。唯一的区别是我将SDK版本更新为Android M(API 23)。

  1. 首先将您的SDK更新到API 23。

  2. 然后添加检查:Build.VERSION.SDK_INT >= Build.VERSION_CODES.M,而不是Lollipop版本。

  3. 然后,您可以尝试以下代码适用于Android M版本及以上:

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

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

}

希望这能有所帮助。

我尝试过这个,但没有成功。目前我正在使用反射来避免在Lollipop及以下版本中崩溃,但如果可能的话,我想避免使用它。 - argenkiwi

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