A few seconds delay when trying to turn on the power of the LED flash

I am trying to turn on the LED flash, but the LED flash turns on after a delay of a few seconds.

I have a built-in torch in my phone, and when I click on it, the flash immediately turns on.

What is the problem?

Here is my code:

private void processOnClick() { if (manuName.contains("motorola")) { DroidLED led; try { led = new DroidLED(); led.enable(true); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } else { if (mCamera == null) { try { mCamera = Camera.open(); } catch (Exception e) { e.printStackTrace(); } } try { mCamera = Camera.open(); } catch (Exception e) { e.printStackTrace(); } if (mCamera != null) { final Parameters params = mCamera.getParameters(); List<String> flashModes = params.getSupportedFlashModes(); if (flashModes == null) { return; } else { if (count == 0) { params.setFlashMode(Parameters.FLASH_MODE_OFF); mCamera.setParameters(params); mCamera.startPreview(); } String flashMode = params.getFlashMode(); if (!Parameters.FLASH_MODE_TORCH.equals(flashMode)) { if (flashModes.contains(Parameters.FLASH_MODE_TORCH)) { params.setFlashMode(Parameters.FLASH_MODE_TORCH); mCamera.setParameters(params); } else { // Toast.makeText(this, // "Flash mode (torch) not supported",Toast.LENGTH_LONG).show(); params.setFlashMode(Parameters.FLASH_MODE_ON); mCamera.setParameters(params); try { mCamera.autoFocus(new AutoFocusCallback() { public void onAutoFocus(boolean success, Camera camera) { count = 1; } }); } catch (Exception e) { e.printStackTrace(); } } } } } } if (mCamera == null) { return; } } private void processOffClick() { if (manuName.contains("motorola")) { DroidLED led; try { led = new DroidLED(); led.enable(false); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } else { if (mCamera != null) { mCamera.stopPreview(); mCamera.release(); } } } 

DroidLED Class:

 import java.lang.reflect.Method; import android.os.IBinder; class DroidLED { private Object svc = null; private Method getFlashlightEnabled = null; private Method setFlashlightEnabled = null; @SuppressWarnings("unchecked") public DroidLED() throws Exception { try { // call ServiceManager.getService("hardware") to get an IBinder for the service. // this appears to be totally undocumented and not exposed in the SDK whatsoever. Class sm = Class.forName("android.os.ServiceManager"); Object hwBinder = sm.getMethod("getService", String.class).invoke(null, "hardware"); // get the hardware service stub. this seems to just get us one step closer to the proxy Class hwsstub = Class.forName("android.os.IHardwareService$Stub"); Method asInterface = hwsstub.getMethod("asInterface", android.os.IBinder.class); svc = asInterface.invoke(null, (IBinder) hwBinder); // grab the class (android.os.IHardwareService$Stub$Proxy) so we can reflect on its methods Class proxy = svc.getClass(); // save methods getFlashlightEnabled = proxy.getMethod("getFlashlightEnabled"); setFlashlightEnabled = proxy.getMethod("setFlashlightEnabled", boolean.class); } catch(Exception e) { throw new Exception("LED could not be initialized"); } } public boolean isEnabled() { try { return getFlashlightEnabled.invoke(svc).equals(true); } catch(Exception e) { return false; } } public void enable(boolean tf) { try { setFlashlightEnabled.invoke(svc, tf); } catch(Exception e) {} } } 

I took this code from some answer around stackoverflow.

Thanks for your help!

+4
source share
2 answers

Do you get big delays with the motor system?

This is just an assumption, but the DroidLED constructor calls for expensive system initializations. Could you do this?

 public class MyWidgetClickHandler { private DroidLED = null; public MyWidgetClickHandler(string ManuName) { // This is slow. It will run once at initialization. if (ManuName != null && ManuName.toLowerCase().contains("motorola")) DroidLED = new DroidLED(); } public void processOnClick() { if (DroidLED != null) DroidLED.enable(true); else ; // ... TODO } public void processOffClick() { if (DroidLED != null) DroidLED.enable(false); else ; // ... TODO } } 

There could be a lot more. For example, you can create an LED interface with enable and isEnabled and have two implementations for it. One of them will be DroidLED , and the other is CommonCameraLED . In this case, it looks like this:

 public class LEDFactory { public static LED createLED(string ManuName) { if (ManuName != null && ManuName.toLowerCase().contains("motorola")) return new DroidLED(); else return new CommonCameraLED(); } } public class MyWidgetClickHandler { private LED myLed = null; public MyWidgetClickHandler(string ManuName) { myLed = LEDFactory.createLED(ManuName); } public void processOnClick() { myLed.enable(true); // NOTHING TO DO } public void processOffClick() { myLed.enable(false); // NOTHING TO DO } } 

You can also create Thread to initialize so that the phone does not start slowly.

0
source

I ran into the same problem and found a solution, but I ran the tests using the Samsung Galaxy S2. This code should work on every device.

Profiling each of the functions, I found that some of the calls required to configure the camera have a delay of up to 500 ms , which makes the strobe effect impossible.

My solution was to move all these functions to a separate function, which I call when I want to get the camera, and reduce the β€œenable” code only until Camera.setParameters() called. By doing this, the delay decreased to 4 ms .

For example (the given code is only for confirming the point):

 // First get the camera for your app (Keep this variables as class members so the live between functions) private void acquireCamera() { try { // Get camera cam = Camera.open(); // This is not on your code but you should do it for compatibility mSurfaceTexture = new SurfaceTexture(0); cam.setPreviewTexture(mSurfaceTexture); cam.startPreview(); camParams = cam.getParameters(); } catch(IOException e) { /*...*/ } } // Then turn on / off as many times you want. private void setTorch(boolean on) { camParams.setFlashMode(on? Camera.Parameters.FLASH_MODE_TORCH : Camera.Parameters.FLASH_MODE_OFF); cam.setParameters(camParams); } // Finally release the camera when you`re done private void releaseCamera { camParams = null; cam.stopPreview(); mSurfaceTexture = null; cam.release(); } 
0
source

Source: https://habr.com/ru/post/1500203/


All Articles