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

实现思路:

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.mzph.cn/bicheng/3681.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python基础知识—运算符和if语句(二)

&#x1f3ac; 秋野酱&#xff1a;《个人主页》 &#x1f525; 个人专栏:《Java专栏》 《Python专栏》 ⛺️心若有所向往,何惧道阻且长 文章目录 1.输入和输出函数1.1输出函数1.2输入函数 2.常见运算符2.1赋值运算符2.2比较运算符2.3逻辑运算符2.4and逻辑与2.5or逻辑或2.6not逻…

ceph介绍

一、前言 Ceph 是一个完全分布式的系统&#xff0c;它将数据分布在整个集群中的多个节点上&#xff0c;以实现高可用性和容错性&#xff0c;ceph支持对象存储、块存储、文件存储所以被称为统一存储&#xff0c;ceph的架构由以下组件组成:mon、mgr、osd、mds、cephfs、rgw&#…

深度学习Day-14:RNN实现心脏病预测

&#x1f368; 本文为&#xff1a;[&#x1f517;365天深度学习训练营] 中的学习记录博客 &#x1f356; 原作者&#xff1a;[K同学啊 | 接辅导、项目定制] 要求&#xff1a; 本地读取并加载数据&#xff1b;了解循环神经网络RNN的构建过程&#xff1b;测试集accuracy达到87%…

自己搭建的大疆无人机RTMP流媒体服务延迟太大

流程&#xff1a;无人机摄像头->图传->遥控器->流媒体服务器->取流播放&#xff0c;延迟有10秒来的&#xff0c;大家有没有什么好的方案。

C# 结合JavaScript实现手写板签名并上传到服务器

应用场景 我们最近开发了一款笔迹测试功能的程序&#xff08;测试版&#xff09;&#xff0c;用户在手写板上手写签名&#xff0c;提交后即可测试出被测试者的心理素质评价分析。类似功能的场景还比如&#xff0c;在银行柜台办理业务&#xff0c;期间可能需要您使用手写设备进…

2023最新!nginx安装配置保姆级教程

2023最新!nginx安装配置保姆级教程 这篇文章了参考了这位的教程:https://blog.csdn.net/qq_36838700/article/details/129971765 导航 文章目录 2023最新!nginx安装配置保姆级教程一、nginx下载二、编译安装nginx安装pcre安装openssl、zlib、gcc依赖安装nginx 二、拓展 一、n…

低空经济+飞行汽车:载人无人机技术详解

低空经济与飞行汽车是近年来备受关注的话题。随着科技的不断进步&#xff0c;尤其是无人机技术的快速发展&#xff0c;飞行汽车已经从科幻概念逐渐变为现实。以下是对低空经济与飞行汽车&#xff0c;特别是载人无人机技术的详解&#xff1a; 1. 低空经济&#xff1a; 定义&…

isListEqual方法比较

这个方法有改进空间吗&#xff1f; private static boolean isListEqual(List<String> l0, List<String> l1) {if (l0 null && l1 null)return true;if (l0 l1)return true;if (l0 null || l1 null)return false;if (l0.size() ! l1.size())return f…

ADB 命令获取Android 设备的屏幕分辨率和屏幕像素密度

1. 获取屏幕分辨率和像素密度 获取 Android 设备屏幕分辨率&#xff1a; adb shell wm size Physical size: 1440x3120 获取android设备屏幕密度(DPI)&#xff1a; adb shell wm density Physical density: 560 打印屏幕相关的详细信息&#xff1a; adb shell dumpsys wi…

javaEE--多线程学习-进程调度

进程调度不明白&#xff1f;看这一篇文章就够了&#xff0c;逻辑衔接严密&#xff0c;文末附有关键面试题&#xff0c;一个海后的小故事让你瞬间明白这里面的弯弯绕绕&#xff01; 目录 1.什么是进程&#xff1f; 2.进程控制块&#xff08;PCB&#xff09; 2.1 一个PCB就是一…

顺序表 (C语言版)

