Use camera flashlight in Android

89,334

Solution 1

Every device is a bit different. Samsung especially likes to make things complicated for app developers.

On the Galaxy Tab you should be good with:

Camera cam;
void ledon() {
    cam = Camera.open();     
    Parameters params = cam.getParameters();
    params.setFlashMode(Parameters.FLASH_MODE_ON);
    cam.setParameters(params);
    cam.startPreview();
    cam.autoFocus(new AutoFocusCallback() {
                public void onAutoFocus(boolean success, Camera camera) {
                }
            });
}

void ledoff() {
    cam.stopPreview();
    cam.release();
}

If that doesn't work then it might be a matter of setting FLASH_MODE_OFF initially and changing it after the startPreview.

Solution 2

You must not release the camera after setting the parameters. I found that flash is activated (in torch mode) after I have started the preview. ( Applies to motorola defy, 2.1 )

It is also a good idea to check supported flash modes, before trying to activate them.

Messing around with camera settings on android is darkest voodoo: Many devices behave differently and there seems to be no reliable way of targeting them all with one piece of code. Safest bet is to always set up your camera properly when your onResume() method is called. I would also consider doing the same in onConfigChange(), because at least Motorola screen locker can force your application into portrait mode, restarting it completely.

P.s. I suppose that when you close the camera, the native camera app is closed and then recreated in a fresh state.

Solution 3

I have done it the following way, which works on many phones:

 String manuName = android.os.Build.MANUFACTURER.toLowerCase();
 Camera mCamera;

The below code shows, how to turn lights off and on:

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

        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) {
            count = 0;
            mCamera.stopPreview();
        }
    }
}

Below is the class DroidLED:

 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) {}
    }

}

The following permissions must be set in your AndroidManifest.xml:

 <uses-permission android:name="android.permission.CAMERA" />
 <uses-permission android:name="android.permission.FLASHLIGHT"/>
 <uses-feature android:name="android.hardware.camera" />
 <uses-feature android:name="android.hardware.camera.autofocus" />
 <uses-feature android:name="android.hardware.camera.flash" />

Solution 4

