4

I am making a simple application that acts as a flashlight. I need to be able to turn on and off the flash from a button in the application with the Camera2 API, as I get errors with the old camera API. I would like to use a "torch" flashlight, where the camera doesn't have to open in order for the flash to turn on. I know it's possible, as lots of phones have a flash on/off in the quick settings menu, but I can't find any code or tutorials about how to do this.

Code:

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

I am running on a Nexus 6P with Android 6.0.1.

EDIT: I need to use the Camera2 API. I haven't found a good tutorial for this yet, and after getting an answer, I will create one in Q/A format on here.

Cœur
  • 37,241
  • 25
  • 195
  • 267
Benjamin Owen
  • 608
  • 2
  • 10
  • 28
  • 1
    check out this link might help you.http://stackoverflow.com/questions/6068803/how-to-turn-on-camera-flash-light-programmatically-in-android – Kristo Jan 09 '16 at 21:45
  • I've used that exact code :P. That was the first question I found and I get the error: `An error occurred while connecting to camera: 0` – Benjamin Owen Jan 09 '16 at 21:46
  • error occured? are you sutre that you had all required – piotrek1543 Jan 09 '16 at 21:51
  • Yes. Both permissions for camera and both for Android.hardware. – Benjamin Owen Jan 09 '16 at 21:52
  • can you paste the code that you are using in here please so we might see if you used it correctly. – Daniel Netzer Jan 14 '16 at 14:47
  • Post edited with code. – Benjamin Owen Jan 14 '16 at 14:49
  • you are aware that Camera class wont work on API's above 21 right? besides that let me read abit about the new cameraManager and ill post an answer in abit. – Daniel Netzer Jan 14 '16 at 14:52
  • I know the Camera API doesn't work on the newer versions of Android. I just haven't found a good tutorial for the Camera2 API. I'll look at the Android Developer documentation and see if I can scrape anything off of that. – Benjamin Owen Jan 14 '16 at 14:55
  • The Camera API works fine past API21, even though it is marked as deprecated. The issue here is that there is no preview surface provided with Camera.setPreviewDisplay() or Camera.setPreviewTexture(), which is mandatory before preview can be started on most Android devices. Some devices work anyway, leading to confusion. – Eddy Talvala Jan 15 '16 at 00:02
  • I got errors when using it... – Benjamin Owen Jan 15 '16 at 00:03

4 Answers4

21

I'll be addressing you to the Android Dev. documentation about the CameraManager since more code will be required but this is the basic code to activate the Flash on the camera in API's above 21.

CameraManager camManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
String cameraId = camManager.getCameraIdList()[0]; // Usually front camera is at 0 position.
camManager.setTorchMode(cameraId, true);

Android CameraManager documentation.

Android.hardware.camera2 documentation.

very important thing to remember that you will need to use try/catch to discard possible errors and ofcourse check that no other higher priority application is using the camera at the moment.

