Chapter 7 Android應用元件 Android應用元件可以幫助我們獲得系統資源訊息(ActivityManager)、提供系統服務(Service)、搜尋系統服務(SearchManager)、監聽Intent訊息(Broadcast Receiver)以及資料共享(ContentProvider和ContentResolver)。

Slides:



Advertisements
Similar presentations
從 Android SDK 3.0 開始增加了 2 個新的類別: Fragment 與 Action Bar 。 Fragment 提供不同佈局畫面的另一種用法,但 設計更有彈性,更能針對螢幕大小變化,採用 最合適的設計,例如對較大螢幕的平板裝置, 它可以在一個活動的畫面同時顯示 2 個 Fragment.
Advertisements

Android ADT + Android SDK Eclipse Eclipse 編輯器 JAVA JAVA 開發工具.
数据存储.
第13章 繪圖與多媒體 13-1 顯示圖檔-行動相簿 13-2 音樂播放-音樂播放器 13-3 影片播放-視訊播放器
實驗五:多媒體播放器選單介面.
Part 2 開發Android應用程式的流程
位置與地圖應用 此投影片為講解Android如何取得定位經緯度和使用Google Map地圖.
第二章 JAVA语言基础.
Android + Web Service 建國科技大學 資管系 饒瑞佶 2017/3 V1.
ArrayAdapter & Spinner
厦门大学数据库实验室 报告人:谢荣东 导师:林子雨 2014年8月30日
Services of the Mobile and Use of Communication Network
實驗四:單位轉換程式.
Chapter 13 Android 實戰演練.
Android + JUnit 單元測試 建國科技大學資管系 饒瑞佶 2012/8/19V4.
實驗十三:顯示目前經緯度位置.
Ch06 再談選單元件 物件導向系統實務.
使用Android控制Arduino 史先强
第10章 App微信分享的实现 倚动实验室.
Android資料庫處理 Android智慧型手機程式設計 程式設計與應用班 建國科技大學 資管系 饒瑞佶 2012/4 V1
第9章 位置服务与地图应用.
第一个Android程序 本讲大纲: 1、创建Android应用程序 2、Android项目结构说明 3、运行Android应用程序
第8章 Android内容提供者(ContentProvider)应用
Chapter 6 Advanced UI Design.
Android智慧型手機程式設計實務應用班
Ch5 Android應用程式的主要組成.
Android介面設計 Android智慧型手機程式設計 建國科技大學 資管系 饒瑞佶 2012/4 V1 2012/8 V2
Android Intent 建國科技大學 資管系 饒瑞佶 2011/1.
Chapter 6 進階UI設計.
第4章 Android生命周期.
ContentProvider與資料共享
第9章 使用意圖啟動活動與內建應用程式 9-1 意圖的基礎 9-2 使用意圖啟動活動
ANDROID PROGRAMMING2.
CH7 佈局、按鈕與文字編輯元件.
Android + Service 建國科技大學 資管系 饒瑞佶.
2018/12/3 面向对象与多线程综合实验-网络编程 教师:段鹏飞.
第10章 儲存偏好設定、檔案與資料庫 10-1 存取偏好設定 10-2 檔案存取 10-3 關聯式資料庫與SQLite
實驗十四:顯示與控制地圖.
第2讲 移动应用开发基础知识(二) 宋婕
建立Android新專案 Android智慧型手機程式設計 程式設計與應用班 建國科技大學 資管系 饒瑞佶 2012/4 V1
第8章 Service解析.
第6章 建立Android使用介面 6-1 介面元件的基礎 6-2 Android的事件處理 6-3 按鈕元件 6-4 文字元件
手機的頁面轉換與資料傳遞.
Android 视频教程简介.
生活智慧王 樹德科技大學 資訊工程系 指導教授 : 陳毓璋 教授 小組成員: 劉上緯 翁維廷 洪文財.
第10章 GPS位置服务与地图编程.
實驗十一:待辦事項程式 (儲存在手機上).
主编:钟元生 赵圣鲁.
Intent.
Android 开发入门.
Android Application Component
網路應用.
Chapter 5 Basic UI Design.
Android視窗介面 建國科技大學 資管系 饒瑞佶 2010/10.
實驗九:延續實驗八, 製作一個完整音樂播放器
Location Based Services - LBS
補間動畫 (Tween Animation) 靜宜大學資管系 楊子青
第二章 Java语法基础.
Android視窗介面 建國科技大學 資管系 饒瑞佶 2010/10.
Review 1~3.
第二章 Java基本语法 讲师:复凡.
RecyclerView and CardView
Android藍芽聊天室 SDK內的範例程式
Android Speech To Text(STT)
用Intent啟動程式中的其他Activity、運用WebView顯示網頁 靜宜大學資管系 楊子青
第2章 Java语言基础.
第9章 BroadcastReceiver的使用
Android进程间通讯.
加速感測器 靜宜大學資管系 楊子青.
Part 8 Broadcast Receiver、Service和App Widget
Presentation transcript:

