Presentation is loading. Please wait.

Presentation is loading. Please wait.

Part 7 Intent、Intent Filter和傳送資料

Similar presentations


Presentation on theme: "Part 7 Intent、Intent Filter和傳送資料"— Presentation transcript:

1

2 Part 7 Intent、Intent Filter和傳送資料
單元37專案中的AndroidManifest.xml程式功能描述檔 單元38 Intent粉墨登場 單元39 Tab標籤頁介面 – 使用Intent物件 單元40 Intent Filter讓程式也能幫助別人 單元41讓Intent物件附帶資料 單元42要求被呼叫的Activity回傳資料

3 單元37專案中的AndroidManifest.xml程式功能描述檔

4 程式功能描述檔AndroidManifest.xml src資料夾 用來存放專案中所有的Java程式檔,此資料夾下可以再建立數個不同的套件路徑資料夾,以方便將不同套件的程式檔分開存放。 gen資料夾 儲存由Android程式編譯器從res資料夾下的資源檔所產生的專案資源,其中包含一個資源類別R,此資料夾下的內容我們不能修改。 Android X.X資料夾 程式專案使用的Android版本,我們可以藉由開啟專案的屬性對話盒來進行變更。 assets資料夾 用來存放程式中會用到的其它檔案資源,例如影像檔,和res資料夾不同的是,存放在assets資料夾下的檔案,Android編譯器不會將它們加入gen資料夾下的資源類別R中。

5 程式功能描述檔AndroidManifest.xml bin資料夾 儲存由Android程式編譯器產生的檔案,我們不需要修改其中的內容。
res資料夾 用來存放專案中需要用到的資源,包括字串、介面佈局檔、動畫資源檔、影像檔、…等。這些資源檔會被Android編譯器自動加入gen資料夾下的資源類別R。 AndroidManifest.xml檔案 記錄此程式專案的架構和功能等相關資訊,它是程式用來和Android系統溝通的重要資料,程式開發者必須自行維護它的內容。 default.properties檔案 這也是由Android程式專案產生器自動建立的檔案,我們不能對它進行修改。 proguard.cfg檔案 這個檔案我們也不需對它進行修改。

6 「電腦猜拳遊戲」程式專案中的AndroidManifest.xml檔
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android=" package="tw.android" android:versionCode="1" android:versionName="1.0"> <uses-sdk android:minSdkVersion="11" /> <application <activity android:name=".Main" <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> <uses-sdk android:minSdkVersion="3" /> </manifest>

7 <manifest>標籤的功能
1. Package 指定專案中的程式檔的套件路徑。 2. android:versionCode 記錄此專案的版本號碼。 3. android:versionName 記錄此專案的版本名稱。

8 < uses-sdk >標籤的功能
用來記錄此程式專案使用的Android SDK版本,android:minSdkVersion="11"表示此程式專案必須在Android SDK 3.0以上的環境才能執行(Android SDK 3.0的版本編號就是11)。 8

9 <application>標籤的功能
<manifest>標籤中的<application>標籤是用來記錄程式的相關資訊。 1. android:icon 指定程式執行時所顯示的小圖示。 2. android:label 程式執行時顯示在手機螢幕上方的訊息列中的程式名稱。

10 <activity>標籤的功能
<application>標籤中包含一個<activity>標籤。Activity是Android應用程式的執行單元,以物件導向的觀念來說,就是一個執行的物件。截至目前為止,所有的範例程式都只有一個Activity,其實在一個Android應用程式中可以建立多個Activity,每一個Activity都必須在AndroidManifest.xml檔案中建立一個對應的<activity>標籤描述該Activity的相關資訊。

11 在程式專案中新增第二個Activity 當使用者按下主程式畫面上的按鈕後,就會啟動這個「電腦猜拳遊戲」程式。 11

12 在程式專案中新增第二個Activity Step 1. 每個Activity都需要一個專用的介面佈局檔,在Eclipse左邊的專案檢視視窗中用滑鼠右鍵點選layout資料夾,然後選擇New>File新增一個game_activity.xml檔案,然後把「電腦猜拳遊戲」專案中的介面佈局檔的內容全部複製到此新檔。 Step 2. 在Eclipse左邊的專案瀏覽視窗中點選「專案名稱>src>(套件名稱)」,在套件名稱上按下滑鼠右鍵,在彈出的選單中選擇New>Class。

