如何在Android中以编程方式打开前闪光灯?


233

我想在Android中以编程方式打开前闪光灯(不使用相机预览)。我用Google搜索,但是找到的帮助使我转至此页面

有人有任何链接或示例代码吗?

Answers:


401

对于此问题,您应该:

  1. 检查手电筒是否可用?

  2. 如果是这样,请关闭/打开

  3. 如果没有,那么您可以根据您的应用程序需求执行任何操作。

对于检查设备中闪存的可用性

您可以使用以下内容:

 context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);

如果有闪存可用,则返回true,否则返回false。

有关更多信息,请参见:
http : //developer.android.com/reference/android/content/pm/PackageManager.html

对于打开/关闭手电筒:

我用谷歌搜索了有关android.permission.FLASHLIGHT的内容。Android清单的许可看起来很有希望:

 <!-- Allows access to the flashlight -->
 <permission android:name="android.permission.FLASHLIGHT"
             android:permissionGroup="android.permission-group.HARDWARE_CONTROLS"
             android:protectionLevel="normal"
             android:label="@string/permlab_flashlight"
             android:description="@string/permdesc_flashlight" />

然后使用Camera并设置Camera.Parameters。这里使用的主要参数是FLASH_MODE_TORCH

例如。

代码段可打开相机手电筒。

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

代码段可关闭相机LED灯。

  cam.stopPreview();
  cam.release();

我刚刚找到一个使用此权限的项目。检查快速设置的src代码。此处http://code.google.com/p/quick-settings/(注意:此链接现在已断开)

对于Flashlight,请直接查看 http://code.google.com/p/quick-settings/source/browse/trunk/quick-settings/#quick-settings/src/com/bwx/bequick/flashlight(注意:此链接为现在坏了)

Update6 您也可以尝试按此答案在Galaxy Nexus上添加一个SurfaceView中所述的SurfaceView,该手电可由什么API控制? 这似乎是可在许多手机上使用的解决方案。

更新5主要更新

我找到了一个替代链接(针对上面的断开链接):http : //www.java2s.com/Open-Source/Android/Tools/quick-settings/com.bwx.bequick.flashlight.htm您现在可以使用此链接链接。[更新:2012年9月14日,此链接现已断开]

更新1

另一个开源代码:http : //code.google.com/p/torch/source/browse/

更新2

显示如何在Motorola Droid上启用LED的示例:http : //code.google.com/p/droidled/

另一个开源代码:

http://code.google.com/p/covedesigndev/
http://code.google.com/p/search-light/

更新3(用于打开/关闭相机LED的小部件)

如果您要开发一个打开/关闭相机LED的小部件,则必须参考我的答案 Widget,以在android中打开/关闭相机手电筒

更新4

如果要设置相机LED发出的光的强度,可以参考我可以更改Android设备的LED强度吗?满员。请注意,只有植根的HTC设备才支持此功能。

**问题:**

打开/关闭手电筒时也有一些问题。例如。对于没有FLASH_MODE_TORCH或什至没有的设备,手电筒不会打开等。

通常,三星会产生很多问题。

您可以在下面的列表中参考问题:

在Android中使用相机手电筒

在Samsung Galaxy Ace 2.2.1和Galaxy Tab中打开/关闭相机LED /闪光灯


2
感谢您的帮助,它对我有用!-我只是复制了接口Flashlight和类HtcLedFlashlight,然后仅使用true / false HtcLedFlashlight及其它调用setOn方法。---接口手电筒code.google.com/p/quick-settings/source/browse/trunk/... -类HtcLedFlashlight code.google.com/p/quick-settings/source/browse/trunk/...
saiket 2011年

1
@saiket:欢迎..如果您的问题解决了,则将此答案标记为已解决。因此,它可以对他人有用..
卡尔蒂克Domadiya

1
@PolamReddyRajaReddy:我认为您正在三星设备中进行测试。我对么 ?
Kartik Domadiya 2011年

7
对于权限,清单文件中的正确代码是:`<uses-permission android:name =“ android.permission.CAMERA” /> <uses-permission android:name =“ android.permission.FLASHLIGHT” />`
ixeft

1
还可以使用:-camera.release();

35

根据我的经验,如果您的应用程序设计为既可以纵向又可以横向使用,则需要将变量声明cam为static。否则,onDestroy()在切换方向时称为的会破坏它,但不会释放Camera,因此无法再次将其重新打开。

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

表现出我不得不把这条线

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

来自http://developer.android.com/reference/android/hardware/Camera.html

上述建议行对我不起作用。


如果相机关闭,则无需检查系统功能。如果cam!= null,则将其打开
Greg Ennis

1
对我来说最有帮助的部分是you need to declare the variable cam as static
Alex Jolig

当导入Camera班级时AndroidStudio 注意成为android.hardware班级...
AN

32

在API 23或更高版本中(Android M,6.0)

打开代码

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

关闭代码

camManager.setTorchMode(cameraId, false);

和权限

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

附加编辑

