Android47_傳感器Sensor

傳感器Sensor

一、傳感器:
(一)、傳感器概述:
1、簡介:
Android手機中常支持多種類型傳感器,如:光照傳感器、加速度傳感器、地磁傳感器、壓力傳感器、溫度傳感器等。賽車遊戲、微信搖一搖、指南針都需要藉助傳感器來完成。
2、傳感器使用步驟:【重要】
  1. 獲取SensorManager對象:
    • sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
  2. 獲取傳感器類型:
    • Sensor sensor = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
  3. SensorManager對象註冊監聽器,監聽傳感器輸出的信號:
    • sensorManager.registerListener(listener, sensor,sensorManager.SENSOR_DELAY_GAME);
  4. 資源釋放:SensorManager對象解除註冊監聽器
  • sensorManager.unregisterListener(listener);

(二)、光照傳感器:

1、核心代碼:

public class MainActivity extends Activity {

private TextView textView_lightlevel;

private SensorManager sensorManager;

private SensorEventListener listener = new SensorEventListener() {


@Override

public void onSensorChanged(SensorEvent event) {

float value = event.values[0];

textView_lightlevel.setText(value + "lx");


}


@Override

public void onAccuracyChanged(Sensor sensor, int accuracy) {

// TODO Auto-generated method stub


}

};


@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);


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

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

Sensor sensor = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);

// 傳感器輸出信息的更新速率

sensorManager.registerListener(listener, sensor,

sensorManager.SENSOR_DELAY_GAME);

}


@Override

protected void onDestroy() {

super.onDestroy();

if (sensorManager != null) {

sensorManager.unregisterListener(listener);

}

}


}



(三)、加速度傳感器:(模擬搖一搖)

1、核心代碼:

public class MainActivity extends Activity {

private SensorManager sensorManager;

private SensorEventListener listener = 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]);

if (valueX > 15 || valueY > 15 || valueZ > 15) {

Toast.makeText(MainActivity.this, "搖晃了!", 0).show();

}

}


@Override

public void onAccuracyChanged(Sensor sensor, int accuracy) {

}

};


@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);


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

Sensor sensor = sensorManager

.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

sensorManager.registerListener(listener, sensor,

sensorManager.SENSOR_DELAY_FASTEST);

}


@Override

protected void onDestroy() {

super.onDestroy();

if (sensorManager != null) {

sensorManager.unregisterListener(listener);

}

}


@Override

public boolean onCreateOptionsMenu(Menu menu) {

// Inflate the menu; this adds items to the action bar if it is present.

getMenuInflater().inflate(R.menu.main, menu);

return true;

}


}




(四)、方向傳感器:(指南針)

1、核心代碼:

public class MainActivity extends Activity {

private TextView textView_main_info;

private ImageView imageView_main_arrow;

private SensorManager sensorManager;

private SensorEventListener listener = new SensorEventListener() {

float[] accelerometerValues = new float[3];

float[] magneticValues = new float[3];

float lastRotateDegree;


@Override

public void onSensorChanged(SensorEvent event) {

if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {

accelerometerValues = event.values.clone();

} else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {

magneticValues = event.values.clone();

}

float[] R = new float[9];// 包含旋轉矩陣的數據放在R數組中

float[] values = new float[3];// 手機在各個方向上旋轉的數據放在這個數組中

sensorManager.getRotationMatrix(R, null, accelerometerValues,

magneticValues);

sensorManager.getOrientation(R, values);


float rotateDegree = -(float) Math.toDegrees(values[0]);

// textView_main_info.setText(Math.toDegrees(values[0]) + "");

if (Math.abs(rotateDegree - lastRotateDegree) > 1) {

RotateAnimation animation = new RotateAnimation(

lastRotateDegree, rotateDegree,

Animation.RELATIVE_TO_SELF, 0.5f,

Animation.RELATIVE_TO_SELF, 0.5f);

animation.setFillAfter(true);

imageView_main_arrow.startAnimation(animation);

lastRotateDegree = rotateDegree;

}

setTitle("角度爲:" + Math.toDegrees(values[0]));


}


@Override

public void onAccuracyChanged(Sensor sensor, int accuracy) {

// TODO Auto-generated method stub


}

};


@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);


imageView_main_arrow = (ImageView) findViewById(R.id.imageView_main_arrow);


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

Sensor accelerometerSensor = sensorManager

.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

Sensor mageneticSensor = sensorManager

.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);

sensorManager.registerListener(listener, accelerometerSensor,

sensorManager.SENSOR_DELAY_NORMAL);

sensorManager.registerListener(listener, mageneticSensor,

sensorManager.SENSOR_DELAY_NORMAL);


}


@Override

public boolean onCreateOptionsMenu(Menu menu) {

// Inflate the menu; this adds items to the action bar if it is present.

getMenuInflater().inflate(R.menu.main, menu);

return true;

}


}



(五)、加速度傳感器+補間動畫實現改進版《搖一搖》:
效果如下圖:


1、佈局核心代碼:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="match_parent"

    android:layout_height="match_parent" 

    android:background="#000">


    <ImageView

        android:id="@+id/imageView_main_flower"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_centerInParent="true"

        android:src="@drawable/shakehideimg_man2" />


    <LinearLayout

        android:layout_width="match_parent"

        android:layout_height="match_parent"

        android:layout_centerInParent="true"

        android:orientation="vertical" 

        android:gravity="center"

        >


        <ImageView

            android:id="@+id/imageView_main_logoup"

            android:layout_width="match_parent"

            android:layout_height="wrap_content"

            android:background="#000"

            android:src="@drawable/shake_logo_up" />

        <ImageView

            android:id="@+id/imageView_main_logodown"

            android:layout_width="match_parent"

            android:layout_height="wrap_content"

            android:background="#000"

            android:src="@drawable/shake_logo_down" />

    </LinearLayout>