13 在程式專案中新增第二個Activity Step 3. 在類別對話盒中的Name欄位輸入我們想要的類別名稱,然後按下Superclass欄位右邊的Browse按鈕,在出現的對話盒最上面的欄位中輸入Activity,下方清單中就會顯示Activity類別,用滑鼠快按二下該類別就會自動回到原來的對話盒,並完成填入Superclass欄位。 Step 4. 按下Finish按鈕後,在Eclipse中央的程式碼視窗就會出現程式檔的編輯畫面。 Step 5. 打開此專案的介面佈局檔res/layout/main.xml,在操作介面中加入一個按鈕如下: <Button android:layout_width=“match_parent” android:layout_height=“wrap_content” android:text=“執行「電腦猜拳遊戲」程式” />

14 在程式專案中新增第二個Activity Step 6. 打開此專案的主類別程式碼,新增一個主程式的按鈕的OnClickListener物件,然後在該物件的onClick()方法中加入下列粗體部分的程式碼,最後將此OnClickListener物件設定給主程式的按鈕。 public void onClick(View v) { Intent it = new Intent(); it.setClass(Main.this, Game.class); startActivity(it); } Intent是Android系統中具有重要功能的物件,在下一個單元中我們會對Intent物件再作詳細的介紹,這裡我們先利用它來啟動「電腦猜拳遊戲」這個Activity。

15 在程式專案中新增第二個Activity Step 7. 把原來「電腦猜拳遊戲」專案的res/values/strings.xml檔案中所定義的字串,複製到此專案的同名檔案中。 Step 8. 把原來「電腦猜拳遊戲」專案的res/drawable-hdpi資料夾中的剪刀、石頭、布影像檔複製到此專案的同名資料夾中。 15

16 在程式專案中新增第二個Activity Step 9. 打開此專案的AndroidManifest.xml檔案,加入下列粗體字的部分: <?xml version="1.0" encoding="utf-8"?> <manifest …> <application …> <activity android:name=".Main“ <intent-filter> … </intent-filter> </activity> <activity android:name=".Game“ </activity> </application> </manifest> 16

17 在程式專案中新增第二個Activity 新增的程式碼是告訴Android系統這個專案中新增加一個Activity,android:name=".Game"屬性是指定這個Activity的路徑和名稱,以附點開頭表示和專案的主要Activity放在同一個路徑。如果路徑不相同,就要寫出完整的路徑,例如android:name="tw.android.Game"。android:label屬性是設定Activity執行時要顯示在手機上方訊息列的程式標題,上面的範例是使用定義在字串資源檔中名為gameTitle的字串。 17

18 使用「互動式介面」編輯AndroidManifest.xml 開啟AndroidManifest.xml檔案後在程式編輯視窗下方有一排標籤,由左至右依序為Manifest、Application、Permissions…,它們其實就是對應到AndroidManifest.xml檔案中的標籤架構,我們可以利用這些標籤頁來編輯AndroidManifest.xml檔案的內容。 18

19 單元38 Intent粉墨登場

20 Intent的功能 Intent翻譯成中文的意思是「意圖」,說的白話一些就是「我想要…」,也就是說目前執行中的Activity想請其它的Activity或是Android系統中的其它程式來完成一件工作,並且把執行權交給對方,然後目前的Activity便會進入休息的狀態,等到對方完成工作交回執行權後,才會再回到執行狀態。 我們可以把Intent物件視為是程式和Android系統互動的媒介。當程式需要其它Activity或是程式來完成工作時,便可以建立一個Intent物件,然後在該物件中填入必要的資訊,最後呼叫startActivity()方法將此Intent物件傳給Android系統。Android系統收到Intent物件之後,便會根據其中的資訊啟動適當的Activity或程式來加以處理。

21 Intent的範例 上一個單元我們利用setClass()方法直接指定要啟動的Activity類別(就是Game.class),並填入此Intent物件的擁有者(類別名稱.class),接著就呼叫startActivity()方法將它送出。 Intent it = new Intent(); it.setClass(Main.this, Game.class); startActivity(it);

