2

I have been working on an app to use a phone's/tablet's camera flash as a flashlight. Everything seemed to be working fine but when I tested it on my Droid Bionic running Android 4.1.2, the app failed to turn on the flash even though it said it did. Here is the java code I used:

    package com.example.flash;

    import android.app.Activity;
    import android.content.Context;
    import android.content.Intent;
    import android.content.pm.PackageManager;
    import android.hardware.Camera;
    import android.hardware.Camera.Parameters;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.Menu;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.Toast;

    public class MainActivity extends Activity {

    private boolean isFlashOn = false;
    private Camera camera;
    private Button button;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    button = (Button) findViewById(R.id.buttonFlashlight);
    Context context = this;
    PackageManager pm = context.getPackageManager();

    if(!pm.hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
        Log.e("err", "Device has no camera!");
        Toast.makeText(getApplicationContext(),
        "Your device doesn't have camera!",Toast.LENGTH_SHORT).show();
        return;
        }

    camera = Camera.open();

    final Parameters p = camera.getParameters();

    button.setOnClickListener(new OnClickListener() {
        public void onClick(View arg0) {
            if (isFlashOn) {
            Log.i("info", "torch is turned off!");                   
            p.setFlashMode(Parameters.FLASH_MODE_OFF);
            camera.setParameters(p);                   
            isFlashOn = false;
            button.setText("Tap to turn flashlight on.");
            } 
            else {
            Log.i("info", "torch is turned on!");
            p.setFlashMode(Parameters.FLASH_MODE_TORCH);
            camera.setParameters(p);
            isFlashOn = true;
            button.setText("Tap to turn flashlight off.");
            }
        }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    protected void onStop() {
        super.onStop();
        if (camera != null) {
        camera.release();
    }

}}

Is this code correct or did I miss something?

Logcat:

07-03 18:48:29.064: E/Trace(773): error opening trace file: No such file or directory (2)
07-03 18:48:30.535: D/Camera(773): app passed NULL surface
07-03 18:48:31.023: D/libEGL(773): loaded /system/lib/egl/libEGL_emulation.so
07-03 18:48:31.073: D/(773): HostConnection::get() New Host Connection established     0x2a13c3c0, tid 773
07-03 18:48:31.123: D/libEGL(773): loaded /system/lib/egl/libGLESv1_CM_emulation.so
07-03 18:48:31.173: D/libEGL(773): loaded /system/lib/egl/libGLESv2_emulation.so
07-03 18:48:31.406: W/EGL_emulation(773): eglSurfaceAttrib not implemented
07-03 18:48:31.433: D/OpenGLRenderer(773): Enabling debug mode 0
07-03 18:48:31.723: I/Choreographer(773): Skipped 58 frames!  The application may be doing too much work on its main thread.
07-03 18:49:05.923: D/dalvikvm(773): GC_CONCURRENT freed 202K, 12% free 2623K/2956K, paused 74ms+25ms, total 234ms
07-03 18:49:06.216: W/EGL_emulation(773): eglSurfaceAttrib not implemented
07-03 18:49:09.584: D/Camera(773): app passed NULL surface
07-03 18:49:09.853: W/EGL_emulation(773): eglSurfaceAttrib not implemented
07-03 18:49:11.813: I/info(773): torch is turned on!
07-03 18:49:13.467: I/info(773): torch is turned off!
07-03 18:49:16.263: W/EGL_emulation(773): eglSurfaceAttrib not implemented
07-03 18:49:16.713: D/AndroidRuntime(773): Shutting down VM
07-03 18:49:16.713: W/dalvikvm(773): threadid=1: thread exiting with uncaught exception (group=0x40a71930)
07-03 18:49:16.936: E/AndroidRuntime(773): FATAL EXCEPTION: main
07-03 18:49:16.936: E/AndroidRuntime(773): java.lang.RuntimeException: Method called after release()
07-03 18:49:16.936: E/AndroidRuntime(773):  at android.hardware.Camera._stopPreview(Native Method)
07-03 18:49:16.936: E/AndroidRuntime(773):  at android.hardware.Camera.stopPreview(Camera.java:543)
07-03 18:49:16.936: E/AndroidRuntime(773):  at com.example.flash.MainActivity.surfaceDestroyed(MainActivity.java:140)
07-03 18:49:16.936: E/AndroidRuntime(773):  at android.view.SurfaceView.updateWindow(SurfaceView.java:553)
07-03 18:49:16.936: E/AndroidRuntime(773):  at android.view.SurfaceView.onWindowVisibilityChanged(SurfaceView.java:231)
07-03 18:49:16.936: E/AndroidRuntime(773):  at android.view.View.dispatchWindowVisibilityChanged(View.java:7544)
07-03 18:49:16.936: E/AndroidRuntime(773):  at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1039)
07-03 18:49:16.936: E/AndroidRuntime(773):  at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1039)
07-03 18:49:16.936: E/AndroidRuntime(773):  at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1039)
07-03 18:49:16.936: E/AndroidRuntime(773):  at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1039)
07-03 18:49:16.936: E/AndroidRuntime(773):  at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1211)
07-03 18:49:16.936: E/AndroidRuntime(773):  at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:989)
07-03 18:49:16.936: E/AndroidRuntime(773):  at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4351)
07-03 18:49:16.936: E/AndroidRuntime(773):  at android.view.Choreographer$CallbackRecord.run(Choreographer.java:749)
07-03 18:49:16.936: E/AndroidRuntime(773):  at android.view.Choreographer.doCallbacks(Choreographer.java:562)
07-03 18:49:16.936: E/AndroidRuntime(773):  at android.view.Choreographer.doFrame(Choreographer.java:532)
07-03 18:49:16.936: E/AndroidRuntime(773):  at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735)
07-03 18:49:16.936: E/AndroidRuntime(773):  at android.os.Handler.handleCallback(Handler.java:725)
07-03 18:49:16.936: E/AndroidRuntime(773):  at android.os.Handler.dispatchMessage(Handler.java:92)
07-03 18:49:16.936: E/AndroidRuntime(773):  at android.os.Looper.loop(Looper.java:137)
07-03 18:49:16.936: E/AndroidRuntime(773):  at android.app.ActivityThread.main(ActivityThread.java:5041)
07-03 18:49:16.936: E/AndroidRuntime(773):  at java.lang.reflect.Method.invokeNative(Native Method)
07-03 18:49:16.936: E/AndroidRuntime(773):  at java.lang.reflect.Method.invoke(Method.java:511)
07-03 18:49:16.936: E/AndroidRuntime(773):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
07-03 18:49:16.936: E/AndroidRuntime(773):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
07-03 18:49:16.936: E/AndroidRuntime(773):  at dalvik.system.NativeStart.main(Native Method)
07-03 18:49:24.854: E/Trace(811): error opening trace file: No such file or directory (2)
07-03 18:49:25.413: D/libEGL(811): loaded /system/lib/egl/libEGL_emulation.so
07-03 18:49:25.567: D/(811): HostConnection::get() New Host Connection established 0x2a15f570, tid 811
07-03 18:49:25.643: D/libEGL(811): loaded /system/lib/egl/libGLESv1_CM_emulation.so
07-03 18:49:25.663: D/libEGL(811): loaded /system/lib/egl/libGLESv2_emulation.so
07-03 18:49:25.934: W/EGL_emulation(811): eglSurfaceAttrib not implemented
07-03 18:49:25.963: D/OpenGLRenderer(811): Enabling debug mode 0
07-03 18:53:12.298: D/Camera(811): app passed NULL surface
07-03 18:53:12.723: D/dalvikvm(811): GC_CONCURRENT freed 172K, 11% free 2600K/2904K, paused 9ms+165ms, total 421ms
07-03 18:53:12.934: E/EGL_emulation(811): rcCreateWindowSurface returned 0
07-03 18:53:12.934: E/EGL_emulation(811): tid 811: eglCreateWindowSurface(631): error 0x3003 (EGL_BAD_ALLOC)
07-03 18:53:12.943: D/AndroidRuntime(811): Shutting down VM
07-03 18:53:12.943: W/dalvikvm(811): threadid=1: thread exiting with uncaught exception (group=0x40a71930)
07-03 18:53:13.033: E/AndroidRuntime(811): FATAL EXCEPTION: main
07-03 18:53:13.033: E/AndroidRuntime(811): java.lang.RuntimeException: createWindowSurface failed EGL_BAD_ALLOC
07-03 18:53:13.033: E/AndroidRuntime(811):  at android.view.HardwareRenderer$GlRenderer.createSurface(HardwareRenderer.java:1064)
07-03 18:53:13.033: E/AndroidRuntime(811):  at android.view.HardwareRenderer$GlRenderer.createEglSurface(HardwareRenderer.java:961)
07-03 18:53:13.033: E/AndroidRuntime(811):  at android.view.HardwareRenderer$GlRenderer.initialize(HardwareRenderer.java:787)
07-03 18:53:13.033: E/AndroidRuntime(811):  at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1502)
07-03 18:53:13.033: E/AndroidRuntime(811):  at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:989)
07-03 18:53:13.033: E/AndroidRuntime(811):  at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4351)
07-03 18:53:13.033: E/AndroidRuntime(811):  at android.view.Choreographer$CallbackRecord.run(Choreographer.java:749)
07-03 18:53:13.033: E/AndroidRuntime(811):  at android.view.Choreographer.doCallbacks(Choreographer.java:562)
07-03 18:53:13.033: E/AndroidRuntime(811):  at android.view.Choreographer.doFrame(Choreographer.java:532)
07-03 18:53:13.033: E/AndroidRuntime(811):  at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735)
07-03 18:53:13.033: E/AndroidRuntime(811):  at android.os.Handler.handleCallback(Handler.java:725)
07-03 18:53:13.033: E/AndroidRuntime(811):  at android.os.Handler.dispatchMessage(Handler.java:92)
07-03 18:53:13.033: E/AndroidRuntime(811):  at android.os.Looper.loop(Looper.java:137)
07-03 18:53:13.033: E/AndroidRuntime(811):  at android.app.ActivityThread.main(ActivityThread.java:5041)
07-03 18:53:13.033: E/AndroidRuntime(811):  at java.lang.reflect.Method.invokeNative(Native Method)
07-03 18:53:13.033: E/AndroidRuntime(811):  at java.lang.reflect.Method.invoke(Method.java:511)
07-03 18:53:13.033: E/AndroidRuntime(811):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
07-03 18:53:13.033: E/AndroidRuntime(811):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
07-03 18:53:13.033: E/AndroidRuntime(811):  at dalvik.system.NativeStart.main(Native Method)

