[android] How to turn on front flash light programmatically in Android?

I want to turn on front flash light (not with camera preview) programmatically in Android. I googled for it but the help i found referred me to this page

Does anyone have any links or sample code?

This question is related to android android-camera

The answer is


Android Lollipop introduced camera2 API and deprecated the previous camera API. However, using the deprecated API to turn on the flash still works and is much simpler than using the new API.

It seems that the new API is intended for use in dedicated full featured camera apps and that its architects didn't really consider simpler use cases such as turning on the flashlight. To do that now, one has to get a CameraManager, create a CaptureSession with a dummy Surface, and finally create and start a CaptureRequest. Exception handling, resource cleanup and long callbacks included!

To see how to turn the flashlight on Lollipop and newer, take a look at the FlashlightController in the AOSP project (try to find the newest as older use APIs that have been modified). Don't forget to set the needed permissions.


Android Marshmallow finally introduced a simple way to turn on the flash with setTorchMode.


Complete Code for android Flashlight App

Manifest

  <?xml version="1.0" encoding="utf-8"?>
  <manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.user.flashlight"
      android:versionCode="1"
      android:versionName="1.0">

      <uses-sdk
          android:minSdkVersion="8"
          android:targetSdkVersion="17"/>

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

      <application
          android:allowBackup="true"
          android:icon="@mipmap/ic_launcher"
          android:label="@string/app_name"
          android:theme="@style/AppTheme" >
          <activity
              android:name=".MainActivity"
              android:label="@string/app_name" >
              <intent-filter>
                  <action android:name="android.intent.action.MAIN" />

                  <category android:name="android.intent.category.LAUNCHER" />
              </intent-filter>
          </activity>
      </application>

  </manifest>

XML

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="OFF"
        android:id="@+id/button"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true"
        android:onClick="turnFlashOnOrOff" />
</RelativeLayout>

MainActivity.java

  import android.app.AlertDialog;
  import android.content.DialogInterface;
  import android.content.pm.PackageManager;
  import android.hardware.Camera;
  import android.hardware.Camera.Parameters;
  import android.support.v7.app.AppCompatActivity;
  import android.os.Bundle;
  import android.view.View;
  import android.widget.Button;

  import java.security.Policy;

  public class MainActivity extends AppCompatActivity {

      Button button;
      private Camera camera;
      private boolean isFlashOn;
      private boolean hasFlash;
      Parameters params;

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

          button = (Button) findViewById(R.id.button);

          hasFlash = getApplicationContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);

          if(!hasFlash) {

              AlertDialog alert = new AlertDialog.Builder(MainActivity.this).create();
              alert.setTitle("Error");
              alert.setMessage("Sorry, your device doesn't support flash light!");
              alert.setButton("OK", new DialogInterface.OnClickListener() {
                  @Override
                  public void onClick(DialogInterface dialog, int which) {
                      finish();
                  }
              });
              alert.show();
              return;
          }

          getCamera();

          button.setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View v) {

                  if (isFlashOn) {
                      turnOffFlash();
                      button.setText("ON");
                  } else {
                      turnOnFlash();
                      button.setText("OFF");
                  }

              }
          });
      }

      private void getCamera() {

          if (camera == null) {
              try {
                  camera = Camera.open();
                  params = camera.getParameters();
              }catch (Exception e) {

              }
          }

      }

      private void turnOnFlash() {

          if(!isFlashOn) {
              if(camera == null || params == null) {
                  return;
              }

              params = camera.getParameters();
              params.setFlashMode(Parameters.FLASH_MODE_TORCH);
              camera.setParameters(params);
              camera.startPreview();
              isFlashOn = true;
          }

      }

      private void turnOffFlash() {

              if (isFlashOn) {
                  if (camera == null || params == null) {
                      return;
                  }

                  params = camera.getParameters();
                  params.setFlashMode(Parameters.FLASH_MODE_OFF);
                  camera.setParameters(params);
                  camera.stopPreview();
                  isFlashOn = false;
              }
      }

      @Override
      protected void onDestroy() {
          super.onDestroy();
      }

      @Override
      protected void onPause() {
          super.onPause();

          // on pause turn off the flash
          turnOffFlash();
      }

      @Override
      protected void onRestart() {
          super.onRestart();
      }

      @Override
      protected void onResume() {
          super.onResume();

          // on resume turn on the flash
          if(hasFlash)
              turnOnFlash();
      }

      @Override
      protected void onStart() {
          super.onStart();

          // on starting the app get the camera params
          getCamera();
      }

      @Override
      protected void onStop() {
          super.onStop();

          // on stop release the camera
          if (camera != null) {
              camera.release();
              camera = null;
          }
      }

  }

