Android13锁屏或灭屏状态下,快速按两次音量下键实现打开闪光灯功能

embedded/2024/10/18 19:25:42/

实现思路:

1、发送广播

    WindowManagerService循环读取下面按键消息并分发给窗口,在消息分发前会在PhoneWindowManager.interceptKeyBeforeQueueing方法中进行消息的过滤。因此该实现方式为在消息分发前的interceptKeyBeforeQueueing方法中监听当前按键为音量下键,如果当前状态为锁屏状态,并按键为音量下键,且两次按键间隔时间小于800ms时发送广播--“com.custom.volume_down”

具体实现方式如下:

sys\frameworks\base\services\core\java\com\android\server\policy\PhoneWindowManager.java

private long lastTime = 0;@Override
public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) {final int keyCode = event.getKeyCode();final boolean down = event.getAction() == KeyEvent.ACTION_DOWN;......switch (keyCode) {......case KeyEvent.KEYCODE_VOLUME_DOWN:// add startString volume_down = SystemProperties.get("persist.sys.double.volume_down");if (DEBUG_INPUT) {Log.i(TAG, "interceptKeyBeforeQueueing:"+ " VOLUME KEYCODE_VOLUME_DOWN"+ " volume_down = " + volume_down+ " keyguardActive = " + keyguardActive+ " lastTime = " + lastTime);}if (down) { //按键按下if (volume_down != null && !volume_down.equals("0")) {if (keyguardActive) {//锁屏if (System.currentTimeMillis() - lastTime <= 800) {mContext.sendBroadcast(new Intent("com.custom.volume_down"));lastTime = 0;} else {lastTime = System.currentTimeMillis();}return 0;}}}// add endcase KeyEvent.KEYCODE_VOLUME_UP:......

2、接收广播

接收到广播“com.custom.volume_down”后打开或关闭闪光灯

private CameraManager mCameraManager;
private boolean mFlashlightEnabled = false;private String mCameraId;
private Handler mHandler;
private void initBroadcastReceiver(Context context) {mCameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);tryInitCamera();IntentFilter filter = new IntentFilter();filter.addAction("com.custom.volume_down");context.registerReceiver(new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();LogUtils.i(TAG, "action = " + action);if (action != null) {if (action.equals("com.custom.volume_down")) {String volume_down =     SysProUtils.get("persist.sys.double.volume_down");LogUtils.i(TAG, "volume_down = " + volume_down);if (volume_down != null) {if (volume_down.equals("1")) {setFlashlight(!mFlashlightEnabled);}}}}}}, filter);
}private synchronized void ensureHandler() {if (mHandler == null) {HandlerThread thread = new HandlerThread(TAG, Process.THREAD_PRIORITY_BACKGROUND);thread.start();mHandler = new Handler(thread.getLooper());}
}public void setFlashlight(boolean enabled) {synchronized (this) {if (mCameraId == null) return;if (mFlashlightEnabled != enabled) {mFlashlightEnabled = enabled;try {mCameraManager.setTorchMode(mCameraId, enabled);} catch (CameraAccessException e) {Log.e(TAG, "Couldn't set torch mode", e);mFlashlightEnabled = false;}}}
}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;
}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);}
}private final CameraManager.TorchCallback mTorchCallback =new CameraManager.TorchCallback() {@Override@WorkerThreadpublic void onTorchModeChanged(String cameraId, boolean enabled) {if (TextUtils.equals(cameraId, mCameraId)) {setTorchMode(enabled);}}};private void setTorchMode(boolean enabled) {synchronized (CommModule.this) {mFlashlightEnabled = enabled;}
}

3、在settings源码中添加控制

在settings中添加开关按钮。

如果打开开关,双击音量下键,打开或关闭闪光灯。

如果关闭开关,双击音量下键,不做任何处理。

在res/xml/accessibility_settings.xml中添加

+        <SwitchPreference
+            android:key="accessibility_flashlight"
+            android:persistent="false"
+            android:icon="@drawable/ic_flashlight"
+            android:summary="@string/accessibility_settings_flashlight_summary"
+            android:title="@string/accessibility_settings_flashlight_preference_title"
+            settings:searchable="true"
+            settings:controller="com.android.settings.accessibility.FlashlightPreferenceController"/>

在app\src\main\java\com\android\settings\accessibility目录下新建FlashlightPreferenceController.java