人们仍然支持我的答案,因此我决定发布其他代码这是我当时解决该问题的方法:

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

2
“通常前置摄像头位于0位置”是什么意思?我该如何检查哪个在前面?顺便说一句,前置摄像头是针对当前用户的。背面摄像头可能总是带有闪光灯。以及如何检查闪光灯是打开还是关闭?
Android开发人员

13

我通过以下简单的三个步骤获得了自动闪光指示灯。

  • 我刚刚在Manifest.xml文件中添加了Camera and Flash Permission
<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" />
  • 在您的相机代码中执行此操作。

    //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(构建+运行)->现在转到Dim light区域和Snap photo,如果设备支持,您应该获得自动闪光灯。


9

Android Lollipop引入了camera2 API,并弃用了之前的camera API。但是,使用不推荐使用的API来打开闪光灯仍然可以使用,并且比使用新的API简单得多。

新的API似乎旨在用于专用的全功能相机应用程序,并且其架构师并未真正考虑更简单的用例,例如打开手电筒。现在要做的是,必须获得CameraManager,使用虚拟的Surface创建一个CaptureSession,最后创建并启动一个CaptureRequest。包括异常处理,资源清理和长回调!

若要查看如何在Lollipop和更高版本上打开手电筒,请查看AOSP项目中的FlashlightController(尝试查找已被修改的最新的较旧使用的API)。不要忘记设置所需的权限。


Android Marshmallow最终引入了一种简单的方法,可以使用setTorchMode打开闪光灯。


1
旧的android.hardware.Camera API仍然可以像以前一样正常运行,因此您根本不需要将android.hardware.camera2用于手电筒。不过,由于无需保持活动预览来启用手电筒,因此使用camera2可以降低功耗和CPU负载。
Eddy Talvala 2015年

我已经在两个Lollipop设备上尝试了一种较简单的实现,即使它在我尝试过的所有Lollipop之前的所有设备上都可以工作,它也没有打开闪存。也许那只是Lollipop中的错误。如果旧方法仍然对您
有用

我目前有配备Lollipop的Nexus 5,它的运行效果非常好。我还拥有一个由我自己的作品创建的应用程序,并通过这些方法实现。万一有人想尝试。我放置了一个播放商店的链接:play.google.com/store/apps/details?id=com.fadad.linterna 重要的是,在运行闪光灯和权限之前,请务必确保相机处于活动状态或禁用状态。
ferdiado

抱歉,是我的错。当我尝试使用旧的API打开闪光灯时,另一个应用程序可能正在使用相机。我已经更新了答案。
LukaCiko

7

android Flashlight App的完整代码

表现

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

  }

如果在开始您的示例之前闪光灯已经打开,则尝试关闭闪光灯将不起作用...您有解决该问题的方法吗?
Taifun '17

7

在不同的Android版本中,有多种访问Camera Flash的方法。很少有API在Lollipop中停止工作,然后在棉花糖中再次更改。为了克服这个问题,我创建了一个简单的库,该库已在我的几个项目中使用,并且效果良好。它仍然不完整,但是您可以尝试检查代码并找到缺失的部分。这是链接-NoobCameraFlash

如果您只想集成到代码中,则可以使用gradle。这是说明(直接来自自述文件)-

步骤1.将JitPack存储库添加到您的构建文件中。将其添加到存储库末尾的root build.gradle中:

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

步骤2.添加依赖性

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

用法

初始化NoobCameraManager单例。

NoobCameraManager.getInstance().init(this);

您可以选择设置日志级别以进行调试日志记录。记录使用LumberJack库。默认的LogLevel为LogLevel.None

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

之后,您只需要呼叫单身人士即可打开或关闭相机闪光灯。

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

在初始化NoobCameraManager之前,您必须注意运行时权限才能自己访问Camera。在0.1.2或更早版本中,我们曾经直接从库中提供对权限的支持,但是由于对Activity对象的依赖,我们必须将其删除。

切换Flash也很容易

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

请添加对使用上下文而不是活动的支持。谢谢!
Vajira Lasantha

@VajiraLasantha要获得许可,必须使用Activity对象。我打算通过某种方式分离权限来完全删除需求。它已在此处跟踪-github.com/Abhi347/NoobCameraFlash/issues/3 同时,您可以根据需要修改代码以删除要求。我可能需要一些时间来处理它。
noob

是的,我看到了。我已经通过删除权限内容更改了您的lib以使用Context。因为我的应用程序已经在进行权限验证。当您发布支持Context的正确实现时,请告诉我。谢谢!
Vajira Lasantha

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.
Pratik Butani

如果设备上多次闪烁怎么办?有些在前置摄像
Android开发人员


0

在棉花糖及更高版本中,CameraManager的“ setTorchMode()”似乎是答案。这对我有用:

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

0

试试这个。

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

-3

您还可以使用以下代码关闭闪光灯。

Camera.Parameters params = mCamera.getParameters()
p.setFlashMode(Parameters.FLASH_MODE_OFF);
mCamera.setParameters(params);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.