There's different ways to access Camera Flash in different Android versions. Few APIs stopped working in Lollipop and then it got changed again in Marshmallow. To overcome this, I have created a simple library that I have been using in few of my projects and it's giving good results. It's still incomplete, but you can try to check the code and find the missing pieces. Here's the link - NoobCameraFlash.

If you just want to integrate in your code, you can use gradle for that. Here's the instructions (Taken directly from the Readme) -

Step 1. Add the JitPack repository to your build file. Add it in your root build.gradle at the end of repositories:

allprojects {
        repositories {
            ...
            maven { url "https://jitpack.io" }
        }
}

Step 2. Add the dependency

dependencies {
        compile 'com.github.Abhi347:NoobCameraFlash:0.0.1'
  }

Usage

Initialize the NoobCameraManager singleton.

NoobCameraManager.getInstance().init(this);

You can optionally set the Log Level for debug logging. Logging uses LumberJack library. The default LogLevel is LogLevel.None

NoobCameraManager.getInstance().init(this, LogLevel.Verbose);

After that you just need to call the singleton to turn on or off the camera flash.

NoobCameraManager.getInstance().turnOnFlash();
NoobCameraManager.getInstance().turnOffFlash();

You have to take care of the runtime permissions to access Camera yourself, before initializing the NoobCameraManager. In version 0.1.2 or earlier we used to provide support for permissions directly from the library, but due to dependency on the Activity object, we have to remove it.

It's easy to toggle Flash too

if(NoobCameraManager.getInstance().isFlashOn()){
    NoobCameraManager.getInstance().turnOffFlash();
}else{
    NoobCameraManager.getInstance().turnOnFlash();
}

In Marshmallow and above, CameraManager's `setTorchMode()' seems to be the answer. This works for me:

 final CameraManager mCameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
 CameraManager.TorchCallback torchCallback = new CameraManager.TorchCallback() {
     @Override
     public void onTorchModeUnavailable(String cameraId) {
         super.onTorchModeUnavailable(cameraId);
     }

     @Override
     public void onTorchModeChanged(String cameraId, boolean enabled) {
         super.onTorchModeChanged(cameraId, enabled);
         boolean currentTorchState = enabled;
         try {
             mCameraManager.setTorchMode(cameraId, !currentTorchState);
         } catch (CameraAccessException e){}



     }
 };

 mCameraManager.registerTorchCallback(torchCallback, null);//fires onTorchModeChanged upon register
 mCameraManager.unregisterTorchCallback(torchCallback);

In API 23 or Higher (Android M, 6.0)

Turn On code

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    CameraManager camManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
    String cameraId = null; 
    try {
        cameraId = camManager.getCameraIdList()[0];
        camManager.setTorchMode(cameraId, true);   //Turn ON
    } catch (CameraAccessException e) {
        e.printStackTrace();
    }
}

Turn OFF code

camManager.setTorchMode(cameraId, false);

And Permissions

<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.FLASHLIGHT"/>

ADDITIONAL EDIT

People still upvoting my answer so I decided to post additional code This was my solution for the problem back in the day:

public class FlashlightProvider {

private static final String TAG = FlashlightProvider.class.getSimpleName();
private Camera mCamera;
private Camera.Parameters parameters;
private CameraManager camManager;
private Context context;

public FlashlightProvider(Context context) {
    this.context = context;
}

private void turnFlashlightOn() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        try {
            camManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
            String cameraId = null; 
            if (camManager != null) {
                cameraId = camManager.getCameraIdList()[0];
                camManager.setTorchMode(cameraId, true);
            }
        } catch (CameraAccessException e) {
            Log.e(TAG, e.toString());
        }
    } else {
        mCamera = Camera.open();
        parameters = mCamera.getParameters();
        parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
        mCamera.setParameters(parameters);
        mCamera.startPreview();
    }
}