顺序存储&#xff1a; 把逻辑上相邻的元素存储在物理位置上也相邻的存储单元中&#xff0c;元素之间的关系由存储单元的邻接关系来体现。 顺序表的特点&#xff1a; 能在O(1)的时间内找到第i个元素存储密度高拓展容量不方便插入&#xff0c;删除操作不方便 C语言中可使用&am…

已解决java.lang.IllegalThreadStateException: 非法线程状态异常的正确解决方法,亲测有效!!!

已解决java.lang.IllegalThreadStateException: 非法线程状态异常的正确解决方法&#xff0c;亲测有效&#xff01;&#xff01;&#xff01; 目录 问题分析 场景描述 报错原因 解决思路 解决方法 检查线程状态 正确管理线程生命周期 异常处理 总结 博主v&#xff1a…

JavaEE >> Spring Boot(1)

Spring Boot 前面已经介绍了 Spring &#xff0c;是为了简化 Java 程序开发的&#xff0c;而在前面创建的过程中就会发现其实 Spring 还是有点复杂&#xff0c;此时 Spring Boot 就诞生了&#xff0c; Spring Boot 是为了简化 Spring 程序开发的。 Spring Boot 即 Spring 脚手…

history日志发送到远程日志服务器

主要目标是设置history信息包含谁、源IP、在哪个目录下、做了什么工作&#xff0c;并实时将日志发送到日志审计服务。 &#xff08;一&#xff09;基础知识 1.logger 是一个shell接口&#xff0c;可以通过该接口使用rsyslog的日志模块 2./etc/profile.d/history.sh比配置/etc…

Android某钉数据库的解密分析

声明 1 本文章中所有内容仅供学习交流&#xff0c;抓包内容、敏感网址、数据接口均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01; 目的 1 解密app数据库&#xff0c;用数据库软件打开查看信息内容 入手…

【后端】python与django的开发环境搭建指南

安装Git 双击Git 客户端安装文件&#xff0c;在安装页面&#xff0c;单击“Next” 在安装路径选择页面&#xff0c;保持默认&#xff0c;单击“Next” 在功能组件选择页面&#xff0c;保持默认&#xff0c;单击“Next” 在开始菜单文件夹设置页面&#xff0c;保持默认&am…

浅谈rDNS在IP情报建设中的应用

在当今数字化世界中&#xff0c;互联网已经成为人们日常生活和商业活动中不可或缺的一部分。在这个庞大而复杂的网络生态系统中&#xff0c;IP地址是连接和识别各种网络设备和服务的基础。然而&#xff0c;仅仅知道一个设备的IP地址并不足以充分理解其在网络中的角色和行为。为…

复现SMO算法:理解SVM、SMO和高斯核【一、了解相关概念】

任务要求 复现带有高斯核的SMO算法。在LIBSVM中找到一个包含超过1000条数据的数据集。在保持超参数一致的情况下&#xff0c;确保自己实现的模型的精度与LIBSVM相比&#xff0c;相差不超过1%。 复现SMO算法&#xff1a;理解SVM、SMO和高斯核 在这篇博客中&#xff0c;我将深…

win11 桌面图标突然多 绿色小对勾,如何去除掉

突然间桌面图标每个上面都有一个绿色小狗狗&#xff0c;如下图所示&#xff0c;以为中病毒了&#xff0c;后来一查不是。 去除方法 1、鼠标在桌面空白处单击&#xff0c;选择“个性化”&#xff08;或直接按“windows键I键”&#xff09;调出设置菜单。 2、在左侧选择“主题”…

oracle varchar2类型如何转化为date类型

ALTER TABLE unit_bin_h ADD TRANS_TIME_TEMP DATE; –处理中文 上午/下午 –UPDATE unit_bin_h SET TRANS_TIME_TEMP TO_CHAR(TO_TIMESTAMP(trans_time, ‘dd-mon-rr hh.mi.ss.ff am’), ‘yyyy-MM-dd hh24:mi:ss’) WHERE TRANS_TIME LIKE ‘%下午’ OR TRANS_TIME LIKE ‘%…