Android 手电筒制作

一、SystemUI中手电筒的控制

推荐:Android QuickSetting—手电筒控制

通过手机下拉状态栏,可以找到手电筒图标。也就是说SystemUI中存在控制手电筒的代码。

SystemUI源码路径:

frameworks\base\packages\SystemUI

找到SystemUI中关于对手电筒控制相应类的位置:

\frameworks\base\packages\SystemUI\src\com\android\systemui\qs\tiles\FlashlightTile.java
/** Quick settings tile: Control flashlight **/
public class FlashlightTile extends QSTileImpl<BooleanState> implementsFlashlightController.FlashlightListener {@Overrideprotected void handleClick() {if (ActivityManager.isUserAMonkey()) {return;}boolean newState = !mState.value;//调用QSTileImpl的refreshState方法,更新下拉状态栏状态refreshState(newState);//通过FlashlightController设置手电筒开或关mFlashlightController.setFlashlight(newState);}
}

FlashlightController 源码位于:

frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\policy\FlashlightController.java
public interface FlashlightController extends CallbackController<FlashlightListener>, Dumpable

这是一个接口类,具体实现在FlashlightControllerImpl中:

public class FlashlightControllerImpl implements FlashlightController{private final CameraManager mCameraManager;public FlashlightControllerImpl(Context context) {mContext = context;mCameraManager = (CameraManager) mContext.getSystemService(Context.CAMERA_SERVICE);tryInitCamera();}private void tryInitCamera() {try {mCameraId = getCameraId();} catch (Throwable e) {Log.e(TAG, "Couldn't initialize.", e);return;}if (mCameraId != null) {ensureHandler();mCameraManager.registerTorchCallback(mTorchCallback, mHandler);}}
}

初始化了CameraManager,通过相机控制操作手电筒开关。

在setFlashlight方法中控制手电筒开关。