private void turnFlashlightOff() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        try {
            String cameraId;
            camManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
            if (camManager != null) {
                cameraId = camManager.getCameraIdList()[0]; // Usually front camera is at 0 position.
                camManager.setTorchMode(cameraId, false);
            }
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    } else {
        mCamera = Camera.open();
        parameters = mCamera.getParameters();
        parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
        mCamera.setParameters(parameters);
        mCamera.stopPreview();
    }
}
}

Try this.

CameraManager camManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
    String cameraId = null; // Usually front camera is at 0 position.
    try {
        cameraId = camManager.getCameraIdList()[0];
        camManager.setTorchMode(cameraId, true);
    } catch (CameraAccessException e) {
        e.printStackTrace();
    }

You can also use the following code to turn off the flash.

Camera.Parameters params = mCamera.getParameters()
p.setFlashMode(Parameters.FLASH_MODE_OFF);
mCamera.setParameters(params);

From my experience, if your application is designed to work in both portrait and landscape orientation, you need to declare the variable cam as static. Otherwise, onDestroy(), which is called on switching orientation, destroys it but doesn't release Camera so it's not possible to reopen it again.

package com.example.flashlight;

import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.os.Bundle;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.view.Menu;
import android.view.View;
import android.widget.Toast;

public class MainActivity extends Activity {

public static Camera cam = null;// has to be static, otherwise onDestroy() destroys it

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

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

public void flashLightOn(View view) {

    try {
        if (getPackageManager().hasSystemFeature(
                PackageManager.FEATURE_CAMERA_FLASH)) {
            cam = Camera.open();
            Parameters p = cam.getParameters();
            p.setFlashMode(Parameters.FLASH_MODE_TORCH);
            cam.setParameters(p);
            cam.startPreview();
        }
    } catch (Exception e) {
        e.printStackTrace();
        Toast.makeText(getBaseContext(), "Exception flashLightOn()",
                Toast.LENGTH_SHORT).show();
    }
}

public void flashLightOff(View view) {
    try {
        if (getPackageManager().hasSystemFeature(
                PackageManager.FEATURE_CAMERA_FLASH)) {
            cam.stopPreview();
            cam.release();
            cam = null;
        }
    } catch (Exception e) {
        e.printStackTrace();
        Toast.makeText(getBaseContext(), "Exception flashLightOff",
                Toast.LENGTH_SHORT).show();
    }
}
}

to manifest I had to put this line

    <uses-permission android:name="android.permission.CAMERA" />

from http://developer.android.com/reference/android/hardware/Camera.html

suggested lines above wasn't working for me.


I have implemented this function in my application through fragments using SurfaceView. The link to this stackoverflow question and its answer can be found here

Hope this helps :)


I Got AutoFlash light with below simple Three Steps.

  • I just added Camera and Flash Permission in Manifest.xml file
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />

<uses-permission android:name="android.permission.FLASHLIGHT"/>
<uses-feature android:name="android.hardware.camera.flash" android:required="false" />
  • In your Camera Code do this way.

    //Open Camera
    Camera  mCamera = Camera.open(); 
    
    //Get Camera Params for customisation
    Camera.Parameters parameters = mCamera.getParameters();
    
    //Check Whether device supports AutoFlash, If you YES then set AutoFlash
    List<String> flashModes = parameters.getSupportedFlashModes();
    if (flashModes.contains(android.hardware.Camera.Parameters.FLASH_MODE_AUTO))
    {
         parameters.setFlashMode(Parameters.FLASH_MODE_AUTO);
    }
    mCamera.setParameters(parameters);
    mCamera.startPreview();
    
  • Build + Run —> Now Go to Dim light area and Snap photo, you should get auto flash light if device supports.