I need to use only the flash with the API camera2 (Android 5, API level 21), like torch applications. But all the examples that I found requires the display of camera stream in a view
可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
回答1:
https://github.com/pinguo-yuyidong/Camera2/blob/master/app/src/main/java/us/yydcdut/androidltest/otheractivity/FlashActivity.java
here,you don't need the preview to open the flash.
回答2:
Just use following class to turn on/off FlashLight in Android L,
public class FlashLightUtilForL {
private CameraCaptureSession mSession;
private CaptureRequest.Builder mBuilder;
private CameraDevice mCameraDevice;
private CameraManager mCameraManager;
public FlashLightUtilForL(Context context) {
try {
mCameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
//here to judge if flash is available
CameraCharacteristics cameraCharacteristics = mCameraManager.getCameraCharacteristics("0");
boolean flashAvailable = cameraCharacteristics.get(CameraCharacteristics.FLASH_INFO_AVAILABLE);
if (flashAvailable) {
mCameraManager.openCamera("0", new MyCameraDeviceStateCallback(), null);
} else {
//todo: throw Exception
}
//mCameraManager.openCamera("0", new MyCameraDeviceStateCallback(), null);
} catch (Exception e) {
e.printStackTrace();
}
}
class MyCameraDeviceStateCallback extends CameraDevice.StateCallback {
@Override
public void onOpened(CameraDevice camera) {
mCameraDevice = camera;
//get builder
try {
mBuilder = camera.createCaptureRequest(CameraDevice.TEMPLATE_MANUAL);
//flash on, default is on
mBuilder.set(CaptureRequest.CONTROL_AE_MODE, CameraMetadata.CONTROL_AF_MODE_AUTO);
mBuilder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_TORCH);
List<Surface> list = new ArrayList<Surface>();
SurfaceTexture mSurfaceTexture = new SurfaceTexture(1);
Size size = getSmallestSize(mCameraDevice.getId());
mSurfaceTexture.setDefaultBufferSize(size.getWidth(), size.getHeight());
Surface mSurface = new Surface(mSurfaceTexture);
list.add(mSurface);
mBuilder.addTarget(mSurface);
camera.createCaptureSession(list, new MyCameraCaptureSessionStateCallback(), null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
@Override
public void onDisconnected(CameraDevice camera) {
}
@Override
public void onError(CameraDevice camera, int error) {
}
}
private Size getSmallestSize(String cameraId) throws CameraAccessException {
Size[] outputSizes = mCameraManager.getCameraCharacteristics(cameraId)
.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)
.getOutputSizes(SurfaceTexture.class);
if (outputSizes == null || outputSizes.length == 0) {
throw new IllegalStateException(
"Camera " + cameraId + "doesn't support any outputSize.");
}
Size chosen = outputSizes[0];
for (Size s : outputSizes) {
if (chosen.getWidth() >= s.getWidth() && chosen.getHeight() >= s.getHeight()) {
chosen = s;
}
}
return chosen;
}
/**
* session callback
*/
class MyCameraCaptureSessionStateCallback extends CameraCaptureSession.StateCallback {
@Override
public void onConfigured(CameraCaptureSession session) {
mSession = session;
try {
mSession.setRepeatingRequest(mBuilder.build(), null, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
@Override
public void onConfigureFailed(CameraCaptureSession session) {
}
}
public void turnOnFlashLight() {
try {
mBuilder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_TORCH);
mSession.setRepeatingRequest(mBuilder.build(), null, null);
} catch (Exception e) {
e.printStackTrace();
}
}
public void turnOffFlashLight() {
try {
mBuilder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_OFF);
mSession.setRepeatingRequest(mBuilder.build(), null, null);
} catch (Exception e) {
e.printStackTrace();
}
}
private void close() {
if (mCameraDevice == null || mSession == null) {
return;
}
mSession.close();
mCameraDevice.close();
mCameraDevice = null;
mSession = null;
}
}
回答3:
here is the complete demo check this.
package com.camera2;
import android.content.Context;
import android.graphics.SurfaceTexture;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CameraMetadata;
import android.hardware.camera2.CaptureRequest;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Size;
import android.view.Surface;
import android.view.View;
import android.widget.Button;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity
{
private CameraManager cameraManager;
private CameraCharacteristics cameraCharacteristics;
private CameraDevice mCameraDevice;
private CameraCaptureSession mSession;
private CaptureRequest.Builder mBuilder;
private Button on;
private Button off;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
on = (Button) findViewById(R.id.on);
off = (Button) findViewById(R.id.off);
initCamera();
}
public void click(View v)
{
switch (v.getId())
{
case R.id.on:
try
{
turnOnFlashLight();
}
catch (Exception e)
{
e.printStackTrace();
}
break;
case R.id.off:
turnOffFlashLight();
break;
}
}
private void initCamera()
{
cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
try
{
String[] id = cameraManager.getCameraIdList();
if (id != null && id.length > 0)
{
cameraCharacteristics = cameraManager.getCameraCharacteristics(id[0]);
boolean isFlash = cameraCharacteristics.get(CameraCharacteristics.FLASH_INFO_AVAILABLE);
if (isFlash)
{
cameraManager.openCamera(id[0], new MyCameraDeviceStateCallback(), null);
}
}
}
catch (CameraAccessException e)
{
e.printStackTrace();
}
}
class MyCameraDeviceStateCallback extends CameraDevice.StateCallback
{
@Override
public void onOpened(CameraDevice camera)
{
mCameraDevice = camera;
// get builder
try
{
mBuilder = camera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
List<Surface> list = new ArrayList<Surface>();
SurfaceTexture mSurfaceTexture = new SurfaceTexture(1);
Size size = getSmallestSize(mCameraDevice.getId());
mSurfaceTexture.setDefaultBufferSize(size.getWidth(), size.getHeight());
Surface mSurface = new Surface(mSurfaceTexture);
list.add(mSurface);
mBuilder.addTarget(mSurface);
camera.createCaptureSession(list, new MyCameraCaptureSessionStateCallback(), null);
}
catch (CameraAccessException e)
{
e.printStackTrace();
}
}
@Override
public void onDisconnected(CameraDevice camera)
{
}
@Override
public void onError(CameraDevice camera, int error)
{
}
}
private Size getSmallestSize(String cameraId) throws CameraAccessException
{
Size[] outputSizes = cameraManager.getCameraCharacteristics(cameraId).get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP).getOutputSizes(SurfaceTexture.class);
if (outputSizes == null || outputSizes.length == 0)
{
throw new IllegalStateException("Camera " + cameraId + "doesn't support any outputSize.");
}
Size chosen = outputSizes[0];
for (Size s : outputSizes)
{
if (chosen.getWidth() >= s.getWidth() && chosen.getHeight() >= s.getHeight())
{
chosen = s;
}
}
return chosen;
}
class MyCameraCaptureSessionStateCallback extends CameraCaptureSession.StateCallback
{
@Override
public void onConfigured(CameraCaptureSession session)
{
mSession = session;
try
{
mSession.setRepeatingRequest(mBuilder.build(), null, null);
}
catch (CameraAccessException e)
{
e.printStackTrace();
}
}
@Override
public void onConfigureFailed(CameraCaptureSession session)
{
}
}
public void turnOnFlashLight()
{
try
{
mBuilder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_TORCH);
mSession.setRepeatingRequest(mBuilder.build(), null, null);
}
catch (Exception e)
{
e.printStackTrace();
}
}
public void turnOffFlashLight()
{
try
{
mBuilder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_OFF);
mSession.setRepeatingRequest(mBuilder.build(), null, null);
}
catch (Exception e)
{
e.printStackTrace();
}
}
private void close()
{
if (mCameraDevice == null || mSession == null)
{
return;
}
mSession.close();
mCameraDevice.close();
mCameraDevice = null;
mSession = null;
}
}
xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
tools:context="com.camera2.MainActivity">
<Button
android:onClick="click"
android:id="@+id/on"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="On" />
<Button
android:onClick="click"
android:id="@+id/off"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Off" />
</LinearLayout>
manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.camera2">
<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" />
<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>
</manifest>
use close() to close camera settings
回答4:
Well, this worked perfectly for me:
public class MainActivity extends AppCompatActivity {
ToggleButton button;
boolean flashLightStatus = true;
boolean deviceHasCameraFlash = getPackageManager()
.hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button= (ToggleButton) findViewById(R.id.button);
FlashLightOn();//When app opens, turn it on.
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(deviceHasCameraFlash){
if(flashLightStatus){//when light on
FlashLightOff();//we should off
}
else //when light off
FlashLightOn();//we should on
}
else
Toast.makeText(MainActivity.this, "No flash available on your device.", Toast.LENGTH_SHORT).show();
}
});
}
private void FlashLightOn() {
CameraManager camManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
try{
String cameraId = camManager.getCameraIdList()[0]; // Usually front camera is at 0 position.
camManager.setTorchMode(cameraId, true);
flashLightStatus=true;
} catch (Exception e){
}
}
private void FlashLightOff() {
CameraManager camManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
try{
String cameraId = camManager.getCameraIdList()[0]; // Usually front camera is at 0 position.
camManager.setTorchMode(cameraId, false);
flashLightStatus=false;
} catch (Exception e){
}
}
}