Daniel Netzer
  • 2,151
  • 14
  • 22
  • Is the rear camera (the one with the flash) in position 1? – Benjamin Owen Jan 14 '16 at 16:16
  • im sry I was talking about the rear camera, but you can always test it and if you read the documentation you can also getCameraProperties and see if that specific camera have a Flash attached or not, small tip for coding, always read the documentation and play with it as practice. – Daniel Netzer Jan 14 '16 at 16:17
  • Ok. I'll try to get the full list and edit it to my post. I'm testing your code now... – Benjamin Owen Jan 14 '16 at 16:18
  • It works! I will be editing the original post with the full code to support Lollipop and older API levels. (For those who don't want to only support 5.0+ like me) – Benjamin Owen Jan 14 '16 at 16:24
  • please mark this as an answer if that works, your welcome. :D – Daniel Netzer Jan 14 '16 at 16:26
  • So I get the error that the class is not found on my older device...`Could not find class 'android.hardware.camera2.CameraManager'`. Is there a way I can tell it to ignore that? (I'm skipping that code if the SDK version is too low. – Benjamin Owen Jan 14 '16 at 17:08
  • there is a way to define for the application to use diffrent kinds of codes per API, try and google it my friend or open a new question, its a whole diffrent subject – Daniel Netzer Jan 14 '16 at 17:53
  • I already created code to handle that, I created a different question at http://stackoverflow.com/questions/34796383/android-fail-to-connect-to-camera-service for my problem. Thanks for all of your help! – Benjamin Owen Jan 14 '16 at 17:54
  • How to be turn off the flash – hem May 02 '17 at 09:34
  • @hem : For turning off the camera , just pass false in setTorchMode() - camManager.setTorchMode(cameraId, false); – BinaryGuy Jul 31 '17 at 11:29
2
 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    mCameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
    try {
        for (String camID : mCameraManager.getCameraIdList()) {
            CameraCharacteristics cameraCharacteristics = mCameraManager.getCameraCharacteristics(camID);
            int lensFacing = cameraCharacteristics.get(CameraCharacteristics.LENS_FACING);
            if (lensFacing == CameraCharacteristics.LENS_FACING_FRONT && cameraCharacteristics.get(CameraCharacteristics.FLASH_INFO_AVAILABLE)) {
                mCameraId = camID;
                break;
            } else if (lensFacing == CameraCharacteristics.LENS_FACING_BACK && cameraCharacteristics.get(CameraCharacteristics.FLASH_INFO_AVAILABLE)) {
                mCameraId = camID;
            }
        }
        if (mCameraId != null) {
            mCameraManager.setTorchMode(mCameraId, true);
        }
    } catch (CameraAccessException e) {
        e.printStackTrace();
    }
}

mCameraId will preferably turn on front camera flash by priority and if there is no front flash then back camera flash will be used. If device has no flash then mCameraId will be null and setTorchMode will not be called in the code above.

LokiDroid
  • 972
  • 10
  • 22
1

Try this. Is working fine on me for android Pie and above. There is a toggle button that turns on and off the flashlight

    ToggleButton FlB = (ToggleButton) findViewById(R.id.FlashBt);

    final boolean[] IsTurnedOn = {false};
    final CameraManager camManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
    String cameraId = null; // Usually front camera is at 0 position.
    try {
        cameraId = camManager.getCameraIdList()[0];
    } catch (CameraAccessException e) {
        e.printStackTrace();
    }
    final String finalCameraId = cameraId;

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

            if (!IsTurnedOn[0]){
                try {
                    camManager.setTorchMode(finalCameraId, true);
                } catch (CameraAccessException e) {
                    e.printStackTrace();
                }
            }
            else {
                try {
                    camManager.setTorchMode(finalCameraId, false);
                } catch (CameraAccessException e) {
                    e.printStackTrace();
                }
            }
            IsTurnedOn[0] =!IsTurnedOn[0];

        }
    });
Apollon
  • 311
  • 7
  • 29
-1

Simplest and most banal way to do a flashlight app

// xml code

<?xml version="1.0" encoding="utf-8"?>
<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:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.android.torcia.MainActivity">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="ON"
        android:id="@+id/flash_button"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true"
        android:onClick="turnOnOff"/>
</RelativeLayout>

//java code

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    Button flashButton;
    String buttonText;

    public void checkState(String buttonText) {


        switch (buttonText) {

            case "ON":

                flashButton.setText("OFF");
                flashOn();

                break;

            case "OFF":

                flashButton.setText("ON");
                flashOff();

                break;
        }
    }


    public void turnOnOff(View view) {

        flashButton = (Button) findViewById(R.id.flash_button);
        buttonText = flashButton.getText().toString();
        checkState(this.buttonText);

    }

    public void flashOn() {

        Camera camera = Camera.open();
        Camera.Parameters parameters = camera.getParameters();
        parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
        camera.setParameters(parameters);
        camera.startPreview();

    }


    public void flashOff() {

        Camera camera2 = Camera.open();
        Camera.Parameters parameters2 = camera2.getParameters();
        parameters2.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
        camera2.setParameters(parameters2);
        camera2.stopPreview();

    }


}

// AndroidManifest

<?xml version="1.0" encoding="utf-8"?>

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

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">

    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

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

leolHC
  • 31
  • 2
  • 2
    This is not the correct way to use the API, even though this will work on many devices. The API requires that you set a preview target before calling startPreview, and that is enforced on many devices (such as all newer Nexus phones). – Eddy Talvala Sep 17 '16 at 00:31
  • 4
    It is incorrect answer! Question is about newer Camera2 API, but answer uses older camera API version. – Ayaz Alifov Apr 27 '17 at 13:30