前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android实现摇一摇触发逻辑

Android实现摇一摇触发逻辑

作者头像
码农帮派
发布2021-04-22 11:28:49
2.5K0
发布2021-04-22 11:28:49
举报
文章被收录于专栏:码农帮派码农帮派

下面的代码主要控制手机摇晃的程度,在摇晃到一定成的时候,才会触发摇一摇回调,重点在于如何保证摇一摇的触发既不能太灵敏,也不能太迟钝。

下面代码的主要思路,是计算两次时间间隔之间摇晃的空间位置之间的直线距离,从而计算获得当前时间段内摇晃手机的速度,当这个速度达到一定的阈值,则认为出发了摇一摇的动作,反之则进行下一次的摇晃数据的采集。

具体的代码如下:

代码语言:javascript
复制
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;

import com.dragon.learn.LearnApplication;

import java.util.ArrayList;

public class ShakeUtils implements SensorEventListener {

    private volatile static ShakeUtils instance;

    public static ShakeUtils getInstance() {
        if (instance == null) {
            synchronized (ShakeUtils.class) {
                if (instance == null) {
                    instance = new ShakeUtils();
                }
            }
        }

        return instance;
    }

    private ArrayList<OnShakeListener> mOnShakeListeners = null;

    // 触发Shake的最小时间间隔
    private static final int MIN_SHAKE_INTERVAL = 1024;
    // 上次触发Shake操作的时间
    private long mLastShakeTime = 0L;

    private long mLastUpdateTime = 0L;
    // 摇晃的速度
    private static int SPEED_SHAKE_MILLSECONDS = 400;
    // 两次摇晃的最小时间间隔
    private static final int SHAKE_INTERVAL_MILLSECOND = 55;
    // 上次摇晃的重力坐标位置
    private float mLastX = 0;
    private float mLastY = 0;
    private float mLastZ = 0;

    public interface OnShakeListener {
        void onShake(double speed);
    }

    public ShakeUtils() {
        Context context = LearnApplication.getLearnApplication();
        SensorManager mSensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
        Sensor sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        mSensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_UI);

        mOnShakeListeners = new ArrayList<>();
    }

    public void bindShakeListener(OnShakeListener listener) {
        if (listener != null) {
            mOnShakeListeners.add(listener);
        }
    }

    public void unBindShakeListener(OnShakeListener listener) {
        mOnShakeListeners.remove(listener);
    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        if (event == null) {
            return;
        }

        long curUpdateTime = System.currentTimeMillis();
        // 两次位置改变的时间间隔
        long timeInterval = curUpdateTime - mLastUpdateTime;

        if (timeInterval < SHAKE_INTERVAL_MILLSECOND) {
            return;
        }

        if (event.values.length < 3) {
            return;
        }

        mLastUpdateTime = curUpdateTime;

        float x = event.values[0];
        float y = event.values[1];
        float z = event.values[2];

        float deltaX = x - mLastX;
        float deltaY = y - mLastY;
        float deltaZ = z - mLastZ;

        mLastX = x;
        mLastY = y;
        mLastZ = z;

        double speed = Math.sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ) * 1000.0 / timeInterval;

        if (speed >= SPEED_SHAKE_MILLSECONDS) {
            startShake(speed);
        }
    }

    private void startShake(double speed) {
        long curShakeTime = System.currentTimeMillis();

        if (curShakeTime - mLastShakeTime < MIN_SHAKE_INTERVAL) {
            return;
        }

        mLastShakeTime = curShakeTime;

        for (int i = 0; i < mOnShakeListeners.size(); i++) {
            mOnShakeListeners.get(i).onShake(speed);
        }
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
    }
}

我们使用的时候,只需要通过bind绑定,但是需要注意在不需要shake事件的时候,需要及时的unBind:

代码语言:javascript
复制
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import com.dragon.learn.R;
import com.dragon.learn.utils.ShakeUtils;

public class ShakeEventActionActivity extends AppCompatActivity implements ShakeUtils.OnShakeListener {

    TextView mSpeedTv;

    ShakeUtils mShakeUtils;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_shake_event_action);

        mSpeedTv = findViewById(R.id.shake_speed);

        mShakeUtils = ShakeUtils.getInstance();

        mShakeUtils.bindShakeListener(this);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mShakeUtils.unBindShakeListener(this);
    }

    @Override
    public void onShake(double speed) {
        Log.e("onShake", "onShake speed:" + speed);
        mSpeedTv.setText("当前摇晃的速度: " + speed);
    }
}

摇一摇触发的效果:

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-04-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码农帮派 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档