背景
项目中,需要在某些界面监听用户摇晃动作做出相应的反应。下面分Kotlin和Java两种给出具体的代码。
实现方案(Kotlin)
新增SensorManagerHelper.kt
class SensorManagerHelper(private val context: Context) : SensorEventListener { // 速度阈值,当摇晃速度达到这值后产生作用 private val SPEED_SHRESHOLD = 5000 // 两次检测的时间间隔 private val UPTATE_INTERVAL_TIME = 50 // 传感器管理器 private var sensorManager: SensorManager? = null // 传感器 private var sensor: Sensor? = null // 重力感应监听器 private var onShakeListener: OnShakeListener? = null // 手机上一个位置时重力感应坐标 private var lastX: Float = 0.toFloat() private var lastY: Float = 0.toFloat() private var lastZ: Float = 0.toFloat() // 上次检测时间 private var lastUpdateTime: Long = 0 init { start() } /** * 开始检测 */ fun start() { // 获得传感器管理器 sensorManager = context .getSystemService(Context.SENSOR_SERVICE) as SensorManager if (sensorManager != null) { // 获得重力传感器 sensor = sensorManager!!.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) } // 注册 if (sensor != null) { sensorManager!!.registerListener( this, sensor, SensorManager.SENSOR_DELAY_GAME ) } } /** * 停止检测 */ fun stop() { sensorManager!!.unregisterListener(this) } // 摇晃监听接口 interface OnShakeListener { fun onShake() } // 设置重力感应监听器 fun setOnShakeListener(listener: OnShakeListener) { onShakeListener = listener } /** * 重力感应器感应获得变化数据 * android.hardware.SensorEventListener#onSensorChanged(android.hardware * .SensorEvent) */ override fun onSensorChanged(event: SensorEvent) { // 现在检测时间 val currentUpdateTime = System.currentTimeMillis() // 两次检测的时间间隔 val timeInterval = currentUpdateTime - lastUpdateTime // 判断是否达到了检测时间间隔 if (timeInterval < UPTATE_INTERVAL_TIME) return // 现在的时间变成last时间 lastUpdateTime = currentUpdateTime // 获得x,y,z坐标 val x = event.values[0] val y = event.values[1] val z = event.values[2] // 获得x,y,z的变化值 val deltaX = x - lastX val deltaY = y - lastY val deltaZ = z - lastZ // 将现在的坐标变成last坐标 lastX = x lastY = y lastZ = z val speed = Math.sqrt((deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ).toDouble()) / timeInterval * 10000 // 达到速度阀值,发出提示 if (speed >= SPEED_SHRESHOLD) { onShakeListener!!.onShake() } } override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) {} }
调用
SensorManagerHelper sensorHelper = SensorManagerHelper(this) sensorHelper.setOnShakeListener(object : SensorManagerHelper.OnShakeListener { override fun onShake() { Toast.makeText(this@MainActivity, "不要摇俺啦,好晕哦!", Toast.LENGTH_SHORT).show() } })
实现方案(Java)
新增SensorManagerHelper.java
public class SensorManagerHelper implements SensorEventListener { // 速度阈值,当摇晃速度达到这值后产生作用 private final int SPEED_SHRESHOLD = 5000; // 两次检测的时间间隔 private final int UPTATE_INTERVAL_TIME = 50; // 传感器管理器 private SensorManager sensorManager; // 传感器 private Sensor sensor; // 重力感应监听器 private OnShakeListener onShakeListener; // 上下文对象context private Context context; // 手机上一个位置时重力感应坐标 private float lastX; private float lastY; private float lastZ; // 上次检测时间 private long lastUpdateTime; public SensorManagerHelper(Context context) { this.context = context; start(); } /** * 开始检测 */ public void start() { // 获得传感器管理器 sensorManager = (SensorManager) context .getSystemService(Context.SENSOR_SERVICE); if (sensorManager != null) { // 获得重力传感器 sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); } // 注册 if (sensor != null) { sensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_GAME); } } /** * 停止检测 */ public void stop() { sensorManager.unregisterListener(this); } /** * 摇晃监听接口 */ public interface OnShakeListener { void onShake(); } /** * 设置重力感应监听器 */ public void setOnShakeListener(OnShakeListener listener) { onShakeListener = listener; } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { } /** * 重力感应器感应获得变化数据 * android.hardware.SensorEventListener#onSensorChanged(android.hardware * .SensorEvent) */ @Override public void onSensorChanged(SensorEvent event) { // 现在检测时间 long currentUpdateTime = System.currentTimeMillis(); // 两次检测的时间间隔 long timeInterval = currentUpdateTime - lastUpdateTime; // 判断是否达到了检测时间间隔 if (timeInterval < UPTATE_INTERVAL_TIME) return; // 现在的时间变成last时间 lastUpdateTime = currentUpdateTime; // 获得x,y,z坐标 float x = event.values[0]; float y = event.values[1]; float z = event.values[2]; // 获得x,y,z的变化值 float deltaX = x - lastX; float deltaY = y - lastY; float deltaZ = z - lastZ; // 将现在的坐标变成last坐标 lastX = x; lastY = y; lastZ = z; double speed = Math.sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ) / timeInterval * 10000; // 达到速度阀值,发出提示 if (speed >= SPEED_SHRESHOLD) { onShakeListener.onShake(); } } }
调用
SensorManagerHelper sensorHelper = new SensorManagerHelper(this); sensorHelper.setOnShakeListener(() -> ToastUtil.showToast(ContextUtil.get(), "不要摇俺啦,好晕哦!"));
onDestroy方法中停止监听sensorHelper.stop()
如果只是某个界面监听摇晃,那就只在某个界面中增加;如果是整个app监听,建议在Application中添加监听(因app全生命周期监听,故不再需要增加停止监听方法)。
效果图(摇晃手机后)
作者:程序园中猿
链接:https://www.jianshu.com/p/6f8880f58725
点击查看更多内容
为 TA 点赞
评论
共同学习,写下你的评论
评论加载中...
作者其他优质文章
正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