2 Answers2

2

UPDATE

I think the key is you are running Android 4.1.2. Since Android 4.0, if you want to use the Camera Device, even if you only want to use the flash, you are forced to use a SurfaceView.

In the previous answer (below), I gave you a link to a Torch app which uses SurfaceView. Try it or adapt it to your code.

PREVIOUS ANSWER:

As stated in many other cases (like this one), you may be facing a Device-Specific issue that is quite common in the Android world.

Although getSupportedFlashModes() may return FLASH_MODE_TORCH on nearly every device, many of them don't actually support it.

Anyway, you could try these:

  • Use camera.startPreview(); after camera = Camera.open();
  • Try setting FLASH_MODE_OFF initially (before camera.startPreview();).
  • Check if this Torch app works in your device. In case it does, you have the source code to compare it to yours.
  • Download a Torch app from the Play Store to test if it's a device issue or not.
  • Post the issue in a Droid Bionic support forum.

UPDATE: I would say the final keyword is a problem in your code. Try changing it to:

//camera = Camera.open();
//final Parameters p = camera.getParameters();

button.setOnClickListener(new OnClickListener() {
    public void onClick(View arg0) {
        if (isFlashOn) {
           Log.i("info", "torch is turned off!");                   
           cam.stopPreview();
           cam.release();
           isFlashOn = false;
           button.setText("Tap to turn flashlight on.");
           } 
        else {
           Log.i("info", "torch is turned on!");
           camera = Camera.open();
           Parameters p = camera.getParameters();
           p.setFlashMode(Parameters.FLASH_MODE_OFF);
           camera.setParameters(p);
           camera.startPreview();
           p.setFlashMode(Parameters.FLASH_MODE_TORCH);
           camera.setParameters(p);
           isFlashOn = true;
           button.setText("Tap to turn flashlight off.");
        }
    }
});
Community
  • 1
  • 1
