2016-05-25 36 views
4

我有一個小功能。打開手電筒並保持開啓,直到用戶將其從我的應用程序中關閉或我的應用程序退出。使用:Android使用運行時策略來支持不同的API級別?

  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 levle 22手機上)可能無法正常工作。我正在考慮使用android.hardware.camera2測試suggested here 計劃使用if(android.os.Build.VERSION.SDK_INT> 20)和一個策略(一個基本接口由兩個類實現,一個使用舊的API和一個使用舊的API新的camera2 API

這是所有設備上的安全嗎?我看到我們可以爲android類做到這一點,但它也適用於我們自己的類嗎?還是有設備掃描我們所有的代碼,並拒絕它,如果它是指API,它不知道密碼的?

我不希望有兩個的APK作爲它的一個小功能。

我要確保閃存可用這樣的,在沒有測試但在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; 
} 

Flash界面的兩個類之間改變的是:

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

但是,只要初始化應用程序就會打開閃光燈。我打算辭職不幹了,後來意識到我的Camera2Impl我可以:

public boolean torchInit() { 
    //do nothing on usual init that app calls on create 
    return true; 
} 

,而是做火炬手中的init(閃爍):

public boolean torchOn() { 
     //if not in it, try first 3 times 
     if(mBuilder == null || mSession == null){ 
      if(firstFewTimesTorchOn > 0){ 
       firstFewTimesTorchOn--; 
       torchInit2(); 
       try{ 
        Thread.sleep(150); 
       }catch(Exception e){} 
       if(mBuilder == null || mSession == null) { 
        return false; 
       } 
      } 
     } 
     try { 
      mBuilder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_TORCH);//and etc 
+1

*這是所有設備上的安全嗎?*簡短的回答,不,不是所有的相機都會有閃光燈,一些Android版本的棒棒糖,有一個閃光燈在幾秒鐘後閃動,導致手機重啓,電池電量耗盡。由OP編寫的代碼假設他們都會擁有它,如果安裝到沒有閃存的設備上,這可能會適得其反,如果在這種情況下我看不到優雅的處理方式。 – t0mm13b

+0

@ t0mm13b感謝棒棒糖頭。在我的設備上沒有發生,但我會添加警告。我的應用程序使用屏幕作爲燈光和閃光燈是可選 – tgkprog

+0

OP:很酷,一些nexus 5/5x在棒棒糖上有這個問題。善於思考使用屏幕作爲後備燈時,只需確保釋放喚醒鎖,不想讓幾個android用戶在他們看到電池電量消耗的位置時感到不安;) – t0mm13b

回答

2

Android設備沒有「掃描」代碼 - 編譯器。因此,我認爲你的想法沒有任何問題。相反 - 使用戰略模式是更好的,然後if-else遍佈的代碼。

沿着這些線路的東西應該工作:

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

是的,我的意思是編譯器在執行預檢時會在android上拋出異常。我知道它不適用於網絡應用程序,因爲他們對設計更爲嚴格而感到疑惑。無論如何與這 – tgkprog

2

這是安全上的所有設備?

爲什麼不放一個檢查閃光燈是否可用。

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

如果閃存可用,則返回true,否則返回false。你可以在你的代碼塊中寫入更多的代碼。

+0

正在進行是的已經這樣做(更新回答我的相機var是null,如果這不存在,我檢查爲空)。更擔心在同一個應用程序中的新舊代碼。 – tgkprog

+0

在檢查之前,您必須獲得Camera/Flash的運行時權限,否則您將在版本6+中獲得空指針異常。在代碼不重要的較低版本中,它將運行良好。 – Mukesh

+0

是的,謝謝 – tgkprog

相關問題