背景
项目中,需要在某些界面监听用户摇晃动作做出相应的反应。下面分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
點(diǎn)擊查看更多內(nèi)容
為 TA 點(diǎn)贊
評(píng)論
評(píng)論
共同學(xué)習(xí),寫(xiě)下你的評(píng)論
評(píng)論加載中...
作者其他優(yōu)質(zhì)文章
正在加載中
感謝您的支持,我會(huì)繼續(xù)努力的~
掃碼打賞,你說(shuō)多少就多少
贊賞金額會(huì)直接到老師賬戶
支付方式
打開(kāi)微信掃一掃,即可進(jìn)行掃碼打賞哦
