![Android服務(wù)Service詳解電子版本_第1頁](http://file4.renrendoc.com/view/46f7d9c8d8f25c7cca39a584055cdc79/46f7d9c8d8f25c7cca39a584055cdc791.gif)
![Android服務(wù)Service詳解電子版本_第2頁](http://file4.renrendoc.com/view/46f7d9c8d8f25c7cca39a584055cdc79/46f7d9c8d8f25c7cca39a584055cdc792.gif)
![Android服務(wù)Service詳解電子版本_第3頁](http://file4.renrendoc.com/view/46f7d9c8d8f25c7cca39a584055cdc79/46f7d9c8d8f25c7cca39a584055cdc793.gif)
![Android服務(wù)Service詳解電子版本_第4頁](http://file4.renrendoc.com/view/46f7d9c8d8f25c7cca39a584055cdc79/46f7d9c8d8f25c7cca39a584055cdc794.gif)
![Android服務(wù)Service詳解電子版本_第5頁](http://file4.renrendoc.com/view/46f7d9c8d8f25c7cca39a584055cdc79/46f7d9c8d8f25c7cca39a584055cdc795.gif)
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、Good is good, but better carries it.精益求精,善益求善。Android服務(wù)Service詳解-第8章Android服務(wù)HYPERLINK/art/201006/206884.htmo8.1Service起步t_blank8.1Service起步HYPERLINK/art/201006/206885.htmo8.1.1Service的生命周期t_blank8.1.1Service的生命周期HYPERLINK/art/201006/206886.htmo8.1.2綁定Activity和Servicet_blank8.1.2綁定Activity和ServiceHY
2、PERLINK/art/201006/206887.htmo8.1.3在BroadcastReceiver中啟動Servicet_blank8.1.3在BroadcastReceiver中啟動Ser.HYPERLINK/art/201006/206889.htmo8.2.1獲得系統(tǒng)服務(wù)t_blank8.2.1獲得系統(tǒng)服務(wù)HYPERLINK/art/201006/206891.htmo8.2.2在模擬器上模擬重力感應(yīng)t_blank8.2.2在模擬器上模擬重力感應(yīng)HYPERLINK/art/201006/206892.htmo8.3.1計時器:Chronometert_blank8.3.1計時器:
3、ChronometerHYPERLINK/art/201006/207064.htmo8.3.2預(yù)約時間Handlert_blank8.3.2預(yù)約時間HandlerHYPERLINK/art/201006/207065.htmo8.3.4在線程中更新GUI組件t_blank8.3.4在線程中更新GUI組件HYPERLINK/art/201006/207066.htmo8.3.5全局定時器AlarmManager(1)t_blank8.3.5全局定時器AlarmManager(1)HYPERLINK/art/201006/207067.htmo8.3.5全局定時器AlarmManager(2)t
4、_blank8.3.5全局定時器AlarmManager(2)HYPERLINK/art/201006/207068.htmo8.3.5全局定時器AlarmManager(3)t_blank8.3.5全局定時器AlarmManager(3)HYPERLINK/art/201006/207069.htmo8.4.1什么是AIDL服務(wù)t_blank8.4.1什么是AIDL服務(wù)HYPERLINK/art/201006/207070.htmo8.4.2建立AIDL服務(wù)的步驟(1)t_blank8.4.2建立AIDL服務(wù)的步驟(1)HYPERLINK/art/201006/207071.htmo8.4.
5、2建立AIDL服務(wù)的步驟(2)t_blank8.4.2建立AIDL服務(wù)的步驟(2)HYPERLINK/art/201006/207072.htmo8.4.2建立AIDL服務(wù)的步驟(3)t_blank8.4.2建立AIDL服務(wù)的步驟(3)HYPERLINK/art/201006/207073.htmo8.5本章小結(jié)t_blank8.5本章小結(jié)第8章Android服務(wù)服務(wù)(Service)是Android系統(tǒng)中4個應(yīng)用程序組件之一(其他的組件詳見3.2節(jié)的內(nèi)容)。服務(wù)主要用于兩個目的:后臺運行和跨進(jìn)程訪問。通過啟動一個服務(wù),可以在不顯示界面的前提下在后臺運行指定的任務(wù),這樣可以不影響用戶做其他事情
6、。通過AIDL服務(wù)可以實現(xiàn)不同進(jìn)程之間的通信,這也是服務(wù)的重要用途之一。本章內(nèi)容Service的生命周期綁定Activity和Service在BroadcastReceiver中啟動Service系統(tǒng)服務(wù)時間服務(wù)在線程中更新GUI組件AIDL服務(wù)在AIDL服務(wù)中傳遞復(fù)雜的數(shù)據(jù)8.1Service起步Service并沒有實際界面,而是一直在Android系統(tǒng)的后臺運行。一般使用Service為應(yīng)用程序提供一些服務(wù),或不需要界面的功能,例如,從Internet下載文件、控制Video播放器等。本節(jié)主要介紹Service的啟動和結(jié)束過程(Service的生命周期)以及啟動Service的各種方法。8
7、.1.1Service的生命周期本節(jié)的例子代碼所在的工程目錄是srcch08ch08_servicelifecycleService與Activity一樣,也有一個從啟動到銷毀的過程,但Service的這個過程比Activity簡單得多。Service啟動到銷毀的過程只會經(jīng)歷如下3個階段:創(chuàng)建服務(wù)開始服務(wù)銷毀服務(wù)一個服務(wù)實際上是一個繼承android.app.Service的類,當(dāng)服務(wù)經(jīng)歷上面3個階段后,會分別調(diào)用Service類中的3個事件方法進(jìn)行交互,這3個事件方法如下:publicvoidonCreate();/創(chuàng)建服務(wù)publicvoidonStart(Intentintent,int
8、startId);/開始服務(wù)publicvoidonDestroy();/銷毀服務(wù)一個服務(wù)只會創(chuàng)建一次,銷毀一次,但可以開始多次,因此,onCreate和onDestroy方法只會被調(diào)用一次,而onStart方法會被調(diào)用多次。下面編寫一個服務(wù)類,具體看一下服務(wù)的生命周期由開始到銷毀的過程。packagenet.blogjava.mobile.service;importandroid.app.Service;importandroid.content.Intent;importandroid.os.IBinder;importandroid.util.Log;/MyService是一個服務(wù)類,
9、該類必須從android.app.Service類繼承publicclassMyServiceextendsServiceOverridepublicIBinderonBind(Intentintent)returnnull;/當(dāng)服務(wù)第1次創(chuàng)建時調(diào)用該方法OverridepublicvoidonCreate()Log.d(MyService,onCreate);super.onCreate();/當(dāng)服務(wù)銷毀時調(diào)用該方法OverridepublicvoidonDestroy()Log.d(MyService,onDestroy);super.onDestroy();/當(dāng)開始服務(wù)時調(diào)用該方法Ove
10、rridepublicvoidonStart(Intentintent,intstartId)Log.d(MyService,onStart);super.onStart(intent,startId);在MyService中覆蓋了Service類中3個生命周期方法,并在這些方法中輸出了相應(yīng)的日志信息,以便更容易地觀察事件方法的調(diào)用情況。讀者在編寫Android的應(yīng)用組件時要注意,不管是編寫什么組件(例如,Activity、Service等),都需要在AndroidManifest.xml文件中進(jìn)行配置。MyService類也不例外。配置這個服務(wù)類很簡單,只需要在AndroidManifest
11、.xml文件的標(biāo)簽中添加如下代碼即可:其中android:enabled屬性的值為true,表示MyService服務(wù)處于激活狀態(tài)。雖然目前MyService是激活的,但系統(tǒng)仍然不會啟動MyService,要想啟動這個服務(wù)。必須顯式地調(diào)用startService方法。如果想停止服務(wù),需要顯式地調(diào)用stopService方法,代碼如下:publicvoidonClick(Viewview)switch(view.getId()caseR.id.btnStartService:startService(serviceIntent);/單擊【StartService】按鈕啟動服務(wù)break;case
12、R.id.btnStopService:stopService(serviceIntent);/單擊【StopService】按鈕停止服務(wù)break;其中serviceIntent是一個Intent對象,用于指定MyService服務(wù),創(chuàng)建該對象的代碼如下:serviceIntent=newIntent(this,MyService.class);運行本節(jié)的例子后,會顯示如圖8.1所示的界面。HYPERLINK/files/uploadimg/20060921/153223104.gift_blank圖8.1開始和停止服務(wù)第1次單擊【StartService】按鈕后,在DDMS透視圖的LogC
13、at視圖的Message列會輸出如下兩行信息:onCreateonStart然后單擊【StopService】按鈕,會在Message列中輸出如下信息:onDestroy下面按如下的單擊按鈕順序的重新測試一下本例?!維tartService】【StopService】【StartService】【StartService】【StartService】【StopService】測試完程序,就會看到如圖8.2所示的輸出信息??梢钥闯觯辉诘?次單擊【StartService】按鈕后會調(diào)用onCreate方法,如果在未單擊【StopService】按鈕時多次單擊【StartService】按鈕,系統(tǒng)
14、只在第1次單擊【StartService】按鈕時調(diào)用onCreate和onStart方法,再單擊該按鈕時,系統(tǒng)只會調(diào)用onStart方法,而不會再次調(diào)用onCreate方法。HYPERLINK/files/uploadimg/20100621/171557332.jpgt_blankHYPERLINK/files/uploadimg/20060921/153223104.gift_blank圖8.2服務(wù)的生命周期方法的調(diào)用情況在討論完服務(wù)的生命周期后,再來總結(jié)一下創(chuàng)建和開始服務(wù)的步驟。創(chuàng)建和開始一個服務(wù)需要如下3步:(1)編寫一個服務(wù)類,該類必須從android.app.Service繼承。S
15、ervice類涉及到3個生命周期方法,但這3個方法并不一定在子類中覆蓋,讀者可根據(jù)不同需求來決定使用哪些生命周期方法。在Service類中有一個onBind方法,該方法是一個抽象方法,在Service的子類中必須覆蓋。這個方法當(dāng)Activity與Service綁定時被調(diào)用(將在8.1.3節(jié)詳細(xì)介紹)。(2)在AndroidManifest.xml文件中使用標(biāo)簽來配置服務(wù),一般需要將標(biāo)簽的android:enabled屬性值設(shè)為true,并使用android:name屬性指定在第1步建立的服務(wù)類名。(3)如果要開始一個服務(wù),使用startService方法,停止一個服務(wù)要使用stopServic
16、e方法。8.1.2綁定Activity和Service本節(jié)的例子代碼所在的工程目錄是srcch08ch08_serviceactivity如果使用8.1.1節(jié)介紹的方法啟動服務(wù),并且未調(diào)用stopService來停止服務(wù),這個服務(wù)就會隨著Android系統(tǒng)的啟動而啟動,隨著Android系統(tǒng)的關(guān)閉而關(guān)閉。也就是服務(wù)會在Android系統(tǒng)啟動后一直在后臺運行,直到Android系統(tǒng)關(guān)閉后服務(wù)才停止。但有時我們希望在啟動服務(wù)的Activity關(guān)閉后服務(wù)自動關(guān)閉,這就需要將Activity和Service綁定。通過bindService方法可以將Activity和Service綁定。bindServ
17、ice方法的定義如下:publicbooleanbindService(Intentservice,ServiceConnectionconn,intflags)該方法的第1個參數(shù)表示與服務(wù)類相關(guān)聯(lián)的Intent對象,第2個參數(shù)是一個ServiceConnection類型的變量,負(fù)責(zé)連接Intent對象指定的服務(wù)。通過ServiceConnection對象可以獲得連接成功或失敗的狀態(tài),并可以獲得連接后的服務(wù)對象。第3個參數(shù)是一個標(biāo)志位,一般設(shè)為Context.BIND_AUTO_CREATE。下面重新編寫8.1.1節(jié)的MyService類,在該類中增加了幾個與綁定相關(guān)的事件方法。package
18、net.blogjava.mobile.service;importandroid.app.Service;importandroid.content.Intent;importandroid.os.Binder;importandroid.os.IBinder;importandroid.util.Log;publicclassMyServiceextendsServiceprivateMyBindermyBinder=newMyBinder();/成功綁定后調(diào)用該方法OverridepublicIBinderonBind(Intentintent)Log.d(MyService,onBin
19、d);returnmyBinder;/重新綁定時調(diào)用該方法OverridepublicvoidonRebind(Intentintent)Log.d(MyService,onRebind);super.onRebind(intent);/解除綁定時調(diào)用該方法OverridepublicbooleanonUnbind(Intentintent)Log.d(MyService,onUnbind);returnsuper.onUnbind(intent);OverridepublicvoidonCreate()Log.d(MyService,onCreate);super.onCreate();Ov
20、erridepublicvoidonDestroy()Log.d(MyService,onDestroy);super.onDestroy();OverridepublicvoidonStart(Intentintent,intstartId)Log.d(MyService,onStart);super.onStart(intent,startId);publicclassMyBinderextendsBinderMyServicegetService()returnMyService.this;現(xiàn)在定義一個MyService變量和一個ServiceConnection變量,代碼如下:priv
21、ateMyServicemyService;privateServiceConnectionserviceConnection=newServiceConnection()/連接服務(wù)失敗后,該方法被調(diào)用OverridepublicvoidonServiceDisconnected(ComponentNamename)myService=null;Toast.makeText(Main.this,ServiceFailed.,Toast.LENGTH_LONG).show();/成功連接服務(wù)后,該方法被調(diào)用。在該方法中可以獲得MyService對象OverridepublicvoidonServ
22、iceConnected(ComponentNamename,IBinderservice)/獲得MyService對象myService=(MyService.MyBinder)service).getService();Toast.makeText(Main.this,ServiceConnected.,Toast.LENGTH_LONG).show();最后使用bindService方法來綁定Activity和Service,代碼如下:bindService(serviceIntent,serviceConnection,Context.BIND_AUTO_CREATE);如果想解除綁定
23、,可以使用下面的代碼:unbindService(serviceConnection);在MyService類中定義了一個MyBinder類,該類實際上是為了獲得MyService的對象實例的。在ServiceConnection接口的onServiceConnected方法中的第2個參數(shù)是一個IBinder類型的變量,將該參數(shù)轉(zhuǎn)換成MyService.MyBinder對象,并使用MyBinder類中的getService方法獲得MyService對象。在獲得MyService對象后,就可以在Activity中隨意操作MyService了。運行本節(jié)的例子后,單擊【BindService】按鈕,
24、如果綁定成功,會顯示如圖8.3所示的信息提示框。關(guān)閉應(yīng)用程序后,會看到在LogCat視圖中輸出了onUnbind和onDestroy信息,表明在關(guān)閉Activity后,服務(wù)先被解除綁定,最后被銷毀。如果先啟動(調(diào)用startService方法)一個服務(wù),然后再綁定(調(diào)用bindService方法)服務(wù),會怎么樣呢?在這種情況下,雖然服務(wù)仍然會成功綁定到Activity上,但在Activity關(guān)閉后,服務(wù)雖然會被解除綁定,但并不會被銷毀,也就是說,MyService類的onDestroy方法不會被調(diào)用。HYPERLINK/files/uploadimg/20060921/153223104.gi
25、ft_blank圖8.3綁定服務(wù)8.1.3在BroadcastReceiver中啟動Service本節(jié)的例子代碼所在的工程目錄是srcch08ch08_startupservice在8.1.1節(jié)和8.1.2節(jié)都是先啟動了一個Activity,然后在Activity中啟動服務(wù)。如果是這樣,在啟動服務(wù)時必須要先啟動一個Activity。在很多時候這樣做有些多余,閱讀完第7章的內(nèi)容,會發(fā)現(xiàn)實例43可以利用BroadcastReceiver在Android系統(tǒng)啟動時運行一個Activity。也許我們會從中得到一些啟發(fā),既然可以在BroadcastReceiver中啟動Activity,為什么不能啟動S
26、ervice呢?說做就做,現(xiàn)在讓我們來驗證一下這個想法。先編寫一個服務(wù)類,這個服務(wù)類沒什么特別的,仍然使用前面兩節(jié)編寫的MyService類即可。在AndroidManifest.xml文件中配置MyService類的代碼也相同。下面來完成最關(guān)鍵的一步,就是建立一個BroadcastReceiver,代碼如下:packagenet.blogjava.mobile.startupservice;importandroid.content.BroadcastReceiver;importandroid.content.Context;importandroid.content.Intent;pub
27、licclassStartupReceiverextendsBroadcastReceiverOverridepublicvoidonReceive(Contextcontext,Intentintent)/啟動一個ServiceIntentserviceIntent=newIntent(context,MyService.class);context.startService(serviceIntent);IntentactivityIntent=newIntent(context,MessageActivity.class);/要想在Service中啟動Activity,必須設(shè)置如下標(biāo)志a
28、ctivityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);context.startActivity(activityIntent);在StartupReceiver類的onReceive方法中完成了兩項工作:啟動服務(wù)和顯示一個Activity來提示服務(wù)啟動成功。其中MessageActivity是一個普通的Activity類,只是該類在配置時使用了android:style/Theme.Dialog主題,因此,如果服務(wù)啟動成功,會顯示如圖8.4所示的信息。HYPERLINK/files/uploadimg/20100621/1703220.j
29、pgt_blankHYPERLINK/files/uploadimg/20060921/153223104.gift_blank圖8.4在BroadcastReceiver中啟動服務(wù)如果安裝本例后,在重新啟動模擬器后并未出現(xiàn)如圖8.4所示的信息提示框,最大的可能是沒有在AndroidManifest.xml文件中配置BroadcastReceiver和Service,下面來看一下AndroidManifest.xml文件的完整代碼?,F(xiàn)在運行本例,然后重啟一下模擬器,看看LogCat視圖中是否輸出了相應(yīng)的日志信息。8.2系統(tǒng)服務(wù)在Android系統(tǒng)中有很多內(nèi)置的軟件,例如,當(dāng)手機(jī)接到來電時,會顯
30、示對方的電話號。也可以根據(jù)周圍的環(huán)境將手機(jī)設(shè)置成震動或靜音。如果想把這些功能加到自己的軟件中應(yīng)該怎么辦呢?答案就是系統(tǒng)服務(wù)。在Android系統(tǒng)中提供了很多這種服務(wù),通過這些服務(wù),就可以像Android系統(tǒng)的內(nèi)置軟件一樣隨心所欲地控制Android系統(tǒng)了。本節(jié)將介紹幾種常用的系統(tǒng)服務(wù)來幫助讀者理解和使用這些技術(shù)。8.2.1獲得系統(tǒng)服務(wù)系統(tǒng)服務(wù)實際上可以看作是一個對象,通過Activity類的getSystemService方法可以獲得指定的對象(系統(tǒng)服務(wù))。getSystemService方法只有一個String類型的參數(shù),表示系統(tǒng)服務(wù)的ID,這個ID在整個Android系統(tǒng)中是唯一的。例如,
31、audio表示音頻服務(wù),window表示窗口服務(wù),notification表示通知服務(wù)。為了便于記憶和管理,AndroidSDK在android.content.Context類中定義了這些ID,例如,下面的代碼是一些ID的定義。publicstaticfinalStringAUDIO_SERVICE=audio;/定義音頻服務(wù)的IDpublicstaticfinalStringWINDOW_SERVICE=window;/定義窗口服務(wù)的IDpublicstaticfinalStringNOTIFICATION_SERVICE=notification;/定義通知服務(wù)的ID下面的代碼獲得了剪貼
32、板服務(wù)(android.text.ClipboardManager對象)。/獲得ClipboardManager對象android.text.ClipboardManagerclipboardManager=(android.text.ClipboardManager)getSystemService(Context.CLIPBOARD_SERVICE);clipboardManager.setText(設(shè)置剪貼版中的內(nèi)容);在調(diào)用ClipboardManager.setText方法設(shè)置文本后,在Android系統(tǒng)中所有的文本輸入框都可以從這個剪貼板對象中獲得這段文本,讀者不妨自己試一試!窗口
33、服務(wù)(WindowManager對象)是最常用的系統(tǒng)服務(wù)之一,通過這個服務(wù),可以獲得很多與窗口相關(guān)的信息,例如,窗口的長度和寬度,如下面的代碼所示:/獲得WindowManager對象android.view.WindowManagerwindowManager=(android.view.WindowManager)getSystemService(Context.WINDOW_SERVICE);/在窗口的標(biāo)題欄輸出當(dāng)前窗口的寬度和高度,例如,320*480setTitle(String.valueOf(windowManager.getDefaultDisplay().getWidth()
34、+*+String.valueOf(windowManager.getDefaultDisplay().getHeight();本節(jié)簡單介紹了如何獲得系統(tǒng)服務(wù)以及兩個常用的系統(tǒng)服務(wù)的使用方法,在接下來的實例47和實例48中將給出兩個完整的關(guān)于獲得和使用系統(tǒng)服務(wù)的例子以供讀者參考。實例47:監(jiān)聽手機(jī)來電工程目錄:srcch08ch08_phonestate當(dāng)來電話時,手機(jī)會顯示對方的電話號,當(dāng)接聽電話時,會顯示當(dāng)前的通話狀態(tài)。在這期間存在兩個狀態(tài):來電狀態(tài)和接聽狀態(tài)。如果在應(yīng)用程序中要監(jiān)聽這兩個狀態(tài),并進(jìn)行一些其他處理,就需要使用電話服務(wù)(TelephonyManager對象)。本例通過Tele
35、phonyManager對象監(jiān)聽來電狀態(tài)和接聽狀態(tài),并在相應(yīng)的狀態(tài)顯示一個Toast提示信息框。如果是來電狀態(tài),會顯示對方的電話號,如果是通話狀態(tài),會顯示正在通話.信息。下面先來看看來電和接聽時的效果,如圖8.5和圖8.6所示。HYPERLINK/files/uploadimg/20060921/153223104.gift_blank圖8.5來電狀態(tài)HYPERLINK/files/uploadimg/20060921/153223104.gift_blank圖8.6接聽狀態(tài)要想獲得TelephonyManager對象,需要使用Context.TELEPHONY_SERVICE常量,代碼如下:
36、TelephonyManagertm=(TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);MyPhoneCallListenermyPhoneCallListener=newMyPhoneCallListener();/設(shè)置電話狀態(tài)監(jiān)聽器tm.listen(myPhoneCallListener,PhoneStateListener.LISTEN_CALL_STATE);其中MyPhoneCallListener類是一個電話狀態(tài)監(jiān)聽器,該類是PhoneStateListener的子類,代碼如下:publicclassMyP
37、honeCallListenerextendsPhoneStateListenerOverridepublicvoidonCallStateChanged(intstate,StringincomingNumber)switch(state)/通話狀態(tài)caseTelephonyManager.CALL_STATE_OFFHOOK:Toast.makeText(Main.this,正在通話.,Toast.LENGTH_SHORT).show();break;/來電狀態(tài)caseTelephonyManager.CALL_STATE_RINGING:Toast.makeText(Main.this,
38、incomingNumber,Toast.LENGTH_SHORT).show();break;super.onCallStateChanged(state,incomingNumber);如果讀者是在模擬器上測試本例,可以使用DDMS透視圖的【EmulatorControl】視圖模擬打入電話。進(jìn)入【EmulatorControl】視圖,會看到如圖8.7所示的界面。在【Incomingnumber】文本框中輸入一個電話號,選中【Voice】選項,單擊【Call】按鈕,這時模擬器就會接到來電。如果已經(jīng)運行本例,在來電和接聽狀態(tài)就會顯示如圖8.5和圖8.6所示的Toast提示信息。HYPERLIN
39、K/files/uploadimg/20100622/125002633.jpgt_blankHYPERLINK/files/uploadimg/20060921/153223104.gift_blank圖8.7用【EmulatorControl】視圖模擬撥打電話實例48:來電黑名單工程目錄:srcch08ch08_phoneblacklist雖然手機(jī)為我們帶來了方便,但有時實在不想接聽某人的電話,但又不好直接掛斷電話,怎么辦呢?很簡單,如果發(fā)現(xiàn)是某人來的電話,直接將手機(jī)設(shè)成靜音,這樣就可以不予理睬了。本例與實例47類似,也就是說,仍然需要獲得TelephonyManager對象,并監(jiān)聽手機(jī)的
40、來電狀態(tài)。為了可以將手機(jī)靜音,還需要獲得一個音頻服務(wù)(AudioManager對象)。本例需要修改實例47中的手機(jī)接聽狀態(tài)方法onCallStateChanged中的代碼,修改后的結(jié)果如下:publicclassMyPhoneCallListenerextendsPhoneStateListenerOverridepublicvoidonCallStateChanged(intstate,StringincomingNumber)/獲得音頻服務(wù)(AudioManager對象)AudioManageraudioManager=(AudioManager)getSystemService(Cont
41、ext.AUDIO_SERVICE);switch(state)caseTelephonyManager.CALL_STATE_IDLE:/在手機(jī)空閑狀態(tài)時,將手機(jī)音頻設(shè)為正常狀態(tài)audioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);break;caseTelephonyManager.CALL_STATE_RINGING:/在來電狀態(tài)時,判斷打進(jìn)來的是否為要靜音的電話號,如果是,則靜音if(12345678.equals(incomingNumber)/將電話靜音audioManager.setRingerMode(Audio
42、Manager.RINGER_MODE_SILENT);break;super.onCallStateChanged(state,incomingNumber);在上面的代碼中,只設(shè)置了12345678為靜音電話號,讀者可以采用實例47的方法使用12345678打入電話,再使用其他的電話號打入,看看模擬器是否會響鈴。8.2.2在模擬器上模擬重力感應(yīng)眾所周知,Android系統(tǒng)支持重力感應(yīng),通過這種技術(shù),可以利用手機(jī)的移動、翻轉(zhuǎn)來實現(xiàn)更為有趣的程序。但遺憾的是,在Android模擬器上是無法進(jìn)行重力感應(yīng)測試的。既然Android系統(tǒng)支持重力感應(yīng),但又在模擬器上無法測試,該怎么辦呢?別著急,天無絕
43、人之路,有一些第三方的工具可以幫助我們完成這個工作,本節(jié)將介紹一種在模擬器上模擬重力感應(yīng)的工具(sensorsimulator)。這個工具分為服務(wù)端和客戶端兩部分。服務(wù)端是一個在PC上運行的JavaSwingGUI程序,客戶端是一個手機(jī)程序(apk文件),在運行時需要通過客戶端程序連接到服務(wù)端程序上才可以在模擬器上模擬重力感應(yīng)。讀者可以從下面的地址下載這個工具:/p/openintents/downloads/list進(jìn)入下載頁面后,下載如圖8.8所示的黑框中的zip文件。HYPERLINK/files/uploadimg/20060921/153223104.gift_blank(點擊查看大
44、圖)圖8.8sensorsimulator下載頁面將zip文件解壓后,運行bin目錄中的sensorsimulator.jar文件,會顯示如圖8.9所示的界面。界面的左上角是一個模擬手機(jī)位置的三維圖形,右上角可以通過滑桿來模擬手機(jī)的翻轉(zhuǎn)、移動等操作。HYPERLINK/files/uploadimg/20060921/153223104.gift_blank(點擊查看大圖)圖8.9sensorsimulator主界面下面來安裝客戶端程序,先啟動Android模擬器,然后使用下面的命令安裝bin目錄中的SensorSimulatorSettings.apk文件。adbinstallSensorS
45、imulatorSettings.apk如果安裝成功,會在模擬器中看到如圖8.10所示黑框中的圖標(biāo)。運行這個程序,會進(jìn)入如圖8.11所示的界面。在IP地址中輸入如圖8.9所示黑框中的IP(注意,每次啟動服務(wù)端程序時這個IP可能不一樣,應(yīng)以每次啟動服務(wù)端程序時的IP為準(zhǔn))。最后進(jìn)入【Testing】頁,單擊【Connect】按鈕,如果連接成功,會顯示如圖8.12所示的效果。HYPERLINK/files/uploadimg/20060921/153223104.gift_blank圖8.10安裝客戶端設(shè)置軟件HYPERLINK/files/uploadimg/20060921/153223104
46、.gift_blank圖8.11進(jìn)行客戶端設(shè)置下面來測試一下SensorSimulator自帶的一個demo,在這個demo中輸出了通過模擬重力感應(yīng)獲得的數(shù)據(jù)。這個demo就在samples目錄中,該目錄有一個SensorDemo子目錄,是一個Eclipse工程目錄。讀者可以直接使用Eclipse導(dǎo)入這個目錄,并運行程序,如果顯示的結(jié)果如圖8.13所示,說明成功使用SensorSimulator在Android模擬器上模擬了重力感應(yīng)。HYPERLINK/files/uploadimg/20060921/153223104.gift_blank圖8.12測試連接狀態(tài)HYPERLINK/files
47、/uploadimg/20060921/153223104.gift_blank圖8.13測試重力感應(yīng)demo在實例49中將給出一個完整的例子來演示如何利用重力感應(yīng)的功能來實現(xiàn)手機(jī)翻轉(zhuǎn)靜音的效果。實例49:手機(jī)翻轉(zhuǎn)靜音工程目錄:srcch08ch08_phonereversal與手機(jī)來電一樣,手機(jī)翻轉(zhuǎn)狀態(tài)(重力感應(yīng))也由系統(tǒng)服務(wù)提供。重力感應(yīng)服務(wù)(android.hardware.SensorManager對象)可以通過如下代碼獲得:SensorManagersensorManager=(SensorManager)getSystemService(Context.SENSOR_SERVICE
48、);本例需要在模擬器上模擬重力感應(yīng),因此,在本例中使用SensorSimulator中的一個類(SensorManagerSimulator)來獲得重力感應(yīng)服務(wù),這個類封裝了SensorManager對象,并負(fù)責(zé)與服務(wù)端進(jìn)行通信,監(jiān)聽重力感應(yīng)事件也需要一個監(jiān)聽器,該監(jiān)聽器需要實現(xiàn)SensorListener接口,并通過該接口的onSensorChanged事件方法獲得重力感應(yīng)數(shù)據(jù)。本例完整的代碼如下:packagenet.blogjava.mobile;importorg.openintents.sensorsimulator.hardware.SensorManagerSimulator;i
49、mportandroid.app.Activity;importandroid.content.Context;importandroid.hardware.SensorListener;importandroid.hardware.SensorManager;importandroid.media.AudioManager;importandroid.os.Bundle;importandroid.widget.TextView;publicclassMainextendsActivityimplementsSensorListenerprivateTextViewtvSensorState
50、;privateSensorManagerSimulatorsensorManager;OverridepublicvoidonAccuracyChanged(intsensor,intaccuracy)OverridepublicvoidonSensorChanged(intsensor,floatvalues)switch(sensor)caseSensorManager.SENSOR_ORIENTATION:/獲得聲音服務(wù)AudioManageraudioManager=(AudioManager)getSystemService(Context.AUDIO_SERVICE);/在這里規(guī)
51、定翻轉(zhuǎn)角度小于-120度時靜音,values2表示翻轉(zhuǎn)角度,也可以設(shè)置其他角度if(values2-120)audioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);elseaudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);tvSensorState.setText(角度:+String.valueOf(values2);break;OverrideprotectedvoidonResume()/注冊重力感應(yīng)監(jiān)聽事件sensorManager.registerLi
52、stener(this,SensorManager.SENSOR_ORIENTATION);super.onResume();OverrideprotectedvoidonStop()/取消對重力感應(yīng)的監(jiān)聽sensorManager.unregisterListener(this);super.onStop();OverridepublicvoidonCreate(BundlesavedInstanceState)super.onCreate(savedInstanceState);setContentView(R.layout.main);/通過SensorManagerSimulator對
53、象獲得重力感應(yīng)服務(wù)sensorManager=(SensorManagerSimulator)SensorManagerSimulator.getSystemService(this,Context.SENSOR_SERVICE);/連接到服務(wù)端程序(必須執(zhí)行下面的代碼)sensorManager.connectSimulator();在上面的代碼中使用了一個SensorManagerSimulator類,該類在SensorSimulator工具包帶的sensorsimulator-lib.jar文件中,可以在lib目錄中找到這個jar文件。在使用SensorManagerSimulator類
54、之前,必須在相應(yīng)的Eclipse工程中引用這個jar文件。現(xiàn)在運行本例,并通過服務(wù)端主界面右側(cè)的【Roll】滑動桿移動到指定的角度,例如,-74.0和-142.0,這時設(shè)置的角度會顯示在屏幕上,如圖8.14和圖8.15所示。HYPERLINK/files/uploadimg/20100622/140139977.jpgt_blankHYPERLINK/files/uploadimg/20060921/153223104.gift_blank圖8.14翻轉(zhuǎn)角度大于-120度HYPERLINK/files/uploadimg/20100622/140139977.jpgt_blankHYPERLI
55、NK/files/uploadimg/20060921/153223104.gift_blank圖8.15翻轉(zhuǎn)角度小于-120度讀者可以在如圖8.14和圖8.15所示的翻轉(zhuǎn)狀態(tài)下?lián)苋腚娫挘瑫l(fā)現(xiàn)翻轉(zhuǎn)角度在-74.0度時來電仍然會響鈴,而翻轉(zhuǎn)角度在-142.0度時就不再響鈴了。由于SensorSimulator目前不支持AndroidSDK1.5及以上版本,因此,只能使用AndroidSDK1.1中的SensorListener接口來監(jiān)聽重力感應(yīng)事件。在AndroidSDK1.5及以上版本并不建議繼續(xù)使用這個接口,代替它的是android.hardware.SensorEventListener
56、接口。8.3.1計時器:Chronometer8.3時間服務(wù)在AndroidSDK中提供了多種時間服務(wù)。這些時間服務(wù)主要處理在一定時間間隔或未來某一時間發(fā)生的任務(wù)。Android系統(tǒng)中的時間服務(wù)的作用域既可以是應(yīng)用程序本身,也可以是整個Android系統(tǒng)。本節(jié)將詳細(xì)介紹這些時間服務(wù)的使用方法,并給出大量的實例供讀者學(xué)習(xí)。8.3.1計時器:Chronometer本節(jié)的例子代碼所在的工程目錄是srcch08ch08_chronometerChronometer是TextView的子類,也是一個Android組件。這個組件可以用1秒的時間間隔進(jìn)行計時,并顯示出計時結(jié)果。Chronometer類有3個
57、重要的方法:start、stop和setBase,其中start方法表示開始計時;stop方法表示停止計時;setBase方法表示重新計時。start和stop方法沒有任何參數(shù),setBase方法有一個參數(shù),表示開始計時的基準(zhǔn)時間。如果要從當(dāng)前時刻重新計時,可以將該參數(shù)值設(shè)為SystemClock.elapsedRealtime()。還可以對Chronometer組件做進(jìn)一步設(shè)置。在默認(rèn)情況下,Chronometer組件只輸出MM:SS或H:MM:SS的時間格式。例如,當(dāng)計時到1分20秒時,Chronometer組件會顯示01:20。如果想改變顯示的信息內(nèi)容,可以使用Chronometer類的
58、setFormat方法。該方法需要一個String變量,并使用%s表示計時信息。例如,使用setFormat(計時信息:%s)設(shè)置顯示信息,Chronometer組件會顯示如下計時信息:計時信息:10:20Chronometer組件還可以通過onChronometerTick事件方法來捕捉計時動作。該方法1秒調(diào)用一次。要想使用onChronometerTick事件方法,必須實現(xiàn)如下接口:android.widget.Chronometer.OnChronometerTickListener在本例中有3個按鈕,分別用來開始、停止和重置計時器,并通過onChronometerTick事件方法顯示當(dāng)
59、前時間,代碼如下:packagenet.blogjava.mobile;importjava.text.SimpleDateFormat;importjava.util.Date;importandroid.app.Activity;importandroid.os.Bundle;importandroid.os.SystemClock;importandroid.view.View;importandroid.view.View.OnClickListener;importandroid.widget.Button;importandroid.widget.Chronometer;impor
60、tandroid.widget.TextView;importandroid.widget.Chronometer.OnChronometerTickListener;publicclassMainextendsActivityimplementsOnClickListener,OnChronometerTickListenerprivateChronometerchronometer;privateTextViewtvTime;OverridepublicvoidonClick(Viewview)switch(view.getId()caseR.id.btnStart:/開始計時器chron
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 冷凍產(chǎn)品購銷合同年
- 單位租車合同協(xié)議
- 航空物流與服務(wù)作業(yè)指導(dǎo)書
- 購買信報箱合同
- 互聯(lián)網(wǎng)金融產(chǎn)品開發(fā)作業(yè)指導(dǎo)書
- 經(jīng)營部國際合作處外事接待管理員崗位說明書
- 裝修合同大全
- 2025年吉林市b2貨運資格證全題
- 2025年岳陽貨運從業(yè)資格證考試試題及答案
- 2025年鄭州駕校考試貨運從業(yè)資格證模擬考試
- 周口2024年河南周口市公安機(jī)關(guān)招聘輔警458人筆試歷年參考題庫附帶答案詳解
- 《頭面部穴位按摩》課件
- 2024美團(tuán)簡化版商家合作合同標(biāo)準(zhǔn)文本一
- 2025年貴州黔源電力股份有限公司招聘筆試參考題庫含答案解析
- 《休閑食品加工技術(shù)》 課件 1 休閑食品生產(chǎn)與職業(yè)生活
- 春季開學(xué)安全第一課
- 《病史采集》課件
- 十大護(hù)理安全隱患
- 2025年新生兒黃疸診斷與治療研究進(jìn)展
- 廣東大灣區(qū)2024-2025學(xué)年度高一上學(xué)期期末統(tǒng)一測試英語試題(無答案)
- 失效模式和效應(yīng)分析護(hù)理
評論
0/150
提交評論