</RelativeLayout>


2、Java核心代碼:

public class MainActivity extends Activity {

// 兩次檢測的時間間隔

private static final int UPTATE_INTERVAL_TIME = 70;

private int track1, track2 = 0;

private SoundPool soundPool = null;

// 上次檢測時間

private long lastUpdateTime;

private ImageView imageView_main_logoup;

private ImageView imageView_main_logodown;

private Vibrator mVibrator;

private SensorManager sensorManager;

private SensorEventListener listener = new SensorEventListener() {


@Override

public void onSensorChanged(SensorEvent event) {

// 現在檢測時間

long currentUpdateTime = System.currentTimeMillis();

// 兩次檢測的時間間隔

long timeInterval = currentUpdateTime - lastUpdateTime;

// 判斷是否達到了檢測時間間隔

if (timeInterval < UPTATE_INTERVAL_TIME)

return;

// 現在的時間變成last時間

lastUpdateTime = currentUpdateTime;


float valueX = Math.abs(event.values[0]);

float valueY = Math.abs(event.values[1]);

float valueZ = Math.abs(event.values[2]);

if (valueX > 15 || valueY > 15 || valueZ > 15) {

startAnimation();

startVibrato();

// stopSensor();


new Handler().postDelayed(new Runnable() {

@Override

public void run() {

Toast.makeText(getApplicationContext(),

"抱歉,暫時沒有找到\n在同一時刻搖一搖的人。\n再試一次吧!", 0).show();

// mVibrator.cancel();

// initSensor();

}

}, 2000);

}

}


@Override

public void onAccuracyChanged(Sensor sensor, int accuracy) {

}

};


@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);


imageView_main_logoup = (ImageView) findViewById(R.id.imageView_main_logoup);

imageView_main_logodown = (ImageView) findViewById(R.id.imageView_main_logodown);


initSensor();

initSoundPool();

}


// 初始化Sensor

private void initSensor() {

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

Sensor sensor = sensorManager

.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

sensorManager.registerListener(listener, sensor,

sensorManager.SENSOR_DELAY_GAME);

mVibrator = (Vibrator) getApplication().getSystemService(

VIBRATOR_SERVICE);

}


// 停止檢測

private void stopSensor() {

if (sensorManager != null) {

sensorManager.unregisterListener(listener);

}

}


// 定義搖一搖之後的動畫效果

private void startAnimation() {

AnimationSet animationSetUp = new AnimationSet(true);

TranslateAnimation animationUp0 = new TranslateAnimation(

Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0,

Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF,

-1.0f);

animationUp0.setDuration(1000);

TranslateAnimation animationUp1 = new TranslateAnimation(

Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0,

Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF,

+1.0f);

animationUp1.setDuration(1000);

// 設置動畫集中下一個動畫的延遲執行時間

animationUp1.setStartOffset(1000);

// 給動畫集中設置動畫

animationSetUp.addAnimation(animationUp0);

animationSetUp.addAnimation(animationUp1);

// 控件啓動動畫集

imageView_main_logoup.startAnimation(animationSetUp);


AnimationSet animationSetDown = new AnimationSet(true);

TranslateAnimation animationDown0 = new TranslateAnimation(

Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, 0f,

Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF,

+1.0f);

animationDown0.setDuration(1000);

TranslateAnimation animationDown1 = new TranslateAnimation(

Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, 0f,

Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF,

-1.0f);

animationDown1.setDuration(1000);

animationDown1.setStartOffset(1000);


animationSetDown.addAnimation(animationDown0);

animationSetDown.addAnimation(animationDown1);

imageView_main_logodown.startAnimation(animationSetDown);

}


public void startVibrato() {

// 第一種加載聲音的方式:利用MediaPlayer播放器

// MediaPlayer player;

// player = MediaPlayer.create(this, R.raw.awe);

// player.setLooping(false);

// player.start();


// 第二種加載聲音的方式:利用聲音池

soundPool.play(track2, 1, 1, 1, 0, 1);


// 定義震動

// 只有1個參數的時候,第一個參數用來指定振動的毫秒數。

// 要傳遞2個參數的時候,第1個參數用來指定振動時間的樣本,第2個參數用來指定是否需要循環,-1爲不重複,非-1則從pattern的指定下標開始重複

// 振動時間的樣本是指振動時間和等待時間的交互指定的數組,即節奏數組。

// ※下面的例子,在程序起動後等待3秒後,振動1秒,再等待2秒後,振動5秒,再等待3秒後,振動1秒

// long[] pattern = {3000, 1000, 2000, 5000, 3000, 1000};

// 震動節奏分別爲:OFF/ON/OFF/ON…

mVibrator.vibrate(new long[] { 500, 200, 500, 200 }, -1);

}


private void initSoundPool() {

// 三個參數:播放最大併發流數量;目標流類型(總是STREAM_MUSIC);0爲默認值。

soundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);

track1 = soundPool.load(this, R.raw.awe, 1);

track2 = soundPool.load(this, R.raw.aw, 1);

}


@Override

protected void onDestroy() {

super.onDestroy();

stopSensor();

if (soundPool != null) {

soundPool.release();

}

}

}


良心的公衆號,更多精品文章,不要忘記關注哈

《Android和Java技術棧》

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章