This works for me on a HTC Desire... (with 2.2) (Of course with Camera and Flashlight permissions):

    Camera mycam = Camera.open();
    Parameters p = mycam.getParameters();// = mycam.getParameters();
    p.setFlashMode(Parameters.FLASH_MODE_TORCH); 
    mycam.setParameters(p); //time passes 
    try {
        Thread.sleep(500);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    p.setFlashMode(Parameters.FLASH_MODE_OFF);
    mycam.release();

Solution 5

You also could try to add a surface view. Please take a look at my answer to LED flashlight on Galaxy Nexus controllable by what API?

Share:
89,334
pgruetter
Author by

pgruetter

Apparently, this user prefers to keep an air of mystery about them. He really does.

Updated on July 20, 2022

Comments

  • pgruetter
    pgruetter almost 2 years

    I'm trying to use the cameras LED flashlight in a widget. I've found several threads about this topic (i.e. the one mentioned later..) , now I'm trying to control the light using:

    Camera cam = Camera.open();     
    Parameters p = cam.getParameters();
    p.setFlashMode(Parameters.FLASH_MODE_TORCH);
    cam.setParameters(p);
    cam.release();
    

    In the AndroidManifest.xml tried different permissions, currently I have:

    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.FLASHLIGHT"/>
    <uses-feature android:name="android.hardware.camera" />
    <uses-feature android:name="android.hardware.camera.autofocus" />
    <uses-feature android:name="android.hardware.camera.flash" />
    

    I'm testing this on my Galaxy Tab as I don't have any other Android devices at hand: the light does not turn on. So I have a few questions now:

    1. Is there any way to test the led light behavior in the Emulator?
    2. Am I doing something wrong here?
    3. According to this question which deals with the same problem, it works differently on the Galaxy Tab. How?
    4. And finally, if it does work differently, I'm starting to wonder if it's just the Galaxy Tab or if other devices use different methods too. It would be hard to test then and it seems rather odd to me.

    Thanks for any insight!

    By the way, I quickly tested with quick-settings which gets mentioned a few times here. The flashlight doesn't work with quick-settings either.

    Note that the Galaxy Tab stil uses android 2.2. I see there were some changes between 2.2 and 2.3.

    Comment: I know it has to work somehow as I have found other apps in the market that work perfectly with the Galaxy Tab.

    Comment 2: If I set cam.setParameters(p); and directly ask the camera for the current state with getFlashMode() it correctly returns FLASH_MODE_TORCH. However, if I release the camera and re-open it, it returns FLASH_MODE_OFF. It's almost as if the Camera object aknowledges the request but doesn't really pass it on to the hardware!?

    --

    After Konstantins comment, I removed the cam.release(); part. He is right, the settings are not persisted if you release the camera. If you use cam.open() again, you will get a fresh instance with the light off. The light's still not working on the galaxy tab though. So, I guess it's hard to keep the light on if you're trying to control it through a widget then. As soon as the background service is finished, the camera object is released automatically and therefore the light switches off again. My questions still remain, especially why the camera doesn't switch on in the first place.

    • CuriousMind
      CuriousMind over 13 years
      Even I wanted to know how to do this. Upvoted!
    • RoflcoptrException
      RoflcoptrException over 13 years
      I don't have any ideas too, but if you can't find a solution you could download one of the flashlight apps from the market and try to decompile it.
    • pgruetter
      pgruetter over 13 years
      Well, before I start reverse engineering someones code, I'd really like some more insight from coders on stackoverflow ;-)
    • Joseph Earl
      Joseph Earl over 13 years
      From what a remember quite a few existing torch apps needed some modification to work with the Tab. Perhaps you could contact the developer of an existing flashlight app that works on the Tab and ask what (if any) modifications they had to make to get their code working on the Tab.
    • laurentsebag
      laurentsebag about 13 years
      Hi! I've never tried to play with the flashlight, but I use this app for my nexus one which is open source : code.google.com/p/torch. Maybe you could try it to see if they have a approach ... good luck!
    • pgruetter
      pgruetter about 13 years
      @Joseph Earl: It really looks like it. I will see if I can get another Android device to test the different beavhior. I also tried the app "LED Light", with which the Galaxy Tab works. However, the light also turns off after a few seconds if it's turned on via the widget. This actually confirms my assumptions I wrote in my last addition. I will try to contact the author. If I do get an answer (not all coder like to share..), I will certainly add it here.
    • pgruetter
      pgruetter about 13 years
      @grattemedi: very nice, thanks for the link. I haven't found that one yet. This actually doesn't look too bad. The only think new in the code is the WakeLock! Never considered this, will try a few things from this example.
    • pgruetter
      pgruetter about 13 years
      Just tested Torch. Doesn't work correctly with the Galaxy Tab either. The device correctly sends back the supported modes (including Torch) though.
    • Konstantin Pribluda
      Konstantin Pribluda about 13 years
      Just for information: Motorola Defy lists following flash modes: [off, on, auto, torch] - and there is definitely no standard how they have to work, and which modes are provided by differen devices
    • ajacian81
      ajacian81 almost 13 years
      Why are you calling camera.release() after turning the flashlight on?
    • pgruetter
      pgruetter almost 13 years
      @ajacian81: I'm not anymore. See the last paragraph in the initial post. Thanks for the comment though!
    • Patricia
      Patricia over 9 years
      @socken23 - Did you ever get this working? I'm having the same problem with the Samsung Galaxy S5. I'm setting the torch on; the parameters shows the flash-mode=torch; it works on every other phone; it's like the camera event doesn't get fired or the camera is ignoring my command. But I know it should work, because I'm running OpenCamera on the Samsung Galaxy S5 and that works when torch is turned on. I cannot see the difference between my code and theirs. Do you know the magic trick?
  • pgruetter
    pgruetter over 13 years
    Lots of good suggestions, thanks! Without releasing the camera instance, I can now ask for the properties and it correctly returns torch mode again, great. However, the flashlight still doesn't switch on, even when using preview. The thing is, I'm trying to switch on the LED light through a widget. This will be hard based on your comments, as I need to hold the Camera object as long as the light should stay on.
  • Konstantin Pribluda
    Konstantin Pribluda over 13 years
    I played around with torch in my small OCR app and found that flash goes on only when I started preview (and it went out when I requested snapshot, thus producing black image). I developed small android demo app in JavaOCR project - feel free to get inspiration from it: sourceforge.net/projects/javaocr
  • pgruetter
    pgruetter over 13 years
    Great! Thanks a lot for the link. I will take a look at it.
  • pgruetter
    pgruetter about 13 years
    What Android device are you trying this on? Thanks!
  • pgruetter
    pgruetter about 13 years
    Thanks a lot for the details. A quick test didn't show any success. Will try it in a single Activity to make sure nothing is interfering. Can you tell me, where do you have this information from? Have you tried it on a Galaxy Tab yourself?
  • Kevin TeslaCoil
    Kevin TeslaCoil about 13 years
    Yes. I'm the dev of TeslaLED, which actually needs an update for the Tab and I haven't had a chance to release yet, but I do similar to above and have tested on a T-Mobile Galaxy Tab. I do start with FLASH_MODE_OFF and switch to to FLASH_MODE_ON however.
  • Kartik Domadiya
    Kartik Domadiya almost 13 years
    @Kevin TeslaCoil: i was facing the same issue but your code worked for me in Samsung Galaxy Ace 2.2.1 . But the LED remains in ON state for just 5secs.. What can be the reason for that ?
  • Kartik Domadiya
    Kartik Domadiya almost 13 years
    @Kevin TeslaCoil : can you please help me here stackoverflow.com/questions/6939816/…
  • Kevin TeslaCoil
    Kevin TeslaCoil almost 13 years
    Sorry @Kartik, I'm not familiar with the Galaxy Ace. Generally most HTC devices are similar to each other and most Motorola devices are similar to each other, but for Samsung every device is rather different.
  • Kartik Domadiya
    Kartik Domadiya almost 13 years
    @Kevin TeslaCoil.. Thanks for the info.. :)
  • RajaReddy PolamReddy
    RajaReddy PolamReddy over 12 years
    @KevinTeslaCoil i am using above code in my android Samsung Ace device i am facing problem with light, after 2 seconds it goes to off.. why like that please help me..
  • AgentKnopf
    AgentKnopf over 11 years
    @Horaceman Does not work on a Samsung Galaxy SII - are u missing anything by any chance? Such as showing the preview?
  • AgentKnopf
    AgentKnopf over 11 years
    Without having tried this approach: If you use reflection there is a good chance your code is gonna break sooner or later.
  • AgentKnopf
    AgentKnopf over 11 years
    I tried on Samsung Galaxy SII an it did not work. Much simpler approaches worked on other phones (Note, Xperia S), it's a pain :P ...
  • timoschloesser
    timoschloesser over 11 years
    For me it's working on the SII, is your surface view visible?
  • AgentKnopf
    AgentKnopf over 11 years
    Yes it is. I tried every possible variation. The thing is: It worked on other phones (also your sample) but not on that SII (at least not on the one I have here). Odd thing is: We also use the camera for other purposes within a proper camera dialog. If I ran that flashlight code, then started the camera dialog, the flashlight did show. First I thought because of the SurfaceView, but since I tried that and it did not work, maybe it's something else. I find it rather horrifying, that there is no simple, unified way of getting the flashlight to work on all devices that support flashlight.
  • hB0
    hB0 almost 11 years
  • rutulPatel
    rutulPatel about 10 years
    @KevinTeslaCoil I've a question, can i access flash light without locking the camera? Becasue when flash light from my app is on, it fails to open the camera. If not, is there any way around? Thanks
  • ChuongPham
    ChuongPham almost 10 years
    This is not a future-proof solution as all Reflection solutions do. Sooner or later, Google will close the gaping hole and Reflection methods like these will simply not work.