Use camera flashlight in Android
Asked Answered
H

7

53

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.

Haughay answered 31/3, 2011 at 16:58 Comment(12)
Even I wanted to know how to do this. Upvoted!Designed
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.Schumacher
Well, before I start reverse engineering someones code, I'd really like some more insight from coders on stackoverflow ;-)Haughay
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.Magree
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!Madeleinemadelena
@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.Haughay
@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.Haughay
Just tested Torch. Doesn't work correctly with the Galaxy Tab either. The device correctly sends back the supported modes (including Torch) though.Haughay
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 devicesGeorg
Why are you calling camera.release() after turning the flashlight on?Ytterbite
@ajacian81: I'm not anymore. See the last paragraph in the initial post. Thanks for the comment though!Haughay
@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?Turmoil
N
35

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.

Nobie answered 7/4, 2011 at 17:33 Comment(7)
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?Haughay
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.Nobie
@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 ?Papaveraceous
@Kevin TeslaCoil : can you please help me here #6940316Papaveraceous
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.Nobie
@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..Sulfapyrazine
@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? ThanksCornhusking
G
18

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.

Georg answered 4/4, 2011 at 12:31 Comment(2)
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.Haughay
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/javaocrGeorg
S
11

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" />
Sigismondo answered 21/9, 2012 at 18:3 Comment(3)
Without having tried this approach: If you use reflection there is a good chance your code is gonna break sooner or later.Dowsabel
From : code.google.com/p/droidled/source/browse/trunk/src/com/droidled/…Society
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.Confuse
D
8

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();
Deering answered 31/3, 2011 at 16:58 Comment(2)
What Android device are you trying this on? Thanks!Haughay
@Deering Does not work on a Samsung Galaxy SII - are u missing anything by any chance? Such as showing the preview?Dowsabel
D
4

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?

Dachau answered 2/3, 2012 at 9:30 Comment(3)
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 ...Dowsabel
For me it's working on the SII, is your surface view visible?Dachau
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.Dowsabel
M
3

Please use this link:

http://www.androidhive.info/2013/04/android-developing-flashlight-application/

It very helpful for me.

Mev answered 4/9, 2014 at 9:37 Comment(0)
G
1
private Camera camera;
void openCam(){
    camera = Camera.open();
    if (camera != null) {
        Camera.Parameters params = camera.getParameters();
        camera.setParameters(params);
    }
    Camera.Parameters p = camera.getParameters();
    p.setFlashMode(Parameters.FLASH_MODE_TORCH);
    camera.setParameters(p);
}

set permission in Manifest:

<uses-permission
    android:name="android.permission.FLASHLIGHT"
    android:permissionGroup="android.permission-group.HARDWARE_CONTROLS"
    android:protectionLevel="normal" />

<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.flash" />
Gallardo answered 29/3, 2012 at 4:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.