package com.android.settings.accessibility;import android.content.Context;
import android.os.SystemProperties;
import android.text.TextUtils;import com.android.settings.R;
import com.android.settings.core.TogglePreferenceController;/*** A toggle preference controller for audio description*/
public class FlashlightPreferenceController extends TogglePreferenceController {static final String PREF_KEY = "accessibility_flashlight";public FlashlightPreferenceController(Context context, String preferenceKey) {super(context, preferenceKey);}@Overridepublic boolean isChecked() {String volume_down = SystemProperties.get("persist.sys.double.volume_down");if (!TextUtils.isEmpty(volume_down)) {if (volume_down.equals("1")) {return true;}}return false;}@Overridepublic boolean setChecked(boolean isChecked) {SystemProperties.set("persist.sys.double.volume_down", isChecked ? "1" : "0");return true;}@Overridepublic int getAvailabilityStatus() {String volume_down = SystemProperties.get("persist.sys.double.volume_down");return TextUtils.isEmpty(volume_down) ? UNSUPPORTED_ON_DEVICE : AVAILABLE;}@Overridepublic int getSliceHighlightMenuRes() {return R.string.menu_key_accessibility;}
}

InputDispatcher拦截逻辑_interceptkeybeforequeueing-CSDN博客

Android事件拦截_interceptkeybeforequeueing-CSDN博客


http://www.ppmy.cn/embedded/28310.html

相关文章

【ARM Cache 系列文章 11.1 -- ARM Cache 全相连 详细介绍】

请阅读【ARM Cache 系列文章专栏导读】 文章目录 Cache 全相连(Fully Associative)全相联映射示例全相联映射原理紧接文章:【ARM Cache 系列文章 11 – ARM Cache 组织形式详细介绍】 Cache 全相连(Fully Associative) 介绍: 在全相连缓存中,任何内存地址都可以缓存在 …

ssm项目后端如何导出war及前端如何导出静态资源

后端如何导出war包 后端工具&#xff1a;IDEA 2020.1.3 运行我们编写工具maven里面的package 运行成功的日志 我们运行完&#xff0c;会生成一个target文件夹&#xff0c;在这个文件夹里面找到war包即可 前端如何导出静态资源 使用工具&#xff1a;WebStorm 2020.1.3 打开左…

PyCharm 2024新版图文安装教程(python环境搭建+PyCharm安装+运行测试+汉化+背景图设置)

名人说&#xff1a;一点浩然气&#xff0c;千里快哉风。—— 苏轼《水调歌头》 创作者&#xff1a;Code_流苏(CSDN) 目录 一、Python环境搭建二、PyCharm下载及安装三、解释器配置及项目测试四、PyCharm汉化五、背景图设置 很高兴你打开了这篇博客&#xff0c;如有疑问&#x…

配置及使用OpenCV(Python)

python配置OpenCV相对于c的配置方法容易的多&#xff0c;但建议在Anaconda中的Python虚拟环境中使用&#xff0c;这样更方便进行包管理和环境管理&#xff1a; 先激活Anaconda的python虚拟环境&#xff1a; conda activate GGBoy 随后下载 opencv 包&#xff1a; conda ins…

为什么叫“机器学习”Machine Learning 而不是叫“计算机学习”?

有一门学科“机器学习”火了起来&#xff0c;它是计算机科学与数学结合的产物&#xff0c;它的目的是使计算机“聪明”起来&#xff0c;实现人工智能。可是&#xff0c;令人困惑的是它明明就是计算机学习&#xff0c;为什么不叫“计算机学习”而叫“机器学习”呢&#xff1f;这…

WPF —— MVVM架构

1 什么是MVVM&#xff1f; MVVM是一种软件架构模式&#xff0c;它将应用程序分为三个层次 model&#xff08;数据模型&#xff09;&#xff0c;view&#xff08;视图&#xff09;&#xff0c;viewmodel&#xff08;视图模型&#xff09; model&#xff1a;表示应用程序当中数…

计算机网络 2.4差错检验与校正

第四节 差错检验与校正 一、认识检验与校正 1.差错形成原因 内部因素&#xff08;随机错&#xff09;&#xff1a;噪声脉冲、脉动噪声、衰减、延迟失真等。 外部因素&#xff08;突发错&#xff09;&#xff1a;电磁干扰、太阳噪声、工业噪声等。 2.差错控制编码分类&#…

HTML超链接、列表、表格、常用标签补充

一、超链接 主要作用&#xff1a;从当前页面进行跳转。 可以实现&#xff1a;①跳转到指定页面、②跳转到指定文件&#xff08;也可触发下载&#xff09;、③跳转到锚点位置、④唤起指定应用。 标签名标签语义常用属性单 / 双 标签a超链接href &#xff1a; 指定要跳转到的具…