为了账号安全,请及时绑定邮箱和手机立即绑定

Android实现摇晃手机的监听(摇一摇)

标签:
Android

背景

项目中,需要在某些界面监听用户摇晃动作做出相应的反应。下面分Kotlin和Java两种给出具体的代码。

实现方案(Kotlin)

  1. 新增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) {}

}
  1. 调用

SensorManagerHelper sensorHelper = SensorManagerHelper(this)
    sensorHelper.setOnShakeListener(object : SensorManagerHelper.OnShakeListener {        override fun onShake() {
            Toast.makeText(this@MainActivity, "不要摇俺啦,好晕哦!", Toast.LENGTH_SHORT).show()
        }
    })

实现方案(Java)

  1. 新增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();
        }
    }
}
  1. 调用

SensorManagerHelper sensorHelper = new SensorManagerHelper(this);
sensorHelper.setOnShakeListener(() -> ToastUtil.showToast(ContextUtil.get(), "不要摇俺啦,好晕哦!"));

onDestroy方法中停止监听
sensorHelper.stop()

如果只是某个界面监听摇晃,那就只在某个界面中增加;如果是整个app监听,建议在Application中添加监听(因app全生命周期监听,故不再需要增加停止监听方法)。

  1. 效果图(摇晃手机后)


    webp



作者:程序园中猿
链接:https://www.jianshu.com/p/6f8880f58725


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消