編輯:關於Android編程
手機中內置的傳感器是一種微型的物理設備,它能夠探測、感受到外界的信號,並按一定規律轉換成我們所需要的信息。Android手機通常都會支持多種類型的傳感器,如光照傳感右器、加速度傳感器、地磁傳感器、壓力傳感器、溫度傳感器等。
當然,Android系統只是負責將這些傳感器所輸出的信息傳遞給我們,至於具體如何去利用這些信息就要充分發揮開發者的想象力了。目前市場上很多的程序都有使用到傳感器的功能,比如最常見的賽車游戲,玩家可以通過旋轉設備來控制賽車的前進方向,就像是在操作方向盤一樣。除此之外,微信的搖一搖功能,手機指南針等軟件也都是借助傳感器來完成的。
光照傳感器在Android中的應用還是比較常見的,比如系統就有個自動調整屏幕亮度的功能。它會檢測手機周圍環境的光照強度,然後對手機屏幕的亮度進行相應地調整,以此保證不管是在強光還是弱光下,手機屏幕都能夠看得清。
例子:
布局:
代碼:
package com.example.test.sensor; import android.app.Activity; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.os.Bundle; import android.widget.TextView; import com.example.test.R; /** * Created by Administrator on 2016/6/4. */ public class LightSensorActivity extends Activity { private TextView txtLevel; //SensorManager是系統所有傳感器的管理器,有了它的實例之後就可以調用getDefaultSensor()方法來得到任意的傳感器類型了 private SensorManager sensorManager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_sensor_light); txtLevel = (TextView) findViewById(R.id.txt_light_lever); sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE); //這裡使用Sensor.TYPE_LIGHT常量來指定傳感器類型,此時的Sensor實例就代表著一個光照傳感器 Sensor sensor = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT); /** *調用SensorManager的registerListener()方法來注冊SensorEventListener才能使其生效,registerListener()方法接收三個參數 * 第一個參數就是SensorEventListener的實例, * 第二個參數是Sensor的實例, * 第三個參數是用於表示傳感器輸出信息的更新速率,共有SENSOR_DELAY_UI、SENSOR_DELAY_NORMAL、 * SENSOR_DELAY_GAME和SENSOR_DELAY_FASTEST這四種值可選,它們的更新速率是依次遞增的。 */ sensorManager.registerListener(listener, sensor, sensorManager.SENSOR_DELAY_NORMAL); } /** * 調用unregisterListener()方法來釋放使用的資源 */ @Override protected void onDestroy() { super.onDestroy(); if (null != sensorManager) { sensorManager.unregisterListener(listener); } } //SensorEventListener是對傳感器輸出的信號進行監聽,SensorEventListener是一個接口,其中定義了onSensorChanged()和onAccuracyChanged()這兩個方法 private SensorEventListener listener = new SensorEventListener() { /** * 當傳感器的精度發生變化時就會調用onAccuracyChanged()方法 * @param event SensorEvent參數裡又包含了一個values數組,所有傳感器輸出的信息都是存放在這裡的。 */ @Override public void onSensorChanged(SensorEvent event) { //values數組中第一個下標的值就是當前的光照強度 float value = event.values[0]; txtLevel.setText("Current light level is " + value + " lx."); } /** * 當傳感器監測到的數值發生變化時就會調用onSensorChanged()方法 * @param sensor 傳感器 * @param accuracy 變化後的值 */ @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { } }; }
Android中的加速度傳感器則是提供了一種機制,使得我們能夠在應用程序中獲取到手機當前的加速度信息,合理利用這些信息就可以開發出一些比較好玩的功能。
接下來我們嘗試利用加速度傳感器來模仿一下微信的搖一搖功能。其實主體邏輯也非常簡單,只需要檢測手機在X軸、Y軸和Z軸上的加速度,當達到了預定值的時候就可以認為用戶搖動了手機,從而觸發搖一搖的邏輯。那麼現在問題在於,這個預定值應該設定為多少呢?由於重力加速度的存在,即使手機在靜止的情況下,某一個軸上的加速度也有可能達到9.8m/s2,因此這個預定值必定是要大於9.8m/s2的,這裡我們就設定為15m/s2吧。
例子:
布局:什麼都沒有,
代碼:
package com.example.test.sensor; import android.app.Activity; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.os.Bundle; import android.widget.Toast; import com.example.test.R; /** * Created by Administrator on 2016/6/4. */ public class AccelerometerSensorActivity extends Activity { private SensorManager sensorManager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_sensor_accelerometer); sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE); Sensor sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); sensorManager.registerListener(listener, sensor, sensorManager.SENSOR_DELAY_NORMAL); } @Override protected void onDestroy() { super.onDestroy(); if (null != sensorManager) { sensorManager.unregisterListener(listener); } } private SensorEventListener listener = new SensorEventListener() { @Override public void onSensorChanged(SensorEvent event) { //加速值可能為負值,所以要取他們的絕對值 float xValue = Math.abs(event.values[0]); float yValue = Math.abs(event.values[1]); float zValue = Math.abs(event.values[2]); if (xValue > 15 || yValue > 15 || zValue > 15) { //認為用戶搖動了手機,觸發搖一搖邏輯 Toast.makeText(AccelerometerSensorActivity.this, "搖一搖", Toast.LENGTH_SHORT).show(); } } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { } }; }
要說Android中另外一個比較常用的傳感器應該就是方向傳感器了。方向傳感器的使用場景要比其他的傳感器更為廣泛,它能夠准確地判斷出手機在各個方向的旋轉角度,利用這些角度就可以編寫出像指南針、地平儀等有用的工具。另外,在本章開始時介紹的通過旋轉設備來控制方向的賽車游戲,也是使用方向傳感器來完成的。Android獲取手機旋轉的方向和角度是通過加速度傳感器和地磁傳感器共同計算得出的,這也是Android目前推薦使用的方式。
例子:制作簡易指南針
布局文件:
主界面:
package com.example.compasstest; import android.content.Context; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.animation.Animation; import android.view.animation.RotateAnimation; import android.widget.ImageView; public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; private SensorManager sensorManager; //指南針的背景圖 private ImageView imgCompass; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); imgCompass = (ImageView) findViewById(R.id.img_compass); sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); //獲取加速傳感器,並為它注冊監聽器 Sensor accelerometerSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); sensorManager.registerListener(listener, accelerometerSensor, SensorManager.SENSOR_DELAY_GAME); //獲取地磁傳感器,並為它注冊監聽器 Sensor magneticSensor = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD); sensorManager.registerListener(listener, magneticSensor, SensorManager.SENSOR_DELAY_GAME); //注:SensorManager.SENSOR_DELAY_GAME為傳感器輸出信息的更新速度 } private SensorEventListener listener = new SensorEventListener() { float[] accelerometerValues = new float[3]; float[] magneticValues = new float[3]; private float lastRotateDegree; @Override public void onSensorChanged(SensorEvent event) { //判斷當前是加速傳感器還是地磁傳感器 if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) { //注意賦值的時候要調用close方法 accelerometerValues = event.values.clone(); } else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) { magneticValues = event.values.clone(); } float[] R = new float[9]; float[] values = new float[3]; SensorManager.getRotationMatrix(R, null, accelerometerValues, magneticValues); SensorManager.getOrientation(R, values); //values[0]表示是手機圍繞Z軸旋轉的弧度,Math.toDegrees()方法是將弧度轉化成角度 // Log.i(TAG, "values[0] is " + Math.toDegrees(values[0])); //values[0]的取值范圍是-180度到180度,其中±180度表示正南方向,0度表示正北方向,?90度表示正西方向,90度表示正東方向。 //將計算出的旋轉角度取反,用於旋轉指南針背景圖 float rotateDegree = -(float) 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); //執行旋轉動畫 imgCompass.startAnimation(animation); lastRotateDegree = rotateDegree; } } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { } }; @Override protected void onDestroy() { super.onDestroy(); if (null!=sensorManager){ sensorManager.unregisterListener(listener); } } }
主題設置:
在AndroidManifest文件裡面種application裡面的屬性theme設置值為@style/AppTheme,而AppTheme裡面設置
效果圖:
當然了,Android中支持的傳感器遠遠不只這些,還有壓力傳感器、溫度傳感器、陀螺儀傳感器等,不過由於這些傳感器都不太常用,而且不少Android手機中都沒有嵌入這些傳感器。
BlueStacks安卓模擬器屏幕窗口大小的調整方法,使用過BlueStacks安卓模擬器的朋友都知道,這款安卓模擬器非常好用,占用資源很少,但是有個缺點是
每次看IOS上的應用,應用中狀態欄的顏色總能與應用標題欄顏色保持一致,用戶體驗很不錯,對於這種效果,像我這種好奇心強的人就會去看看那安卓是否可以呢?若是在安卓4.4之前,
1.概念 Adapter是連接後端數據和前端顯示的適配器接口,是數據和UI(View)之間一個重要的紐帶。在常見的View(ListView,Grid
使用Intent調用語音識別程序說明Android中主要通過RecognizerIntent來實現語音識別,其實代碼比較簡單,但是如果找不到語音識別設備,就會拋出異常 A