Alejandro Colorado
  • 6,034
  • 2
  • 28
  • 39
  • I made the changes that you suggested and it still did not work. I also installed that app and another on the play store. The app you recommended did not function at all on my phone but the other one worked perfectly... – JoshSchellenberger Jun 23 '13 at 02:58
  • [This guy](http://stackoverflow.com/users/563473/kevin-teslacoil) is the dev of TeslaLED. Try that app in your device. If it works, then try [this code](http://stackoverflow.com/a/5585171/1587345) (he tells there he is using it). – Alejandro Colorado Jun 23 '13 at 03:31
  • I am pretty new to this so be patient with me... I substituted the new code with my corresponding code and it didn't recognize the cam variable. Is it supposed to naturally recognize that or did I need to declare it somewhere? – JoshSchellenberger Jul 01 '13 at 04:29
  • You have to declare it, as you did in your original code with the 'private Camera camera;' statement. – Alejandro Colorado Jul 01 '13 at 06:28
  • It still does not work when I change the code and declare private Camera cam; – JoshSchellenberger Jul 01 '13 at 19:35
  • By the way, TeslaLED does work on my device but I could not entirely figure out how to implement his code into mine. – JoshSchellenberger Jul 01 '13 at 20:01
  • When I tap the button to turn on the flash, the flash doesn't turn on but it does set the value of isFlashOn to true. When I tap the button again, the app crashes. I think it is because camera.startPreview() didn't work or it didn't recognize the command cam.stopPreview(). Does anyone know why it would do this? – JoshSchellenberger Jul 01 '13 at 21:25
  • Ok, when I integrated the SurfaceView into my program, it successfully turned the camera on. Unfortunately, whenever I do something else on the app, it crashes... – JoshSchellenberger Jul 03 '13 at 17:03
  • Did the flash turn on? Post your LogCat so we can help you. – Alejandro Colorado Jul 03 '13 at 21:07
  • The flash did turn on. I also added the Logcat. – JoshSchellenberger Jul 04 '13 at 04:29
0

user the permission "android.permission.FLASHLIGHT" in the manifest

<uses-permission android:name="android.permission.FLASHLIGHT" />
<uses-permission android:name="android.permission.CAMERA" />
stinepike
  • 54,068
  • 14
  • 92
  • 112