  public void setFlashlight(boolean enabled) {boolean pendingError = false;synchronized (this) {if (mCameraId == null) return;if (mFlashlightEnabled != enabled) {mFlashlightEnabled = enabled;try {//使用setTorchMode方法控制mCameraManager.setTorchMode(mCameraId, enabled);} catch (CameraAccessException e) {Log.e(TAG, "Couldn't set torch mode", e);mFlashlightEnabled = false;pendingError = true;}}}dispatchModeChanged(mFlashlightEnabled);if (pendingError) {dispatchError();}}

二、制作简单手电筒

1、布局

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><ImageViewandroid:id="@+id/open_button"android:layout_width="match_parent"android:layout_height="match_parent"android:src="@drawable/openbutton"/>
</LinearLayout>

直接在主方法布局文件中布局,放置一张按钮图片。

2、声明权限

android.permission.FLASHLIGHT
允许访问闪光灯

(不声明权限,好像也行,当然加上最好)

//用于5之前,已过时
<uses-permission android:name="android.hardware.camera" />

3、主要代码

oncreate

private CameraManager mCameraManager = null;
private boolean FlashlightEnable = true;
private static ImageView imageButton;
private boolean imageStatues = true;
private String mCameraId = "0";
private static int count = 0;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//初始化initView();//获得mCameraManager对象this.mCameraManager = (CameraManager) getApplication().getSystemService(Context.CAMERA_SERVICE);//获得CameraID,注册手电筒回调tryInitCamera();//默认开启程序,打开手电筒openFlashlight();imageButton.setImageResource(R.drawable.opening);}private void initView() {imageButton = findViewById(R.id.open_button);imageButton.setOnClickListener(this);tryInitCamera();}//获得CameraID,注册手电筒回调private void tryInitCamera() {try {mCameraId = getCameraId();} catch (Throwable e) {Log.e(TAG, "Couldn't initialize.", e);return;}if (mCameraId != null) {mCameraManager.registerTorchCallback(mTorchCallback, null);}}private String getCameraId() throws CameraAccessException {String[] ids = mCameraManager.getCameraIdList();for (String id : ids) {CameraCharacteristics c = mCameraManager.getCameraCharacteristics(id);Boolean flashAvailable = c.get(CameraCharacteristics.FLASH_INFO_AVAILABLE);Integer lensFacing = c.get(CameraCharacteristics.LENS_FACING);if (flashAvailable != null && flashAvailable&& lensFacing != null && lensFacing == CameraCharacteristics.LENS_FACING_BACK) {return id;}}return null;}@Overridepublic void onClick(View v) {if (imageStatues) {closeFlashlight();imageButton.setImageResource(R.drawable.openbutton);} else {openFlashlight();imageButton.setImageResource(R.drawable.opening);}imageStatues = !imageStatues;}

此方法中

  1. 给按钮图片赋值,并设置点击事件监听,每次点击切换图片,并打开或关闭手电筒。
  2. 通过getApplication().getSystemService(Context.CAMERA_SERVICE);获得CameraManager对象。
  3. tryInitCamera()方法中,获得CameraID与registerTorchCallback。
  4. 默认点开应用即打开手电筒。(可自定义)

CameraManager对象用于后面对手电筒的开关。

CameraId在此事实上并不需要去获得,直接给一个值即可。

例:private String mCameraId = "0";

TorchCallback:

private final CameraManager.TorchCallback mTorchCallback =new CameraManager.TorchCallback() {@Overridepublic void onTorchModeUnavailable(String cameraId) {FlashlightEnable = false;if (imageStatues) {imageStatues = false;change();}}@Overridepublic void onTorchModeChanged(@NonNull String cameraId, boolean enabled) {super.onTorchModeChanged(cameraId, enabled);if (count++==1){return;}if (FlashlightEnable != enabled) {FlashlightEnable = enabled;}if (imageStatues != enabled) {imageStatues = enabled;change();}}};

通过TorchCallback监听手电筒是否可用与状态变化。

onTorchModeChanged方法在启动程序时会调用两次,

第一次cameraId是我们的id(获得到为0),enabled是当前手机手电筒状态

第二次cameraId为2,暂未知代表何意,enabled为false,与当前手电筒状态不同步,与cameraId为0的enable无关。

由此,可以设置判断,只有当监听到的是自己的id时,去同步参数。

通过自设change()方法去同步改变应用图片。

private void change() {if (imageStatues) {imageButton.setImageResource(R.drawable.opening);} else {imageButton.setImageResource(R.drawable.openbutton);}}

open&close:

 private void openFlashlight() {try {if (mCameraManager != null) {mCameraManager.setTorchMode(mCameraId, true);}} catch (CameraAccessException e) {e.printStackTrace();}}private void closeFlashlight() {try {if (mCameraManager != null) {mCameraManager.setTorchMode(mCameraId, false);}} catch (CameraAccessException e) {e.printStackTrace();}}

主要通过mCameraManager的setTorchMode()方法去控制手电筒状态。

Android 5之前可使用:

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

开启或关闭手电筒。

后记:

如果在打开应用之后,不做任何操作,直接点Recent(显示最近使用应用)页面,在此关掉的话。onDestory()偶尔并不调用。(本机打log查看,大部分时候无onDestory方法log日志)。

这种情况,如果未开启应用前在SystemUI状态栏中打开手电筒,在打开应用不进行任何操作,之后直接在Recent页面,关掉应用,导致手电筒不关闭。

设置应用打开后的默认状态(即开启默认打开或者关闭一次手电筒)后,onDestory()方法正常被调用,上述现象不在出现。

找到另一篇关于onDestory的介绍:

安卓 后台杀死进程,OnDestroy会执行吗?

扩展:

Android使用Camera2 替代过时的Camera API

在Android 5(API 21,Lollipop)以前,获得相机权限只需要在 AndroidManifest.xml文件里面添加权限就可以用了 。5之后的版本, 允许用户单独管理应用的某个权限,打开或者关闭 。使用相机需要判断是否有权限,没有就需要申请权限。

相机的闪光灯,在相机打开后,在外部会变成不可用状态。也就是说,想要使用闪光灯(手电筒用的就是闪光灯),就需要相机是关闭状态。此处不需要去申请权限。

《SystemUI》限制低电量打开手电筒

Camera2 闪光灯梳理

gitee:https://gitee.com/TongYing1652/torch-test

Android手电筒制作相关推荐

  1. [Android] 如何制作手电筒程序

    继iphone的手电筒开发完成后,接下来我便著手开始Android如何制作手电筒的程序 我的跨平台引擎框架CloudBox已建立好iphone版的程序,但却对于Android上如何操控闪光灯一无所知 ...

  2. android简单手电筒,android 简单的手电筒制作

    这里给出一个简单的手电筒制作的源码: 1,xml布局: 2.,Actity代码: package com.diecolor; import android.app.Activity; import a ...

  3. 怎么用Android做登录界面,利用Android怎么制作一个APP登录界面

    利用Android怎么制作一个APP登录界面 发布时间:2020-12-02 17:09:10 来源:亿速云 阅读:79 作者:Leah 这期内容当中小编将会给大家带来有关利用Android怎么制作一 ...

  4. android页面布局计算机,Android Studio制作简单计算器App

    Android Studio制作简单计算器App 计算机界面如图: 程序设计步骤: (1)在布局文件中声明编辑文件框EditText,按钮Button等组件. (2)在MainActivity中获取组 ...

  5. Android Studio制作.9图片,看这一篇就够了

    一..9.png图片概念 这是安卓开发里面的一种特殊的图片 这种格式的图片在android 环境下具有自适应调节大小的能力,不会失真 (1)允许开发人员定义可扩展区域,当需要延伸图片以填充比图片本身更 ...

  6. Lottie Android 动画制作与使用

    Lottie Android 动画制作与使用 还未了解Lottie的同志,请观看我上篇文章: Lottie Android 初探 一.效果图预览 二.Adobe After Effects安装 作为I ...

  7. Android Studio 制作微信界面 上

    工程功能介绍 打开app,首先是个闪屏界面(常见于一般打开app时的小广告),设置时间为2s后进入登录界面.在登录界面中,中间可以输入密码,点击登录按钮进入微信的界面.   微信的界面由4个fragm ...

  8. 基于Android Tv制作一个Tv桌面(二)

    标题基于Android Tv制作一个Tv桌面(二) 这里是获取APP的各种信息,不知道为什么这一步只能在主类MainActivity 上进行,不能在其他的类进行此操作,也许是我见识短浅的原因吧,因为其 ...

  9. Android studio制作计算器源代码

    版权声明:本文为博主原创文章,未经博主允许不得转载.https://mp.csdn.net/postedit/82623704 一.Android studio制作计算器源代码 这是我学Android ...

最新文章

  1. HDU 1011-Starship Troopers(树形背包)
  2. ERP与EWM集成配置-ERP端组织架构(二)
  3. Exchange对AD的访问
  4. python处理excel教程实例-Python玩转Excel的读写改实例
  5. 杭电OJ1069java实现
  6. 按平均成绩排行c语言文件操作,学生成绩管理系统(c语言结构体以及文件操作)实验报告精选.doc...
  7. lol韩服游戏内设置_LOL手游:灵药战队有多强?辅助国际服第六,AD堪比UZI
  8. ★☆★书已到手《Java程序员,上班那点事儿》正式上架★☆★
  9. 计算机科学名词,计算机科学中的术语(1)
  10. python入门经典书书籍-新手Python入门经典书籍推荐
  11. 要是卢安娜的飓风可以触发所有远程英雄的技能,哪些英雄最强?
  12. ios开发App的图标背景色不能是透明
  13. 很常用的倒计时脚本,可任意设置时…
  14. xshell免费版 正版,非xshell破解版
  15. numpy序列预处理dna序列_使用机器学习和Python揭开DNA测序神秘面纱
  16. “云”溪笔谈 | 走完过渡期“沉浸式视频云”时代来临
  17. platform driver注册过程
  18. 远控免杀从入门到实践(3)-代码篇-C/C++
  19. K12教培老师在新政下面临失业,该何去何从?
  20. 基于matlab实现MSK的调制与解调

热门文章

  1. VSCode编辑器中对PHP语言的支持
  2. [再寄小读者之数学篇](2014-11-02 Herglotz' trick)
  3. 首个仿生机器人亮相 有人造器官与血液
  4. http://www.iefans.net/ie6-ie7-ie8-ieduobanben
  5. 人脸识别评价参数之FAR和FRR
  6. 办公软件 office
  7. Facebook新财报:不惧“隐私门“事件影响,广告业务依然增长强劲
  8. Android图文混排(仿QQ空间评论)
  9. Visual Studio打开文件时出现“向程序发送命令时出现问题
  10. pap认证过程_思科课件8、PAP认证、CHAP认证