Download presentation
Presentation is loading. Please wait.
1
Android Application Component
Chapter 7 Android Application Component Android應用元件可以幫助我們獲得系統資源訊息(ActivityManager)、提供系統服務(Service)、搜尋系統服務(SearchManager)、監聽Intent訊息(Broadcast Receiver)以及資料共享(ContentProvider和ContentResolver)。
2
ActivityManager
3
Description of Functions
ActivityManager ActivityManager can manage a variety of activities. The table below shows nested classes provided by ActivityManager: Class Name Description of Functions ActivityManager.MemoryInfo Information related to memory ActivityManager.ProcessErrorStateInfo Information related to process error state ActivityManager.RecentTaskInfo Information related to related to recent task ActivityManager.RunningAppProcessInfo Information related to running application process ActivityManager.RunningServiceInfo Information related to running service ActivityManager.RunningTaskInfo Information related to running task
4
ActivityManager In this section, we take “get available space of memory” as our example. The codes are shown below: public class ActivityManagerExample extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); TextView tv = (TextView) findViewById(R.id.info); ActivityManager myManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE); // 建立ActivityManager.MemoryInfo物件 ActivityManager.MemoryInfo outInfo = new ActivityManager.MemoryInfo(); // 利用getMemoryInfo方法獲取剩餘記憶體資訊 myManager.getMemoryInfo(outInfo); // 將得到之記憶體大小除1024轉換單位為KB tv.setText("剩餘記憶體: " + (outInfo.availMem/1024) + " KB"); } 在範例中,建構一個ActivityManager物件,並使用getSystemService方法來取得ACTIVITY_SERVICE的資訊,使用方法如下: ActivityManager myManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE); 接著建構一個MemoryInfo物件,利用ActivityManager中的getMemoryInfo方法將資訊存入outInfo物件中,最後將availMem顯示在TextView上,由於availMem單位為Byte,故在此將其值置換為KiloByte,範例結果如圖7.1,左圖為程式所抓取的資料,右圖為系統內建工具抓取的資料。
5
ActivityManager Results of the example is shown below. The left is the result of execution , and the right is system status display: 左圖為程式所抓取的資料,右圖為系統內建工具抓取的資料。
6
Service
7
Service Service是運行在背景的服務,如聽音樂時,可利用Service讓音樂在背景執行,這樣就可以關閉執行音樂的Activity來做其他事情,當要關閉音樂時,可以在抓取Service資訊後將其停止或是其他動作。 Service服務必須對應到AndroidManifest.xml。Service可由Activity來啟動,啟動之後可利用BroadcastReceiver 來取得相關Service訊息。
8
Service 本節範例利用Service服務在背景執行來實作一個簡易Timer,並利用Logcat來觀看結果,範例程式碼如下:
public class ServiceExample extends Activity { @Override public void onCreate(Bundle savedInstanceState) { // 略 myButton.setOnClickListener(new OnClickListener(){ public void onClick(View v) { if ( myButton.getText().equals("開始計時") ) { myButton.setText("停止計時"); Intent i = new Intent(ServiceExample.this, myService.class); startService(i); } else { myButton.setText("開始計時"); stopService(i); }); 範例主要分為兩個部分,Activity部分為ServiceExample,Service部分為myService,而範例是在Activity中啟用myService這個Service,使用方法如下: Intent i = new Intent(ServiceExample.this, myService.class); startService(i); Complete codes please refer to : ServiceExample.java in reference disc
9
Service Build a Service Class Complete codes please refer to :
public class myService extends Service { // 此Thread每次迴圈會sleep 1秒用來計算此Service執行的總時間 // 並傳送Message訊息 // Service尚未結束則傳送PRINT Message // 當接收到Thread傳送Message訊息時,若訊息內容為PRINT則印出 // 此Service目前執行的總時間,若收到STOP訊息時則停止Thread運作 // 覆寫onStart讓Service開始時執行指定的動作 @Override public void onStart (Intent intent, int startId) { } // 覆寫onDestroy讓Service結束時執行指定的動作 public void onDestroy(){ // Service結束時傳送STOP Message用來停止Thread 而在myService中,我們override三個基本的Service Method,分別為: public void onStart (Intent intent, int startId) { // do something } onStart為startService時執行的Method。 public IBinder onBind(Intent intent) { // do something } onBind為Service必備的Method。 public void onDestroy(){ // do something } onDestroy為stopService時執行的Method。 啟動Service最基本的Method為onBind,而在本範例中,我們覆寫onStart以及onDestroy來啟動利用Thread實作的Timer以及結束Timer。在Activity中設置了一個按鈕,當按下去後則startService,此時會執行onStart,在此Method中建立並啟動一個自訂的TimerThread,此Thread每一秒會利用Message傳遞訊息給Handler,並用Log印出現在是第幾秒。當使用者在一次按下按鈕代表計時停止,此時會stopService並使用onDestroy,在此Method中會送一個Message訊息至Handler告知現在要停止Timer,此時會設定TimerThread中的stop標籤讓Timer結束掉 Complete codes please refer to : myService.java in reference disc
10
Service To use Service, it is necessary to set Service in AndroidManifest.xml as shown below: <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android=" package="ncu.bnlab.ServiceExample" android:versionCode="1" android:versionName="1.0"> <application <activity android:name=".ServiceExample" <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:name=".myService" android:exported="true"> </service> </application> <uses-sdk android:minSdkVersion="6" /> </manifest> 在Service中,android:name為執行之Service的Class名稱。第二個為exported,若設為true代表其他的應用程式也可以與這個Service作互動,若需要更進階的限制可再利用permission作進一步設定。
11
Service Results of the example is shown below:
當要關閉Sevice時,可以再抓取Service資訊後將其停止或是做其他動作。此範例當使用者再一次按下按鈕代表計時停止,此時會stopService並使用onDestroy,在此Method中會送一個Message訊息至Handler告知現在要停止Timer,此時會設定TimerThread中的stop標籤讓Timer結束掉
12
SearchManager
13
SearchManager SearchManager類別提供系統搜尋的服務,在正常情況下不會直接使用此類別來做應用,可利用Intent的ACTION_SEARCH或 context.getSystemService (Context.SEARCH_SERVICE)來應用搜尋服務。在許多應用程式中都會提供一個搜尋的介面,比較平常的做法是將此搜尋介面放在Menu中。 搜尋可分為兩種,「Local Search」以及「Globle Search」,Local Search搜尋範圍為應用程式定義的範圍,Globle Search則是搜尋整個系統。
14
SearchManager 在本範例中,實作一個簡單的搜尋範例,利用Menu以及一個EditText來實作。當Menu中有個Search的按鈕,當按下時會跳出一個簡易的快速搜尋列,而EditText中的文字則會自動被輸入至快速搜尋列當中,範例程式碼如下: public class SearchExample extends Activity { EditText searchEdit; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // 設定搜尋為Local Search setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL); searchEdit = (EditText) findViewById(R.id.SearchEdit); } public boolean onCreateOptionsMenu(Menu menu) { menu.add(0, 0, 0, "Search"); return true; public boolean onOptionsItemSelected(MenuItem item) { Bundle dataBundle = new Bundle(); String queryData = searchEdit.getText().toString(); startSearch(queryData, false, dataBundle, false); return super.onOptionsItemSelected(item);
15
Description of Functions
SearchManager Method to start search is to use startSearch. It is used as : Parameters are listed in the table below: startSearch (String initialQuery, boolean selectInitialQuery, Bundle appSearchData, boolean globalSearch) Class Name Description of Functions initialQuery 若此字串不為空白,則會將此字串自動加在搜尋列上。 selectInitialQuery 若為true,則initialQuery會變成預設搜尋條件,當再輸入其他字會將原字串覆蓋掉。 appSearchData 應用程式可加入application-specific額外的內容來增加搜尋的條件 globalSearch 若為false,則看程式是否有設定,若也沒有預設設定,則自動使用Global Search方式;若為true,則設定為platform-global search
16
SearchManager Results of the example is shown below:
17
Broadcast Receivers
18
Broadcast Receivers BroadcastReceiver is a necessary tool in many mobile applications. When an application registers itself to BroadcastReceiver, it is allowed to use onReceive to receive message related to the registered service. The registration method is shown below: registerReceiver(BroadcastReceiver receiver, IntentFilter filter)
19
Description of Functions
Broadcast Receivers onReceive會根據程式跟系統註冊的IntentFilter來獲取相關服務訊息,在此簡單介紹一些關於電池與電源相關的filter如下表: Class Name Description of Functions ACTION_BATTERY_CHANGED When detecting the battery status ACTION_BATTERY_LOW When detecting the capacity of the battery is low ACTION_BATTERY_OKAY When battery status turns from low-battery to normal status ACTION_POWER_CONNECTED When the device is connected to an external power supply ACTION_POWER_DISCONNECTED When the device is disconnected to an external power supply
20
Page Menu Example in this section uses Toast to indicate battery status. When it changes, BroadcastReceiver will calculate the remaining capacity of the battery. Codes of the example is shown below: private BroadcastReceiver batteryReceiver = new BroadcastReceiver() { int level; int scale; @Override public void onReceive(Context context, Intent intent) String action = intent.getAction(); // 判斷接收到的事件是否為ACTION_BATTERY_CHANGED if (action.equals(Intent.ACTION_BATTERY_CHANGED)) // 設定電池level level = intent.getIntExtra("level", 0); // 設定電池scale scale = intent.getIntExtra("scale", 100); // 設定Toast停留長短 int duration = Toast.LENGTH_LONG; // 計算剩餘電量百分比 String text = "剩餘電量為:" + ( level * 100 / scale ) + "%"; Toast.makeText(context, text, duration).show(); } }; 在範例中,我們註冊一個BroadcastReceiver,如下: registerReceiver(batteryReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); 當電池狀態發生變化時,即可收到BroadcastReceiver的資訊,當onReceive收到電池變化訊息時,我們利用Intent的getIntExtra方法抓取電池的兩個資料,一為level,另一個為scale。level會抓取當下電量的值,此值從0到EXTRA_SCALE,而scale則是代表電池最大的level。在計算剩餘電量時,將現在level / scale在乘100即為剩餘百分比。
21
Content Providers
22
Content Providers ContentProvider可提供一個介面給所有應用程式來分享資料,而分享資料的基本格式是利用URI來當成傳遞的媒介: 而ContentProvider的scheme為「content://」,而在CONTENT_URI中的各種URI都有ID,所以在向ContentProvider指定取得某個ID的資料,如下: 在此可利用ContentUris中的withAppendedId方法來幫URI加入ID: 或是利用Uri的withAppendedPath方法加入ID <scheme> : //<authority path-abempty> "?"<query> #<fragment> content : //. . . /35 Uri myUri = ContentUris.withAppendedId( Uri contentUri, long id ); withAppendedPath(Uri baseUri, String pathSegment);
23
Content Resolver
24
Content Resolver 在前面章節提到的ContentProvider可將Content分享至不同的應用程式之中,而ContentResolver則是一個標準的方式來取得ContentProvider所提供的資料,也是用來修改資料的方法,但若牽涉到寫入或修改資料的話,則要看目標的ContentProvider是否允許使用者對資料做存取的動作,若無此權限,則ContentResolver方法會失敗。 ContentProvider通常會使用URI的方式來當作分享資料的識別,故在ContentResolver要抓取某一ContentProvider資料時則必須將要抓取的URI當成參數來使用。
25
Content Resolver 在本節範例中,我們利用系統內建Phones.CONTENT_URI來得到電話中的聯絡人資訊並將其列表,範例程式碼如下: public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ContentResolver cr = getContentResolver(); // Query聯絡人資料,並將結果儲存在Cursor中 Cursor c = cr.query(Contacts.Phones.CONTENT_URI, null, null, null, null); phoneInfo_Name = new String[c.getCount()]; phoneInfo_Number = new String[c.getCount()]; // 先看抓取之 cusor 是否有資料 if (c.moveToFirst()) { int nameColumn = c.getColumnIndex(Phones.NAME); int phoneColumn = c.getColumnIndex(Phones.NUMBER); int index = 0; do { phoneInfo_Name[index] = c.getString(nameColumn); phoneInfo_Number[index] = c.getString(phoneColumn); index++; } while (c.moveToNext()); } setListAdapter(new MyListAdapter(this)); 程式一開始建立一個ContentResolver物件,使用方法如下: ContentResolver cr = getContentResolver(); 接著使用ContentResolver中的query方法將所要抓取之URI傳入: // public final Cursor query (Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) Cursor c = cr.query(Contacts.Phones.CONTENT_URI, null, null, null, null);
26
Description of Functions
Content Resolver Query parameters of ContentResolver is listed in the table below: Parameter Description of Functions uri 欲擷取資料之content:// projection 指定要回傳哪些欄位,若值為null代表全部回傳 selection 指定要回傳哪些列,若值為null代表全部回傳 selectionArgs 可在回傳條件中加入「?」,此陣列會依序取代未知的值 sortOrder 設定回傳結果的排序方式
27
Content Resolver Results of the example is shown below:
28
Content Resolver In this example, the following permission should be inserted in AndroidManifest.xml to maintain normal operation: <uses-permission android:name="android.permission.READ_CONTACTS"> </uses-permission>
29
Content Resolver 上面範例是取得ContentProvider的資料,而接著介紹如何透過ContentResolver來新增資料,要達到此動作則需使用ContentValues,此範例新增一筆聯絡人資料至通訊錄中,程式碼如下: ContentResolver cr = getContentResolver(); // 建立ContentValues物件 ContentValues values = new ContentValues(); // 設定People.NAME以及People.STARRED values.put(People.NAME, "NCU-FAX"); values.put(People.STARRED, 0); // 將上述設定的ContentValues物件Insert至People.CONTENT_URI中 Uri uri = cr.insert(People.CONTENT_URI, values); Uri phoneUri = Uri.withAppendedPath(uri, People.Phones.CONTENT_DIRECTORY); values.clear(); // 設定People.Phones.TYPE(電話類型) values.put(People.Phones.TYPE, People.Phones.TYPE_MOBILE); // 設定People.Phones.NUMBER(電話號碼) values.put(People.Phones.NUMBER, " "); cr.insert(phoneUri, values); 要加入新資料首先先宣告一個ContentValues物件,使用其put方法將我們所要的資訊放到values物件中,接下來使用ContentResolver的insert方法將要加入之values加入目標URI中
30
Content Resolver Results of the example is shown below. The left is before inserting, and the right is after inserting :
31
Description of Function
Content Resolver ContentResolver and its data processing is listed below: Class Name Description of Function delete(Uri url, String where, String[] selectionArgs) Delete the selected data insert(Uri url, ContentValues values) Insert the selected data query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) Query the selected data update(Uri uri, ContentValues values, String where, String[] selectionArgs) Update the selected data
32
Q&A
Similar presentations