今天繼續給你們帶來《Android應用開發全程實錄》中的章節,這部分是講傳感器中的一個實例。android
經過上面的例子咱們學會了如何得到某種類型的傳感器,下面經過一個實例來學習如何使用某一個類型的傳感器。咱們以加速傳感器爲例,來實現這樣一個功能:搖動手機便自動撥打某親情號碼,並實現再次搖動則掛機的功能。ide
工程目錄:EX_12_03佈局
第一步,UI佈局main.xml的代碼以下,其運行效果如圖12-10所示。學習
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent" >
- <TextView android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="當前狀態:就緒"
- android:id="@+id/state"
- android:textColor="#ff0000" />
- <Button android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:id="@+id/call"
- android:text="打電話(10086)"/>
- <Button android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:id="@+id/stop"
- android:text="掛機"/>
- </LinearLayout>
第二步,掛電話須要用到系統的Itelephony類的支持,因爲Google從Android 2.1 SDK版本後,屏蔽了com.android.internal.telephony. Itelephony類,所以,須要從Android×××,找到該類並導入到工程目錄下,記得包名一致。測試
第三步,Activity類ShakeSensorActivity的實現。該類實現SensorListener接口,添加加速度偵聽事件,經過判斷設備X、Y、Z方向的總晃動值來判斷是否啓動打電話和掛機操做。以撥打10086測試爲例,當設備總晃動值大於100做爲一個測試判斷點,若是當前沒有在通話界面,就經過Intent啓動撥打電話,不然就掛機操做。設備搖動時,啓動電話、掛機的界面狀態如圖圖12-十一、圖12-12所示。this
▲圖12-10 軟件運行效果圖spa
▲圖12-11 電話啓動界面 日誌
圖12-12 搖動設備掛機時的狀態界面xml
下面就來看看代碼:接口
- public class ShakeSensorActivity extends Activity implements SensorListener {
- private float lastX;
- private float lastY;
- private float lastZ;
- private View mainView;
- private long currTime;
- private long lastTime;
- private long duration;// 持續時間
- private float currShake;
- private float totalShake;
- private ITelephony iTelephony;
- private boolean isCalling = false;
- SensorManager sm = null;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- mainView = LinearLayout.inflate(this, R.layout.main, null);
- setContentView(mainView);
- ((Button) mainView.findViewById(R.id.call)).setOnClickListener(new
- OnClickListener() {
- @Override
- public void onClick(View v) {
- // 打電話
- callPhoneNumber10086();
- }
- });
- ((Button) mainView.findViewById(R.id.stop)).setOnClickListener(new OnClick- Listener() {
- @Override
- public void onClick(View v) {
- // 掛機
- closePhone();
- }
- });
- // 獲取傳感器管理器
- sm = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
- // 註冊加速度傳感器
- sm.registerListener(this,
- SensorManager.SENSOR_ACCELEROMETER,SensorManager. SENSOR_DELAY_NORMAL);
- }
- @Override
- public void finish() {
- // TODO Auto-generated method stub
- super.finish();
- sm.unregisterListener(this);// 註銷偵聽
- }
- @Override
- public void onAccuracyChanged(int sensor, int accuracy) {
- // 精度改變,該方法實質上不作任何操做,它只在每次調用時,添加一個日誌項
- }
- @Override
- public void onSensorChanged(int sensor, float[] values) {
- float x = values[0];
- float y = values[1];
- float z = values[2];
- currTime = System.currentTimeMillis();
- if (lastX == 0 && lastY == 0 && lastZ == 0) {
- // 第一次shake
- lastTime = currTime;
- }
- if (currTime - lastTime > 200) {// 200毫秒檢測一次
- duration = currTime - lastTime;
- currShake = (Math.abs(x - lastX) + Math.abs(y - lastY) + Math.abs(z - lastZ))/ duration * 200;
- }
- totalShake = totalShake + currShake;
- if (totalShake > 100) {
- totalShake = 0;// 重置爲0,從新累計計數
- lastX = 0;
- lastY = 0;
- lastZ = 0;
- lastTime = 0;
- currTime = 0;
- if (!isCalling) {
- callPhoneNumber10086();
- ((TextView) mainView.findViewById(R.id.state)).setText("當前狀態: 通話中...");
- } else {
- closePhone();
- ((TextView) mainView.findViewById(R.id.state)).setText("當前狀態:通話結束...");
- }
- }
- lastX = x;
- lastY = y;
- lastZ = z;
- lastTime = currTime;
- }
- /**
- * tell 10086打開通話界面
- */
- private synchronized void callPhoneNumber10086() {
- isCalling = true;
- Intent myIntentDial = new Intent(Intent.ACTION_CALL,Uri.parse("tel:" + 10086));
- startActivity(myIntentDial);
- }
- /**
- * 結束通話
- */
- private synchronized void closePhone() {
- try {
- getTelephony();
- iTelephony.endCall();
- isCalling = false;
- } catch (RemoteException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- /**
- * 初始電話 實例
- */
- public void getTelephony() {
- TelephonyManager telMgr = (TelephonyManager)
- this.getSystemService(Service. TELEPHONY_SERVICE);
- Class<TelephonyManager> c = TelephonyManager.class;
- Method getITelephonyMethod = null;
- try {
- getITelephonyMethod = c.getDeclaredMethod("getITelephony",(Class[]) null);
- getITelephonyMethod.setAccessible(true);
- } catch (SecurityException e) {
- e.printStackTrace();
- } catch (NoSuchMethodException e) {
- e.printStackTrace();
- }
- try {
- iTelephony = (ITelephony)
- getITelephonyMethod.invoke(telMgr,(Object[])null);
- } catch (IllegalArgumentException e) {
- e.printStackTrace();
- } catch (IllegalAccessException e) {
- e.printStackTrace();
- } catch (InvocationTargetException e) {
- e.printStackTrace();
- }
- }
經過getTelephony()方法,初始一個iTelephony實例,方便調用,目前只用到了掛機關閉通話,打電話也能夠經過iTelephony.dial(「10086」)直接撥打。這樣就輕鬆實現了甩動打掛電話功能了