Java Android使用运行时策略来支持不同的API级别?

Java Android使用运行时策略来支持不同的API级别?,java,android,Java,Android,我有一个小功能。打开手电筒并保持打开状态,直到用户将其从我的应用程序关闭或我的应用程序退出。使用: params = camera.getParameters(); if (params.getFlashMode().equals(Parameters.FLASH_MODE_TORCH)) { isFlashOn = true; return; }

我有一个小功能。打开手电筒并保持打开状态,直到用户将其从我的应用程序关闭或我的应用程序退出。使用:

            params = camera.getParameters();
            if (params.getFlashMode().equals(Parameters.FLASH_MODE_TORCH)) {
                isFlashOn = true;
                return;
            }
            params.setFlashMode(Parameters.FLASH_MODE_TORCH);
            camera.setParameters(params);
            camera.startPreview();
并关闭:

            if (params.getFlashMode().equals(Parameters.FLASH_MODE_OFF)) {
                isFlashOn = false;
                return;
            }
            params.setFlashMode(Parameters.FLASH_MODE_OFF);
            camera.setParameters(params);
            camera.stopPreview();
但我注意到,这不是很稳健。第一次工作很好,但之后(特别是在我的API Levele 22手机上)可能无法工作。我想用android.hardware.camera2作为测试工具 计划使用if(android.os.Build.VERSION.SDK_INT>20)和策略(一个由两个类实现的基本接口,一个使用旧API,另一个使用新的camera2 API)


这在所有设备上都是安全的吗?我看到我们可以为android类这样做,但我们自己的类也可以吗?或者是否有设备扫描我们所有的代码,如果它有引用它不知道的API的代码,就会拒绝它

我不想做两个APK,因为它是一个小功能

我确保flash可以像这样使用,并没有在所有设备上测试,但在Genymotion应用程序的模拟器中并没有崩溃

public boolean torchInit() {
    try {
        PackageManager pm = app.getPackageManager();
        // First check if device supports flashlight
        boolean hasFlash = pm.hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
        if (!hasFlash) {
            Toast.makeText(app, "Flash not found or can\'t get hold of it. No torch", Toast.LENGTH_LONG).show();
            return false;
        }
        camera = Camera.open();
        Camera.Parameters params = camera.getParameters();
        Log.i(LogId, "camera params flash: " + params.getFlashMode());
        return true;
    } catch (Throwable e) {
        Log.e(LogId, "cameraFlashSetup " + e, e);
        Toast.makeText(app, "Flash error, no torch. Description : " + e, Toast.LENGTH_LONG).show();
        camera = null;
    }
    return false;
}
在两个类之间更改的闪存接口为:

public abstract class TorchInterface  {

protected AppCompatActivity app;

public void init(AppCompatActivity ap){
    app = ap;
}

public abstract boolean torchInit();

public boolean torchReInit(){
    return torchInit();//if re init is not different than init
}

public abstract boolean torchOn();

public abstract boolean torchOff();
}

更新:新代码有效,但仅当我:

 mBuilder = camera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
而不是:

mBuilder = camera.createCaptureRequest(CameraDevice.TEMPLATE_MANUAL);
但一旦启动应用程序,就会立即打开flash。我本来打算扔掉它,但后来在我的Camera2Impl上意识到我可以:

public boolean torchInit() {
    //do nothing on usual init that app calls on create
    return true;
}
并改为在手电筒上进行初始(闪光):

Android设备不会“扫描”代码——编译器会。因此,我看不出你的想法有任何问题。相反,使用策略模式比在所有代码中使用
if-else
要好得多

按照这些思路应该可以做到:

if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
    mFlashlightStrategy = new PostLollipopStrategy();
} else {
    mFlashlightStrategy = new PreLollipopStrategy();
}

这在所有设备上都安全吗

你为什么不检查一下闪光灯是否可用呢

context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);

如果有闪光灯,则返回true,如果没有,则返回false。您可以在true块中编写进一步的代码。

这在所有设备上都安全吗?简短回答,不,不是所有的相机都有闪光灯,一些Android版本的棒棒糖有一个错误,几秒钟后闪光灯打开,导致手机重新启动,电池耗尽。由O编写的代码P假设他们所有人都有,如果安装到没有flash的设备上,这可能会适得其反,在这种情况下,我看不到优雅的操作。@t0mm13b感谢棒棒糖提醒。在我的设备上,这不会发生,但我会添加一个警告。我的应用程序使用屏幕作为指示灯,flash是可选的op:cool,some nexus 5/5x had棒棒糖上的问题。使用屏幕作为备用灯的想法很好,只需确保释放唤醒锁,不要让少数android用户在看到电池电量流向时感到不安;)@t0mm13b是的,在停止和暂停时释放唤醒锁。我的设备确实有问题。我不知道为什么我说它没有。一厢情愿。可能在未来的设备上工作,如果我只在用户打开flash时初始化,则工作。停止和暂停时是否需要停止闪烁。如果应用程序挂起/在后台,闪光灯会亮起是的,已经这样做了(更新的回答:如果没有,我的相机变量为空,我检查是否为空)。更担心的是同一应用程序中的新旧代码。在检查之前,您必须获得照相机/闪光灯的运行时权限,否则在版本6+中会出现空指针异常。在较低版本中,代码无关紧要,它可以正常运行。是的,我的意思是编译器在进行预检查时会在android上抛出异常。我知道它不适用于网络应用程序,我对devcies感到好奇,因为它们更严格。不管怎么说,到底要做什么
context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);