传感器的使用,高仿微信摇一摇,动画加声音

燕和裕
2023-12-01

很多时候我们的应用需要使用传感器,使手机应用更加方便和可玩性更高, Google为我们提供了十一种传感器

#define SENSOR_TYPE_ACCELEROMETER       1 //加速度

#define SENSOR_TYPE_MAGNETIC_FIELD      2 //磁力

#define SENSOR_TYPE_ORIENTATION         3 //方向

#define SENSOR_TYPE_GYROSCOPE           4 //陀螺仪

#define SENSOR_TYPE_LIGHT               5 //光线感应

#define SENSOR_TYPE_PRESSURE            6 //压力

#define SENSOR_TYPE_TEMPERATURE         7 //温度

#define SENSOR_TYPE_PROXIMITY           8 //接近

#define SENSOR_TYPE_GRAVITY             9 //重力

#define SENSOR_TYPE_LINEAR_ACCELERATION 10//线性加速度

#define SENSOR_TYPE_ROTATION_VECTOR     11//旋转矢量

今天我们就实现微信中的摇一摇功能,分析一波,首先是直观的感受是,摇一摇的时候,手机振动了,其次是有动画效果,当然也少不了声音的效果。

xml布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#1f1f1f">

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:src="@drawable/flower" />

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_centerInParent="true"
        android:gravity="center"
        android:orientation="vertical">

        <ImageView
            android:id="@+id/up"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/up" />

        <ImageView
            android:id="@+id/down"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/down" />
    </LinearLayout>
</RelativeLayout>

因为我们需要摇一摇的时候有音效,所以需要在在res中新建一个raw文件夹,然后把音频文件放进文件夹中, 我的音频文件名为awe

逻辑的处理

public class MainActivity extends AppCompatActivity{
    //记录上一次晃动手机的时间
    private long lastTime;
    private ImageView upIv;
    private ImageView downIv;
    private int sound1;
    private SoundPool soundPool;
    private Vibrator vibrator;
    private SensorManager sensorManager;

    @Override
    protected void onCreate (Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //振动器
        vibrator = ((Vibrator) getSystemService(VIBRATOR_SERVICE));
        //传感器
        sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
        upIv = ((ImageView) findViewById(R.id.up));
        downIv = ((ImageView) findViewById(R.id.down));
        initSoundPool();
    }
    @Override
    protected void onResume (){
        super.onResume();
        if(sensorManager != null){
            // 注册监听器
            // 第一个参数是Listener,第二个参数是所得传感器类型,第三个参数值获取传感器信息的频率
            sensorManager.registerListener(sensorEventListener, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL);
        }
    }

    //记得在不用的时候关掉传感器,因为手机黑屏是不会自动关掉传感器的,当然如果你觉得电量一直都很足,那算我多嘴咯。
    @Override
    protected void onStop (){
        super.onStop();
        if(sensorManager != null){// 取消监听器
            sensorManager.unregisterListener(sensorEventListener);
        }
    }
    private SensorEventListener sensorEventListener = new SensorEventListener() {
        //当加速度发生改变时调用
        //当加速度放生变化时就会调用该方法,所以在一次晃动中该方法实际会调用多次
        @Override
        public void onSensorChanged(SensorEvent event) {
            //获取手机在不同方向上加速度的大小
            float valueX = Math.abs(event.values[0]);
            float valueY = Math.abs(event.values[1]);
            float valueZ = Math.abs(event.values[2]);
            //当手机在任意一个方向上加速度的大小超过17时,认为晃动手机了
            if (valueX > 17 || valueY > 17 || valueZ > 17) {
                //获取当前毫秒数
                long currentTimeMillis = System.currentTimeMillis();
                //如果两次连续晃动的时间小于1秒
                if (currentTimeMillis - lastTime < 1000) {
                    return;
                }
                lastTime = currentTimeMillis;
                //1.执行动画
                playAnimation();
                //2.播放音效
                playSound();
                //3.手机震动
                //1.震动节奏,off/on/off/on,
                // new long[]{100, 200, 100, 200, 100, 200}这个数组表示
                // 停止震动100ms/震动200ms/停止震动100ms/......
                //2.是否循环,-1表示不循环
                vibrator.vibrate(new long[]{100, 200, 100, 200, 100, 200}, -1);
            }
        }

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

        }
    };
    //执行动画
    private void playAnimation() {
        AnimationSet up = new AnimationSet(false);
        TranslateAnimation upUp = new TranslateAnimation(TranslateAnimation.RELATIVE_TO_SELF,
                0, TranslateAnimation.RELATIVE_TO_SELF, 0, TranslateAnimation.RELATIVE_TO_SELF, 0,
                TranslateAnimation.RELATIVE_TO_SELF, -1);
        upUp.setDuration(1000);
        TranslateAnimation upDown = new TranslateAnimation(TranslateAnimation.RELATIVE_TO_SELF,
                0, TranslateAnimation.RELATIVE_TO_SELF, 0, TranslateAnimation.RELATIVE_TO_SELF, 0,
                TranslateAnimation.RELATIVE_TO_SELF, 1);
        upDown.setDuration(1000);
        //延迟1秒执行
        upDown.setStartOffset(1000);
        up.addAnimation(upUp);
        up.addAnimation(upDown);
        upIv.startAnimation(up);
        AnimationSet down = new AnimationSet(false);
        TranslateAnimation downDown = new TranslateAnimation(TranslateAnimation.RELATIVE_TO_SELF,
                0, TranslateAnimation.RELATIVE_TO_SELF, 0, TranslateAnimation.RELATIVE_TO_SELF, 0,
                TranslateAnimation.RELATIVE_TO_SELF, 1);
        downDown.setDuration(1000);
        TranslateAnimation downUp = new TranslateAnimation(TranslateAnimation.RELATIVE_TO_SELF,
                0, TranslateAnimation.RELATIVE_TO_SELF, 0, TranslateAnimation.RELATIVE_TO_SELF, 0,
                TranslateAnimation.RELATIVE_TO_SELF, -1);
        downUp.setDuration(1000);
        //延迟1秒执行
        downUp.setStartOffset(1000);
        down.addAnimation(downDown);
        down.addAnimation(downUp);
        downIv.startAnimation(down);
    }
    private void playSound() {
        //1.音频文件id
        //2.3 表示左右声道的音量
        //4.优先级
        //5.循环次数,-1表示无限循环
        //6.播放速率,取值为0.5~2之间,1表示正常速率播放
        soundPool.play(sound1, 1, 1, 1, 0, 1);
    }
    private void initSoundPool() {
        if (Build.VERSION.SDK_INT > 20) {
            SoundPool.Builder builder = new SoundPool.Builder();
            //设置最大并发流
            builder.setMaxStreams(3);
            AudioAttributes.Builder attributes = new AudioAttributes.Builder();
            attributes.setLegacyStreamType(AudioManager.STREAM_MUSIC);
            //设置音频流
            builder.setAudioAttributes(attributes.build());
            soundPool = builder.build();
        } else {
            //1.最大并发流
            //2.音频流
            //3.音频质量
            soundPool = new SoundPool(3, AudioManager.STREAM_MUSIC, 0);
        }
        //读取音频文件,返回值为音频文件id
        //第三个参数表示音频优先级
        sound1 = soundPool.load(this, R.raw.awe, 1);
    }
}

当然,需要申明权限,申明手机振动的权限。

<uses-permission android:name="android.permission.VIBRATE"></uses-permission>
 类似资料: