【体感手势】口袋模式或者防误触

2024-02-09 21:38

本文主要是介绍【体感手势】口袋模式或者防误触,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

口袋模式或者防止误触

带有黑屏手势功能的手机,一般都需要进行一个防误触的判断。防止手机放在口袋里或者包包(一些导电介质的东西可能带来辅助效果,比如钥匙)里别误触发点亮屏幕,甚至是打出电话。

原理

接近式传感器的靠近与远离功能。
可以参考我们手机打电话时,耳朵贴近手机的时候,往往屏幕是自动息屏,离开耳朵一小段距离,屏幕又亮起的这个功能。同理和我们放在口袋中一个意思。比较严格的防误触可能会加上Acc重力传感器进行判断

调用方法

原理->基于接近式传感器的远近识别

    private boolean type_proximity = true;private ProximitySensorManager mProximitySensorManager;private void pocketDetector(boolean isEnable){if (isEnable && (mProximitySensorManager == null)) {mProximitySensorManager = new ProximitySensorManager(mContext, new ProximitySensorManager.Listener() {@Overridepublic void onNear() {// 靠近口袋事件type_proximity = true;}@Overridepublic void onFar() {// 远离口袋事件type_proximity = false;}});mProximitySensorManager.enable();} else if(!isEnable && (mProximitySensorManager != null)){mProximitySensorManager.disable(false);mProximitySensorManager = null;}}  

其中 ProximitySensorManager.java 是系统自带的源码直接粘贴过来,直接使用即可

系统工具类ProximitySensorManager

package com.android.server.policy;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;/*** Manages the proximity sensor and notifies a listener when enabled.*/
public class ProximitySensorManager {/*** Listener of the state of the proximity sensor.* <p>* This interface abstracts two possible states for the proximity sensor, near and far.* <p>* The actual meaning of these states depends on the actual sensor.*/public interface Listener {/** Called when the proximity sensor transitions from the far to the near state. */public void onNear();/** Called when the proximity sensor transitions from the near to the far state. */public void onFar();}public static enum State {NEAR, FAR}private final ProximitySensorEventListener mProximitySensorListener;/*** The current state of the manager, i.e., whether it is currently tracking the state of the* sensor.*/private boolean mManagerEnabled;/*** The listener to the state of the sensor.* <p>* Contains most of the logic concerning tracking of the sensor.* <p>* After creating an instance of this object, one should call {@link #register()} and* {@link #unregister()} to enable and disable the notifications.* <p>* Instead of calling unregister, one can call {@link #unregisterWhenFar()} to unregister the* listener the next time the sensor reaches the {@link State#FAR} state if currently in the* {@link State#NEAR} state.*/private static class ProximitySensorEventListener implements SensorEventListener {private static final float FAR_THRESHOLD = 5.0f;private final SensorManager mSensorManager;private final Sensor mProximitySensor;private final float mMaxValue;private final Listener mListener;/*** The last state of the sensor.* <p>* Before registering and after unregistering we are always in the {@link State#FAR} state.*/private State mLastState;/*** If this flag is set to true, we are waiting to reach the {@link State#FAR} state and* should notify the listener and unregister when that happens.*/private boolean mWaitingForFarState;public ProximitySensorEventListener(SensorManager sensorManager, Sensor proximitySensor,Listener listener) {mSensorManager = sensorManager;mProximitySensor = proximitySensor;mMaxValue = proximitySensor.getMaximumRange();mListener = listener;// Initialize at far state.mLastState = State.FAR;mWaitingForFarState = false;}@Overridepublic void onSensorChanged(SensorEvent event) {// Make sure we have a valid value.if (event.values == null) return;if (event.values.length == 0) return;float value = event.values[0];// Convert the sensor into a NEAR/FAR state.State state = getStateFromValue(value);synchronized (this) {// No change in state, do nothing.if (state == mLastState) return;// Keep track of the current state.mLastState = state;// If we are waiting to reach the far state and we are now in it, unregister.if (mWaitingForFarState && mLastState == State.FAR) {unregisterWithoutNotification();}}// Notify the listener of the state change.switch (state) {case NEAR:mListener.onNear();break;case FAR:mListener.onFar();break;}}@Overridepublic void onAccuracyChanged(Sensor sensor, int accuracy) {// Nothing to do here.}/** Returns the state of the sensor given its current value. */private State getStateFromValue(float value) {// Determine if the current value corresponds to the NEAR or FAR state.// Take case of the case where the proximity sensor is binary: if the current value is// equal to the maximum, we are always in the FAR state.return (value > FAR_THRESHOLD || value == mMaxValue) ? State.FAR : State.NEAR;}/*** Unregister the next time the sensor reaches the {@link State#FAR} state.*/public synchronized void unregisterWhenFar() {if (mLastState == State.FAR) {// We are already in the far state, just unregister now.unregisterWithoutNotification();} else {mWaitingForFarState = true;}}/** Register the listener and call the listener as necessary. */public synchronized void register() {// It is okay to register multiple times.mSensorManager.registerListener(this, mProximitySensor, SensorManager.SENSOR_DELAY_UI);// We should no longer be waiting for the far state if we are registering again.mWaitingForFarState = false;}public void unregister() {State lastState;synchronized (this) {unregisterWithoutNotification();lastState = mLastState;// Always go back to the FAR state. That way, when we register again we will get a// transition when the sensor gets into the NEAR state.mLastState = State.FAR;}// Notify the listener if we changed the state to FAR while unregistering.if (lastState != State.FAR) {mListener.onFar();}}private void unregisterWithoutNotification() {mSensorManager.unregisterListener(this);mWaitingForFarState = false;}}public ProximitySensorManager(Context context, Listener listener) {SensorManager sensorManager =(SensorManager) context.getSystemService(Context.SENSOR_SERVICE);Sensor proximitySensor = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);if (proximitySensor == null) {// If there is no sensor, we should not do anything.mProximitySensorListener = null;} else {mProximitySensorListener =new ProximitySensorEventListener(sensorManager, proximitySensor, listener);}}/*** Enables the proximity manager.* <p>* The listener will start getting notifications of events.* <p>* This method is idempotent.*/public void enable() {if (mProximitySensorListener != null && !mManagerEnabled) {mProximitySensorListener.register();mManagerEnabled = true;}}/*** Disables the proximity manager.* <p>* The listener will stop receiving notifications of events, possibly after receiving a last* {@link Listener#onFar()} callback.* <p>* If {@code waitForFarState} is true, if the sensor is not currently in the {@link State#FAR}* state, the listener will receive a {@link Listener#onFar()} callback the next time the sensor* actually reaches the {@link State#FAR} state.* <p>* If {@code waitForFarState} is false, the listener will receive a {@link Listener#onFar()}* callback immediately if the sensor is currently not in the {@link State#FAR} state.* <p>* This method is idempotent.*/public void disable(boolean waitForFarState) {if (mProximitySensorListener != null && mManagerEnabled) {if (waitForFarState) {mProximitySensorListener.unregisterWhenFar();} else {mProximitySensorListener.unregister();}mManagerEnabled = false;}}
}

结论

实践证明系统的提供的判断误触的工具栏非常好用,简单粗暴又省电,还有稳定得没亲妈

这篇关于【体感手势】口袋模式或者防误触的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/695345

相关文章

Java设计模式---迭代器模式(Iterator)解读

《Java设计模式---迭代器模式(Iterator)解读》:本文主要介绍Java设计模式---迭代器模式(Iterator),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,... 目录1、迭代器(Iterator)1.1、结构1.2、常用方法1.3、本质1、解耦集合与遍历逻辑2、统一

Java 线程安全与 volatile与单例模式问题及解决方案

《Java线程安全与volatile与单例模式问题及解决方案》文章主要讲解线程安全问题的五个成因(调度随机、变量修改、非原子操作、内存可见性、指令重排序)及解决方案,强调使用volatile关键字... 目录什么是线程安全线程安全问题的产生与解决方案线程的调度是随机的多个线程对同一个变量进行修改线程的修改操

Redis Cluster模式配置

《RedisCluster模式配置》:本文主要介绍RedisCluster模式配置,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录分片 一、分片的本质与核心价值二、分片实现方案对比 ‌三、分片算法详解1. ‌范围分片(顺序分片)‌2. ‌哈希分片3. ‌虚

RabbitMQ工作模式中的RPC通信模式详解

《RabbitMQ工作模式中的RPC通信模式详解》在RabbitMQ中,RPC模式通过消息队列实现远程调用功能,这篇文章给大家介绍RabbitMQ工作模式之RPC通信模式,感兴趣的朋友一起看看吧... 目录RPC通信模式概述工作流程代码案例引入依赖常量类编写客户端代码编写服务端代码RPC通信模式概述在R

SQL Server身份验证模式步骤和示例代码

《SQLServer身份验证模式步骤和示例代码》SQLServer是一个广泛使用的关系数据库管理系统,通常使用两种身份验证模式:Windows身份验证和SQLServer身份验证,本文将详细介绍身份... 目录身份验证方式的概念更改身份验证方式的步骤方法一:使用SQL Server Management S

Redis高可用-主从复制、哨兵模式与集群模式详解

《Redis高可用-主从复制、哨兵模式与集群模式详解》:本文主要介绍Redis高可用-主从复制、哨兵模式与集群模式的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝... 目录Redis高可用-主从复制、哨兵模式与集群模式概要一、主从复制(Master-Slave Repli

一文带你搞懂Redis Stream的6种消息处理模式

《一文带你搞懂RedisStream的6种消息处理模式》Redis5.0版本引入的Stream数据类型,为Redis生态带来了强大而灵活的消息队列功能,本文将为大家详细介绍RedisStream的6... 目录1. 简单消费模式(Simple Consumption)基本概念核心命令实现示例使用场景优缺点2

Nginx location匹配模式与规则详解

《Nginxlocation匹配模式与规则详解》:本文主要介绍Nginxlocation匹配模式与规则,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、环境二、匹配模式1. 精准模式2. 前缀模式(不继续匹配正则)3. 前缀模式(继续匹配正则)4. 正则模式(大

Linux系统配置NAT网络模式的详细步骤(附图文)

《Linux系统配置NAT网络模式的详细步骤(附图文)》本文详细指导如何在VMware环境下配置NAT网络模式,包括设置主机和虚拟机的IP地址、网关,以及针对Linux和Windows系统的具体步骤,... 目录一、配置NAT网络模式二、设置虚拟机交换机网关2.1 打开虚拟机2.2 管理员授权2.3 设置子

SpringBoot如何通过Map实现策略模式

《SpringBoot如何通过Map实现策略模式》策略模式是一种行为设计模式,它允许在运行时选择算法的行为,在Spring框架中,我们可以利用@Resource注解和Map集合来优雅地实现策略模式,这... 目录前言底层机制解析Spring的集合类型自动装配@Resource注解的行为实现原理使用直接使用M