22 利用Intent物件記錄要處理的資訊以及處理方法
Intent物件的另一種使用方式是只記錄要處理的資訊以及處理方法,例如檢視、傳送、加入、或刪除,然後將它送出。Android系統收到這個Intent物件之後,會根據其中的資料型態以及處理方式,從系統的記錄清單中挑選一個合適的程式來處理。這種型態的Intent物件需要使用一個Uri物件,它是用來儲存要處理的資料。

23 Intent物件可以完成的工作類型 Intent物件可以完成許多類型的工作,像是開啟網頁、打電話、傳送簡訊、傳送 、播放影片、播放音樂、開啟圖片,拍攝照片、安裝程式、移除程式、…等。

24 利用Intent請求其它程式幫忙 開啟網頁:
Uri uri = Uri.parse(" Intent it = new Intent(Intent.ACTION_VIEW, uri); startActivity(it); 播放MP3: Intent it = new Intent(Intent.ACTION_VIEW); File file = new File("/sdcard/song.mp3"); it.setDataAndType(Uri.fromFile(file), "audio/*"); 檢視圖片: File file = new File("/sdcard/image.png"); it.setDataAndType(Uri.fromFile(file), "image/*");

25 利用Intent請求其它程式幫忙

26 使用模擬器的SD卡 要執行此範例程式需要將MP3檔案和影像檔儲存在模擬器的SD卡中。把檔案上傳到模擬器的SD卡需要使用Eclipse的新功能,另外如果想在SD卡中建立或刪除資料夾則需要進入模擬器的Linux作業系統的命令列模式。 Step 1. 建立一個含有SD卡的模擬器。請點選Eclipse選單上的「Window>Android SDK and AVD Manager」,在對話盒中點選左邊的Virtual Devices再按下右邊的New按鈕,在Name欄位中幫這個模擬器取一個名稱,在Target欄位中選擇一個Android的版本,然後在下方的欄位中可以指定SD卡的容量,例如50,最後按下Create AVD按鈕。

27 使用模擬器的SD卡

28 使用模擬器的SD卡 Step 2. 啟動步驟1建立的模擬器,然後按下模擬器畫面上的Apps按鈕,再從Apps清單中選擇Settings,然後點選Storage。 Step 3. 在螢幕上會顯示SD卡的總容量和可用容量,如果有問題,可以選擇Unmount SD card,然後點選Format SD card。完成後再點選Mount SD card。

29 使用模擬器的SD卡 Step 4. 回到Eclipse程式,找到工具列最右邊有一個名稱叫做Open Perspective的按鈕,點選它然後選擇其中的DDMS選項,Eclipse的操作畫面會隨之改變,在左邊的視窗中會顯示目前執行中的模擬器的名稱,請點選含有SD卡的模擬器。

30 使用模擬器的SD卡 Step 5. 在右邊的視窗中點選File Explorer,然後在下方顯示的資料夾結構中打開mnt/sdcard,並點選sdcard資料夾。 Step 6. 在視窗右上方有一個名稱叫做Push a file onto the device按鈕,點選它後會出現檔案瀏覽對話盒,選擇要上傳到手機的檔案後,按下右下方的「開啟」按鈕,就會將所選擇的檔案上傳至模擬器的SD卡。

31 使用模擬器的SD卡 Step 7. 完成上傳檔案後再利用Eclipse上方工具列最右邊的Java按鈕回到原來Eclipse的畫面。

32 新增或刪除SD卡中的資料夾 以上的步驟只能上傳檔案到模擬器的SD卡,或是從SD卡中刪除檔案,如果是要新增或是刪除資料夾,就必須進入模擬器的Linux作業系統的命令列模式 Step 1. 從Windows的「開始>所有程式>附屬應用程式」中執行「命令提示字元」程式。 Step 2. 將「命令提示字元」程式的執行目錄切換到Eclipse程式資料夾下的android-sdk/platform-tools資料夾(舊版Android SDK為android-sdk-windows/tools資料夾)。

33 新增或刪除SD卡中的資料夾 Step 3. 執行指令「adb -s emulator-5554 shell」。其中emulator-5554是在Eclipse的DDMS操作畫面中顯示的模擬器名稱。

34 新增或刪除SD卡中的資料夾 Step 4. 完成之後會顯示一個#號提示字元,表示我們已經進入模擬器的Linux作業系統。接下來就可以使用Linux的操作指令,像是ls、cd、mkdir、rmdir等進行資料夾的相關操作,例如指令「cd sdcard」就可以進入模擬器的SD卡磁碟中。等全部完成後再輸入exit指令離開Linux命令列模式。 依照以上介紹的方法將程式執行時需要的MP3檔和影像檔上傳到模擬器的SD卡,然後就可以執行範例程式。

35 單元39 Tab標籤頁介面 – 使用Intent物件

36 利用Intent物件建立Tab標籤頁介面
這個方法其實是基於一個很簡單的概念,就是每一個Tab標籤頁都對應到一個獨立的Activity類別,因此不同標籤頁的介面佈局檔和程式碼都是各自獨立,如此一來可以減少介面佈局檔和程式碼的複雜度,使它們易於閱讀和維護。這個新的方法還是必須用到TabHost、TabWidget、和FrameLayout這三個元件。

37 利用Intent物件建立Tab標籤頁介面
範例:把之前完成的DatePicker和TimePicker程式以及ProgressBar程式結合起來,然後放在不同的Tab標籤頁。

38 利用Intent物件建立Tab標籤頁介面
Step 1. 建立一個新的Android應用程式專案,然後編輯res/layout資料夾下的介面佈局檔(參考光碟範例程式),請注意<TabHost>、<TabWidget>、和<FrameLayout>這三個元件的id名稱一定要完全和範例相同,否則程式執行時會發生錯誤。另外我們在<FrameLayout>元件中設定android:paddingTop="70dp"以免標籤頁中的介面元件和標籤的標題重疊。 38

39 利用Intent物件建立Tab標籤頁介面
Step 2. 在res/layout資料夾下新增一個Tab標籤頁的介面佈局檔date_time_picker.xml,然後把之前DatePicker和TimePicker程式專案中的介面佈局檔的內容複製到這個新的介面佈局檔中。如果介面佈局檔中有使用到字串資源,也要在新的專案中建立這些字串資源。 Step 3. 新增另一個介面佈局檔prog_bar_demo.xml,然後把之前ProgressBar程式專案中的介面佈局檔的內容複製到這個新的介面佈局檔中。如果介面佈局檔中有使用到字串資源,也要在新的專案中建立這些字串資源。

40 利用Intent物件建立Tab標籤頁介面
Step 4. 在src/(套件路徑名稱)資料夾中新增二個Activity類別。這二個類別的程式碼分別複製前面的DatePicker和TimePicker程式專案以及ProgressBar程式專案中的程式碼。但是注意setContentView()方法中載入的介面佈局檔名稱必須改成步驟二和步驟三的介面佈局檔名稱。 40

41 利用Intent物件建立Tab標籤頁介面
Step 5. 將主類別所繼承的基礎類別從Activity改成TabActivity如下 package … import … public class 主類別名稱 extends TabActivity { …

42 利用Intent物件建立Tab標籤頁介面
Step 6. 在主類別程式檔中加入設定Tab標籤頁的程式碼: TabHost tabHost = getTabHost(); Intent it = new Intent(); it.setClass(Main.this, DateTimePicker.class); TabSpec spec=tabHost.newTabSpec("tab1"); spec.setContent(it); spec.setIndicator("日期和時間", getResources().getDrawable( android.R.drawable.ic_lock_idle_alarm)); tabHost.addTab(spec); it = new Intent(); it.setClass(Main.this, ProgBarDemo.class); spec=tabHost.newTabSpec("tab2"); spec.setIndicator("ProgressBar Demo", getResources().getDrawable(android.R.drawable.ic_dialog_alert)); spec.setContent(it); tabHost.addTab(spec); tabHost.setCurrentTab(0);

43 利用Intent物件建立Tab標籤頁介面
i. 建立TabHost物件是藉由呼叫getTabHost()方法而不是findViewById()方法 ii. 不需要呼叫TabHost物件的setup()方法 iii. 呼叫TabSpec物件的setContent()方法時,是傳入一個設定好Activity類別的Intent物件

44 利用Intent物件建立Tab標籤頁介面
Step 7. 在專案的AndroidManifest.xml檔案中加入步驟4所建立的Activity的資料。 原來在Tab page的標題可以加上小圖示,可是在Android 4中執行時小圖示會隱藏只顯示標題文字。

45 利用Intent物件建立Tab標籤頁介面
Step 8. 如果想要改變Tab page標題的字體大小,可以利用以下程式碼: TabWidget tabWidget = (TabWidget)tabHost.findViewById(android.R.id.tabs); View tabView = tabWidget.getChildTabViewAt(0); // 0表示第1個Tabe page TextView tab = (TextView)tabView.findViewById(android.R.id.title); tab.setTextSize(20); 如果要設定第2個Tabe page標題的字體大小,就把0改成1依此類推。 45

46 單元40 Intent Filter讓程式也能幫助別人

47 Intent的二種型式 Intent物件對於要執行的工作有二種描述方式。第一種是直接指名道姓,指定要執行的Activity,這種方式稱為顯式的Intent(Explicit Intent)。第二種方式是在Intent物件中記錄資料和對資料的操作,這種方式稱為隱式的Intent(Implicit Intent)。當Android系統收到這種Intent物件的時候,會搜尋系統中所有的程式,找出可以完成這項工作的程式。

48 Intent的二種型式 對於隱式的Intent如果沒有找到任何可以執行的程式,那麼Android系統就會顯示如下的訊息,然後終止原來發出這個Intent物件的程式。如果剛好找到一個可以完成這項工作的程式,Android系統就會直接啟動該程式,如果找到多個程式都可以執行這項工作,就會顯示一個選單視窗,請使用者挑選要啟動的程式。當Android系統要幫隱式的Intent找到合適的程式時,必須使用Intent Filter機制。

49 AndroidManifest.xml檔案中的Intent Filter
<?xml version="1.0" encoding="utf-8"?> <manifest … …> <application …> <activity android:name=".Main" <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>

50 AndroidManifest.xml檔案中的Intent Filter
請注意以上程式碼中標示為粗體字的部分。<intent-filter>標籤是包含在<activity>…</activity>的標籤中,它是告訴Android系統這個Activity的功能。這個範例中使用<action … />和<category …/>這二個標籤,這一組標籤的設定值是告訴Android系統,這個Activity是程式專案執行的入口,也就是啟動程式專案時,第一個執行的Activity。

51 AndroidManifest.xml檔案中的Intent Filter
如果程式專案中新增了其它的Activity,每一個新的Activity都要在程式專案的AndroidManifest.xml檔案中描述它的相關資料,我們可以為Activity加上<intent-filter>標籤,然後在裡頭使用下列三種標籤:<action …/>、<data …/>、<category …/>描述它的功能: 1. <action …/>標籤 描述這個Activity可以執行的操作項目,例如VIEW、EDIT、DIAL、SEND、...等。

52 AndroidManifest.xml檔案中的Intent Filter
2. <data …/>標籤 描述這個Activity可以處理的資料或是資料型態。比較常見的是指定資料型態,例如我們可以利用屬性android:mimeType指定要處理影像或是影片資料:image/png、image/jpg、image/*、video/*、…等,其中*表示所有格式都可以。或是利用屬性android:scheme指定資料類型,例如http、tel、file…等。

53 AndroidManifest.xml檔案中的Intent Filter
3. <category …/>標籤 指定這個Activity所屬的類別,如果是程式專案啟動時要第一個執行的Activity,就必須設定為LAUNCHER類別如下 <category android:name=“android.intent.category.LAUNCHER” /> 如果是其它的Activity,通常都設定為DEFAULT類別 <category android:name="android.intent.category.DEFAULT" />

54 Intent Filter的範例 <activity android:name=".MyImageAct"
<intent-filter> <action android:name="android.intent.action.VIEW" /> <action android:name="android.intent.action.EDIT" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="image/*" /> </intent-filter> <data android:scheme="http" /> <action android:name="android.intent.action.DIAL" /> <data android:scheme="tel" /> </activity>

55 單元41 讓Intent物件附帶資料

56 Intent附帶資料的方法 Intent物件可以用來啟動其它的Activity,或是呼叫其它程式來完成特定的工作。在某些情況下,呼叫的程式可能需要將一些資料項目傳給對方,這時候可以把這些資料包裝在一個Bundle物件中,然後把這個Bundle物件放到Intent物件裡面。這些資料就會隨著Intent物件傳給對方。對方收到Intent物件之後再取出其中的Bundle物件,然後從Bundle物件中取出資料。

57 傳送資料的Activity需要完成的工作
Step 1. 建立一個Intent物件,然後呼叫setClass()方法設定擁有者和要啟動的Activity,通常Intent物件的擁有者就是建立Intent物件的Activity。 Intent it = new Intent(); it.setClass(類別名稱.this, 要啟動的Activity名稱.class); Step 2. 建立一個Bundle物件,然後呼叫Bundle物件的putXXX()方法把資料和資料名稱放到Bundle物件中。每一種資料型態都有對應的put方法可以使用,請參考書上表41-1。 我們必須為每一項加入Bundle物件的資料取一個名稱,對方程式再利用這個名稱從Bundle物件中取出資料。

58 傳送資料的Activity需要完成的工作
Step 3. 利用Intent物件的putExtras()方法把Bundle物件傳給Intent物件,Bundle物件中的資料就會儲存在Intent物件中。 it.putExtras(bundle); 步驟二和三也可以用另一種方式來完成,就是不使用Bundle物件,直接利用Intent物件的putExtra()方法把資料逐一存入Intent物件,請參考以下範例,這二種方法的效果完全相同。 int iVal = 33; double dVal = 200.5; it.putExtra("DATA_INT", iVal); it.putExtra("DATA_DOUBLE", dVal);

59 傳送資料的Activity需要完成的工作
Step 4. 呼叫startActivity()方法送出Intent物件。 59

60 從Intent物件中取出資料 Android系統會根據Intent中的描述啟動適當的Activity或是程式,被啟動的Activity中的onCreate()方法首先會被執行,我們就在onCreate()方法中利用下列步驟取出附帶在Intent物件中的資料。 Step 1. 呼叫getIntent()方法取得傳送過來的Intent物件。 Intent it = getIntent();

61 從Intent物件中取出資料 Step 2. 從Intent物件中取出資料並包裝成Bundle物件。 Bundle bundle = it.getExtras(); Step 3. 根據資料名稱取出Bundle物件中的資料: int iData = bundle.getInt(“DATA_INT”); double dData = bundle.getDouble("DATA_DOUBLE"); 步驟二和三也可以用另一種方式來完成,就是不使用Bundle物件,直接利用Intent物件的getXXXExtra()方法把資料逐一取出,使用getXXXExtra()方法時第二個參數必須設定一個內定值,如果指定的資料名稱不存在時會使用該內定值: int iData = it.getIntExtra("DATA_INT", 0); double dData = it.getDoubleExtra ("DATA_DOUBLE", 0);

62 修改「電腦猜拳遊戲」範例程式 我們希望加上遊戲局數的統計資料,看看使用者總共玩了幾局,其中贏了幾局,而電腦贏了幾局,還有幾局是平手。有關局數統計的資料是交由另一個Activity來顯示。我們在原來的遊戲程式中新增一個「顯示局數統計資料」的按鈕,當此按鈕被按下時,遊戲主程式會將局數統計資料,藉由Intent物件傳送給負責顯示的Activity。使用者看完局數統計資料後,再按下「回到遊戲」按鈕重新回到遊戲程式。

63 修改「電腦猜拳遊戲」範例程式

64 修改「電腦猜拳遊戲」範例程式 步驟一:使用Windows檔案總管複製之前的「電腦猜拳遊戲」專案資料夾,複製之後可以變更複製資料夾的名稱,然後開啟Eclipse,使用主選單File > Import載入複製的專案資料夾。 步驟二:在原來的遊戲介面佈局檔中新增一個「顯示局數統計資料」的按鈕。 步驟三:在原來的遊戲程式中新增局數統計相關變數,並隨著遊戲的進行持續更新其中的值,詳細程式碼請參考範例程式專案。

65 修改「電腦猜拳遊戲」範例程式 步驟四:建立「顯示局數統計資料」按鈕的onClickListener物件並完成內部的程式碼,然後把它設定給「顯示局數統計資料」按鈕,詳細程式碼請參考範例程式專案。 步驟五:在專案的res/layout資料夾下新增一個介面佈局檔,這個介面佈局檔是用來顯示局數統計資料,我們將它取名為game_result.xml ,詳細程式碼請參考範例程式專案。

66 修改「電腦猜拳遊戲」範例程式 步驟六:建立一個新的Activity負責顯示局數統計資料,我們可以將它取名為GameResult。當使用者按下「回到遊戲」按鈕時,會呼叫Activity物件的finish()方法結束這個Activity。 步驟七:在專案的AndroidManifest.xml檔案中新增此Activity的資訊如下: <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android=" …> <application …> <activity … </activity> <activity android:name=".GameResult"/> </application> </manifest>

67 Intent Filter的範例 以上程式碼告訴Android系統在此程式專案檔中有一個Activity名稱叫做MyImageAct,它的內部包含三組<intent-filter>標籤,這是告訴Android系統它可以對三種不同資料類型的Intent物件提供服務,而服務的內容由<intent-filter>標籤內的描述來決定。以第一組<intent-filter>標籤為例: 1. <intent-filter>標籤內的第一行和第二行是說這個Activity可以用來檢視和編輯某種型態的資料。 2. <intent-filter>標籤內的第三行是說這個Activity是屬於DEFAULT類別,也就是可以為一般的Intent物件提供服務。 3. <intent-filter>標籤內的第四行是說這個Activity處理的資料型態是影像,而且可以接受所有影像格式。 後面的二組<intent-filter>標籤和以上的說明類似,只是在<data>的描述中換成使用android:scheme屬性指定資料的類型,例如tel、http、ftp、file、mailto等。

68 Android系統比對Intent和Intent Filter的規則
當Android系統收到一個Intent物件之後,它會把全部有設定<intent-filter>標籤的Activity依照下列規則進行比對。 1. 比對action項目 Activity在<intent-filter>標籤中設定的action項目必須含有Intent物件中指定要執行的action項目。 2. 比對category項目 Activity在<intent-filter>標籤中設定的category必須和Intent物件指定的category相同。如果Intent物件中沒有指定category,則視為DEFAULT。 3. 比對data項目 data項目的比對方式比較複雜。Android系統會從Intent所附帶的資料中嘗試抽取出type、scheme、authority、path四個部分(有些部分可能是空的),然後再和Activity的<intent-filter>標籤中的<data>設定進行比對看有沒有相符。

69 Android系統比對Intent和Intent Filter的規則
合以上三項條件的Activity都會被挑選出來,列入接受此Intent物件的清單。

70 程式接收到Intent物件的工作 當Android系統決定接收Intent物件的Activity之後,該Activity就會被啟動,然後執行它的onCreate()方法。我們在onCreate()方法中完成以下工作: Step 1. 呼叫getIntent()方法取得Android系統傳入的Intent物件 Intent it = getIntent(); Step 2. 利用Intent物件的方法取得data、action、scheme、category…等資料,並根據資料類型和指定的操作方式處理資料,參考範例程式碼。

71 建立範例程式 把前一個單元的程式專案略作修改,原來的程式是示範如何使用Intent物件啟動網頁瀏覽器、MP3播放器和影像檢視程式,這個單元我們要在該專案中新增一個具有Intent Filter功能的Activity,它可以接收瀏覽網頁、檢視和編輯影像等工作的Intent物件。

72 建立範例程式 Step 1. 使用Windows檔案總管複製前一個單元的程式專案資料夾,複製之後可以變更複製資料夾的名稱。
Step 2. 開啟Eclipse,使用主選單File > Import載入複製的專案資料夾。

73 建立範例程式 Step 3. 在這個程式專案中新增一個繼承Activity類別的新類別,我們可以將它取名為MyImageAct,另外也要為這個MyImageAct類別建立一個介面佈局檔,它的介面很簡單,只有一個TextView元件如下: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center_horizontal“ > <TextView android:layout_width="300dp" android:layout_height="wrap_content" android:text="“ /> </LinearLayout>

74 建立範例程式 Step 4. 這個新增的MyImageAct類別將被設定對image型態的資料提供VIEW和EDIT以及對網址資料執行VIEW,只是在實際程式碼中我們不會真的實作這些功能,只會將收到的資料和所指定的操作顯示在螢幕上。我們把取得Intent物件和附帶資料的程式碼,以及執行資料處理的程式碼全部寫在showResult()方法中,然後在onCreate()方法內呼叫showResult()方法,請參考範例程式專案中的程式碼。 74

75 建立範例程式 Step 5. 在程式專案的AndroidManifest.xml檔案中加上MyImageAct的描述,包括它的Intent Filter,請參考範例程式專案。 Step 6. 修改主程式的介面佈局檔和程式碼,請參考範例程式專案。

76 範例程式

77 單元42 要求被呼叫的Activity回傳資料

78 Activity回傳資料的方法 回傳資料的方法仍然是利用Intent物件,只是運作的機制有些不同。首先是原來的Activity必須改用startActivityForResult()方法替代原來的startActivity()方法。startActivityForResult()方法中同樣是利用一個Intent物件來傳遞資料,可是它還另外多了一個請求代碼。這個請求代碼是用來確認回傳資料的來源。此外在原來的Activity中必須新增一個onActivityResult()方法,這個方法是當被呼叫的Activity結束後,Android系統會將它回傳的Intent物件和結果代碼,以及前面的請求代碼一起傳入onActivityResult()方法。 被呼叫的Activity則必須將執行結果放入一個Bundle物件中,再把這個Bundle物件放入一個Intent物件,最後呼叫setResult()方法傳回這個Intent物件,另外還必須傳回一個結果代碼。

79 「電腦猜拳遊戲」範例程式 這個程式專案是以單元三十七的範例為基礎,我們將把「電腦猜拳遊戲」改成具有局數統計的功能(和前一個單元的程式相同),並且加上「完成遊戲」和「取消」二個按鈕。當使用者玩了幾局之後,可以按下「完成遊戲」按鈕回到主程式畫面,同時送回局數統計資料。主程式收到這些回傳的資料後會將它們顯示出來。

80 「電腦猜拳遊戲」範例程式

81 「電腦猜拳遊戲」範例程式 先利用Windows檔案總管複製一份單元三十七的程式專案,複製後讀者可以更改專案資料夾名稱,再利用Eclipse的File>Import功能將該複製的程式專案載入Eclipse。 步驟一: 在主程式Activity的介面佈局檔中新增一個TextView介面元件用來顯示遊戲局數統計資料如下: <?xml version="1.0" encoding="utf-8"?> <LinearLayout … > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="“ /> </LinearLayout>

82 「電腦猜拳遊戲」範例程式 步驟二:在主程式Activity的程式碼中新增一個onActivityResult()方法,在該方法中依序檢查傳回的請求代碼和結果代碼(我們將請求代碼定義為私有常數LAUNCH_GAME),如果傳回的請求代碼和原來送出的請求代碼不同,表示資料的來源有問題,因此程式會放棄執行,否則繼續檢查結果代碼。如果遊戲Activity傳回的結果代碼是RESULT_OK,則從data引數中(data引數就是遊戲Activity傳回的Intent物件)取出資料然後將它們顯示出來。如果遊戲Activity傳回的結果代碼是RESULT_CANCELED,表示使用者是按下「取消」按鈕,因此顯示「使用者取消遊戲」的訊息,另外記得使用startActivityForResult()方法替代原來的startActivity()。實作的程式碼請參考範例程式專案。

83 「電腦猜拳遊戲」範例程式 步驟三:在「電腦猜拳遊戲」的Activity(類別名稱為Game)的介面佈局檔中新增二個按鈕,一個是「完成遊戲」按鈕,另一個則是「取消」按鈕。 步驟四:在「電腦猜拳遊戲」的Activity中增加局數統計相關變數,並在遊戲進行的過程中累計這些變數的值,可以參考單元二十五的程式碼。 步驟五:在「電腦猜拳遊戲」Activity的程式碼中分別完成以上二個按鈕的OnClickListener物件,詳細程式碼請參考範例程式專案。


Download ppt "Part 7 Intent、Intent Filter和傳送資料"

Similar presentations


Ads by Google