【问题标题】:Android 5, camera2 use only flashAndroid 5,camera2 只使用闪光灯
【发布时间】:2014-12-11 10:28:40
【问题描述】:

我只需要使用带有 API camera2(Android 5,API 级别 21)的闪光灯,例如手电筒应用程序。 但是我发现的所有示例都需要在视图中显示相机流

【问题讨论】:

    标签: java camera android-5.0-lollipop


    【解决方案1】:
    【解决方案2】:

    只需使用以下类在 Android L 中打开/关闭 FlashLight,

    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;
        }
    }
    

    【讨论】:

    • 我试试你的源代码:FlashLightUtilForL flash = new FlashLightUtilForL(getActivity().getBaseContext()); if(flashIsOn){ flash.turnOffFlashLight(); flashIsOn = 假; }else{ flash.turnOnFlashLight(); flashIsOn =真;但我不能关闭如果关闭。请问有什么解决办法。
    • 在制作对象时更改上下文,例如 FlashLightUtilForL flash = new FlashLightUtilForL(this);它可能会帮助你。
    • 我在一个fragment,问题是关掉,打开就ok了
    • 在制作对象时更改上下文,例如 FlashLightUtilForL flash = new FlashLightUtilForL(getActivity());它可能会帮助你。
    • 是的,我遇到了你的问题。首先将 close() 方法从私有变为公共。然后首先调用 turnOffFlashLight(),然后调用 close() 方法。我希望它对你有用。
    【解决方案3】:

    这是完整的演示检查。

    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>
    

    清单

    <?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>
    

    使用 close() 关闭相机设置

    【讨论】:

      【解决方案4】:

      嗯,这对我来说非常有效:

      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){
      
              }
          }
      }
      

      【讨论】:

      • 必须添加 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-31
      相关资源
      最近更新 更多