Chapter 7 Android應用元件 Android應用元件可以幫助我們獲得系統資源訊息(ActivityManager)、提供系統服務(Service)、搜尋系統服務(SearchManager)、監聽Intent訊息(Broadcast Receiver)以及資料共享(ContentProvider和ContentResolver)。

ActivityManager

ActivityManager ActivityManager可管理所有的活動(activities),下表為ActivityManager所提供的巢狀類別。 類別名稱 功能介紹 ActivityManager.MemoryInfo 關於記憶體相關訊息 ActivityManager.ProcessErrorStateInfo 錯誤的程序訊息 ActivityManager.RecentTaskInfo 最近使用的任務訊息 ActivityManager.RunningAppProcessInfo 正在執行的程序訊息 ActivityManager.RunningServiceInfo 正在執行的服務訊息 ActivityManager.RunningTaskInfo 正在執行的任務訊息

ActivityManager 在本節中,介紹抓取剩餘記憶體為範例,程式碼如下: 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,左圖為程式所抓取的資料,右圖為系統內建工具抓取的資料。

ActivityManager 範例結果如下,左圖為範例執行結果,右圖為系統狀態顯示: 左圖為程式所抓取的資料,右圖為系統內建工具抓取的資料。

Service

Service Service是運行在背景的服務,如聽音樂時,可利用Service讓音樂在背景執行,這樣就可以關閉執行音樂的Activity來做其他事情,當要關閉音樂時,可以在抓取Service資訊後將其停止或是其他動作。 Service服務必須對應到AndroidManifest.xml。Service可由Activity來啟動,啟動之後可利用BroadcastReceiver 來取得相關Service訊息。

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); 完整程式碼請參考光碟中 ServiceExample.java

Service 建立Service Class 完整程式碼請參考光碟中 myService.java 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結束掉 完整程式碼請參考光碟中 myService.java

Service 使用Service還必須將Service設定在AndroidManifest.xml中,如下: <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="ncu.bnlab.ServiceExample" android:versionCode="1" android:versionName="1.0"> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".ServiceExample" android:label="@string/app_name"> <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作進一步設定。

Service 範例結果如下: 當要關閉Sevice時,可以再抓取Service資訊後將其停止或是做其他動作。此範例當使用者再一次按下按鈕代表計時停止,此時會stopService並使用onDestroy,在此Method中會送一個Message訊息至Handler告知現在要停止Timer,此時會設定TimerThread中的stop標籤讓Timer結束掉

SearchManager

SearchManager SearchManager類別提供系統搜尋的服務,在正常情況下不會直接使用此類別來做應用,可利用Intent的ACTION_SEARCH或 context.getSystemService (Context.SEARCH_SERVICE)來應用搜尋服務。在許多應用程式中都會提供一個搜尋的介面,比較平常的做法是將此搜尋介面放在Menu中。 搜尋可分為兩種,「Local Search」以及「Globle Search」,Local Search搜尋範圍為應用程式定義的範圍,Globle Search則是搜尋整個系統。

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);

