Android利用感測器實現-仿微信搖一搖

小小時光機發表於2017-05-02

感測器

簡單的介紹一下感測器:
就是裝置用來感知周邊環境變化的硬體,

  • Android中的感測器包含在感測器框架中,屬於android.hardware.*(硬體部分)
  • 感測器框架主要包含四個部分:

    • ① SensorManager:用來獲取感測器的入口,它是一個系統的服務,還可以為感測器註冊與取消註冊監聽
    • ② Sensor: 具體的感測器,包含了感測器的名字,型別,取樣率
    • ③ SensorEvent:感測器事件,包含了感測器採集回來的資料,感測器的精度
    • ④ SensorEventListener:感測器的監聽,主要監測感測器資料變化,精度變化…
  • Android播放音訊系統提供了兩種方式

    • ① MediaPlayer 播放常規的音訊,視訊,通常用在播放器上
    • ② SoundPool 聲音池,通常用在小而頻繁播放的音樂,需要同時播放多個音樂的
  • VIBRATE 所震動感測器需要新增許可權

<uses-permission android:name="android.permission.VIBRATE"/>

實現之前先來看看手機上的感測器有哪些?(此處可以略過…)
onCreat();中設定TextView

sensor = (TextView) findViewById(R.id.sensor);

        mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);

        List<Sensor> sensorList = mSensorManager.getSensorList(Sensor.TYPE_ALL);

        StringBuilder builder = new StringBuilder();

        builder.append("感測器總數: "+sensorList.size()+"\n");
        for (int i = 0; i < sensorList.size(); i++) {
            Sensor sensor = sensorList.get(i);
            builder.append("感測器名稱: "+sensor.getName()+", 感測器生產廠商: "+sensor.getVendor()+"\n");
        }
        sensor.setText(builder.toString());

驚奇的發現小米5上竟然有41個感測器,可以哈…厲害了
好了,好了接下來言歸正傳—微信搖一搖


介面的話三張圖片你的層疊,RelativeLayout進行佈局
展示介面

在onCreate中封裝的方法

//搖一搖---->加速感測器
        //1、初始化控制元件
        initView();
        //2、初始化音樂SoundPool
        initSoundPool();
        //3、震動
        initVibrator();

上面蓋的兩張圖片初始化

up_logo = (ImageView) findViewById(R.id.up_logo);
down_logo = (ImageView) findViewById(R.id.down_logo);

在初始化SoundPool的時候,發現new SoundPool已經不推薦使用了,新版的(API>21)使用Builder構建,所以在這裡使用版本進行判斷了一下

private void initSoundPool() {
        if(Build.VERSION.SDK_INT>=21){
            SoundPool.Builder builder = new SoundPool.Builder();
            //設定
            builder.setMaxStreams(1);
            AudioAttributes attributes = new AudioAttributes.Builder()
                    .setLegacyStreamType(AudioManager.STREAM_MUSIC)
                    .build();

            builder.setAudioAttributes(attributes);

            mSoundPool = builder.build();
        }else {
            //已經過時,老版本
            mSoundPool = new SoundPool(1, AudioManager.STREAM_MUSIC, 0);//引數三保留引數
        }
        //新增音樂
        //引數三是音樂池中音樂播放的優先順序
        mSoundPool_id = mSoundPool.load(this, R.raw.awe, 1);
    }

初始化振動器:(是一個系統的服務)

mVibrator = (Vibrator) this.getSystemService(VIBRATOR_SERVICE);

搖一搖利用的是加速度感測器,需要監聽它的變化狀態
SensorManager的註冊也是成對出現的

 @Override
    protected void onStart() {
        super.onStart();
        //4、設定感測器監聽,加速感測器
        initSensor();
    }

    @Override
    protected void onStop() {
        super.onStop();
        //解除註冊
        mSensorManager.unregisterListener(this);
    }

    private void initSensor() {
        Sensor accelerometerSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        //通過SensorManager實現監聽加速感測器
        mSensorManager.registerListener(this,accelerometerSensor,SensorManager.SENSOR_DELAY_UI);
    }

這裡的監聽需要手動去實現(這裡是比較不智慧的…)
implements SensorEventListener會實現兩個方法

//資料發生變化
 @Override
    public void onSensorChanged(SensorEvent event) {

    }

//精度發生變化,感測器的,該方法用不到
    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {

    }

下面是方法的具體實現:

@Override
    public void onSensorChanged(SensorEvent event) {//資料發生變化
        Sensor sensor = event.sensor;
        int type = sensor.getType();
        switch (type){
            case Sensor.TYPE_ACCELEROMETER://加速感測器

                float[] values = event.values;
                //x,y,z 三個方向
                //9.8
                float x = values[0];
                float y = values[1];
                float z = values[2];

                if(Math.abs(x)>25||Math.abs(y)>25||Math.abs(z)>25){
                    //觸發搖一搖
                    //音樂播放
                    mSoundPool.play(mSoundPool_id,1,1,0,0,1);

                    //震動(-1代表只執行一次)
                    mVibrator.vibrate(new long[]{200,300,400,200},-1);
                    //動畫執行
                    initAnimation();
                }
                break;
        }
    }

動畫沒什麼好解釋的,直接上程式碼了

private void initAnimation() {
        //up_logo 向上移動,同時有上下震動
        AnimationSet set_up = new AnimationSet(true);
        TranslateAnimation up_up = new TranslateAnimation(
                TranslateAnimation.RELATIVE_TO_SELF,0,//x軸起點
                TranslateAnimation.RELATIVE_TO_SELF,0,//x軸終點
                TranslateAnimation.RELATIVE_TO_SELF,0,//y軸起點
                TranslateAnimation.RELATIVE_TO_SELF,-1//y軸終點
                );

        up_up.setDuration(1000);

        TranslateAnimation up_down = new TranslateAnimation(
                TranslateAnimation.RELATIVE_TO_SELF,0,//x軸起點
                TranslateAnimation.RELATIVE_TO_SELF,0,//x軸終點
                TranslateAnimation.RELATIVE_TO_SELF,-1,//y軸起點
                TranslateAnimation.RELATIVE_TO_SELF,0//y軸終點
        );
        up_down.setDuration(1000);

        //延遲執行set中的某一動畫
        up_down.setStartOffset(500);
        set_up.addAnimation(up_up);//移動上去;
        set_up.addAnimation(up_down);//拉下來
        up_logo.startAnimation(set_up);

//----------

        AnimationSet set_down = new AnimationSet(true);
        TranslateAnimation down_down = new TranslateAnimation(
                TranslateAnimation.RELATIVE_TO_SELF,0,//x軸起點
                TranslateAnimation.RELATIVE_TO_SELF,0,//x軸終點
                TranslateAnimation.RELATIVE_TO_SELF,0,//y軸起點
                TranslateAnimation.RELATIVE_TO_SELF,1//y軸終點
        );
        down_down.setDuration(1000);
        TranslateAnimation down_up = new TranslateAnimation(
                TranslateAnimation.RELATIVE_TO_SELF,0,//x軸起點
                TranslateAnimation.RELATIVE_TO_SELF,0,//x軸終點
                TranslateAnimation.RELATIVE_TO_SELF,1,//y軸起點
                TranslateAnimation.RELATIVE_TO_SELF,0//y軸終點
        );
        down_up.setDuration(1000);
        down_up.setStartOffset(500);
        set_down.addAnimation(down_down);//向下移動
        set_down.addAnimation(down_up);//往上拉動
        down_logo.startAnimation(set_down);

    }

相關文章