SearchManager 啟動搜尋則是使用startSearch此Method,使用方法如下: 參數如下表所示: startSearch (String initialQuery, boolean selectInitialQuery, Bundle appSearchData, boolean globalSearch) 類別名稱 功能介紹 initialQuery 若此字串不為空白,則會將此字串自動加在搜尋列上。 selectInitialQuery 若為true,則initialQuery會變成預設搜尋條件,當再輸入其他字會將原字串覆蓋掉。 appSearchData 應用程式可加入application-specific額外的內容來增加搜尋的條件 globalSearch 若為false,則看程式是否有設定,若也沒有預設設定,則自動使用Global Search方式;若為true,則設定為platform-global search

SearchManager 範例結果如下:

Broadcast Receivers

Broadcast Receivers BroadcastReceiver在許多手機應用程式上是必須的一個工具,當應用程式註冊一個BroadcastReceiver服務後,可利用onReceive方法來接收關於註冊之服務訊息,註冊方法如下: registerReceiver(BroadcastReceiver receiver, IntentFilter filter)

Broadcast Receivers onReceive會根據程式跟系統註冊的IntentFilter來獲取相關服務訊息,在此簡單介紹一些關於電池與電源相關的filter如下表: 類別名稱 功能介紹 ACTION_BATTERY_CHANGED 電池狀態是否改變 ACTION_BATTERY_LOW 電池是否為低電量狀態 ACTION_BATTERY_OKAY 當電池狀態從低電量變為正常電量時會觸發此狀態 ACTION_POWER_CONNECTED 當裝置接上外部電源時 ACTION_POWER_DISCONNECTED 當裝置外部電源移除時

分頁選單 本節範例利用Toast顯示電量,當電量有改變時,BroadcastReceiver會計算改變後的電量,範例程式碼如下: 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即為剩餘百分比。

Content Providers

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);

Content Resolver

Content Resolver 在前面章節提到的ContentProvider可將Content分享至不同的應用程式之中,而ContentResolver則是一個標準的方式來取得ContentProvider所提供的資料,也是用來修改資料的方法,但若牽涉到寫入或修改資料的話,則要看目標的ContentProvider是否允許使用者對資料做存取的動作,若無此權限,則ContentResolver方法會失敗。 ContentProvider通常會使用URI的方式來當作分享資料的識別,故在ContentResolver要抓取某一ContentProvider資料時則必須將要抓取的URI當成參數來使用。

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);

Content Resolver ContentResolver的query參數如下表: 參數 功能描述 uri projection 指定要回傳哪些欄位,若值為null代表全部回傳 selection 指定要回傳哪些列,若值為null代表全部回傳 selectionArgs 可在回傳條件中加入「?」,此陣列會依序取代未知的值 sortOrder 設定回傳結果的排序方式

Content Resolver 範例結果如下:

Content Resolver 本範例必須要在AndroidManifest.xml中加入下述權限方可正常運作: <uses-permission android:name="android.permission.READ_CONTACTS"> </uses-permission>

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, "03-4226062"); cr.insert(phoneUri, values); 要加入新資料首先先宣告一個ContentValues物件,使用其put方法將我們所要的資訊放到values物件中,接下來使用ContentResolver的insert方法將要加入之values加入目標URI中

Content Resolver 範例結果如下,左圖為未加入前,右圖為加入後:

Content Resolver ContentResolver與資料處理相關方法如下表: 類別名稱 功能介紹 delete(Uri url, String where, String[] selectionArgs) 刪除指定資料 insert(Uri url, ContentValues values) 加入指定資料 query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) 查詢指定資料 update(Uri uri, ContentValues values, String where, String[] selectionArgs) 更新指定資料

Q&A