jollen 發表於 December 29, 2008 7:58 PM
Android 應用程式的模式(application model),可由以下幾個觀念講起。在真正進入 Android 程式設計前,必須先了解以下幾個名詞觀念。 1. Android package(.apk) Android 應用程式套件,包含應用程式本身,以及相關的資源檔案。將 apk 套件下載到 Android 手機後,即可安裝至手機上。Android Development Kit 可自動將 apk 套件下載至模擬器或實體手機。 2. task Task 就是「應用程式」本身,也就是 Android 手機上的圖示,使用者可點擊圖示啟動 task。從開發者的角度來看,task就是一個或多個 activities。 3. process Process 在作業系統的定義上,指的是「執行中的程式」,在 Android 的應用程式模式中,代表的是低階的執行程式,也就是系統層(kernel)的部份。一個 apk 套件裡的所有程式,都是在一個 process 裡執行。 4. 什麼是 Activity(android.app.Activity)...
jollen 發表於 December 29, 2008 8:04 PM
上一則文章介紹了 Activity 與 View 的觀念,若能再理解 Activity 與 View 的關係,就不難了解 Android 應用程式的整個模式了。請看以下的範例程式: package com.moko.hello; import android.app.Activity; import android.os.Bundle; import android.widget.TextView; public class HelloMoko extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) {...
jollen 發表於 December 29, 2008 8:13 PM
初步了解如何撰寫第一個 Android 應用程式後,接著就可以實際來建立我們的第一個 Android 專案了。Android Development Kit(ADT)使用 Eclipse 整合式開發環境,根據 Android SDK 裡的文件說明,先安裝 Eclipse 以及 ADT,然後建立一個新專案(File -> New -> Project),並選擇「Android Project」,如圖1。 圖1:建立 Android Project 接著輸入專案屬性: 1. Package name:Java 套件名稱,在這裡我們將應用程式的套件命名為 com.moko.hello。 2. Activity name:輸入應用程式的 Activity 類別名稱,建立一個繼承 Activity 的新類別。 3. Application name:輸入應用程式名稱,即應用程式標題。 圖2:輸入專案屬性...
jollen 發表於 January 4, 2009 10:22 PM
繼上一篇文章介紹了 View 的觀念後,接下來就要了解一下如何「安排」Android 應用程式的 layout。 Android 應用程式的 layout(UI 佈局)除了直接撰寫程式碼的方式外,也能使用 XML 檔案來做描述(XML-based Layout)。在 Android Development Kit 的「Package Explorer」視窗,點選「res -> layout」選擇 main.xml,可以看到 “Hello Moko” 應用程式的 XML layout 檔案,如圖1。 圖1:"Hello Moko" 的 XML layout 檔 以下這段 XML 用來描述「TextView」物件的 layout: <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello"...
jollen 發表於 January 4, 2009 10:49 PM
上一篇文章介紹了 XML-based layout 後,發現這是一個很方便,而且有用的 UI 安排方式。以圖1為例,我們現在想要做出一個應用程式,讓文字的超鍊結(hyperlink)可以被使用者點選,並自動呼叫瀏覽器連到該網站,這樣的應用程式該如何撰寫呢?請依以下步驟修改程式碼。 圖1:如何設計一個可點擊 URL link 的應用程式? View 的 XML 屬性 每一個 View 都有許多屬性,我們可以利用 XML 來描述每一個 View 的屬性,進而達到控制物件的效果。以 TextView 為例,有一個「android:autoLink」屬性可以控制「是否要自動將網址轉換為可點擊的 URL 文字」。 要怎麼知道每一個 View 都哪些屬性呢?這個時候就要祭出 Android SDK 的 documentation 了。以 TextView 為例,透過以下的說明,可以了解 TextView 有哪些屬性,以及該屬性的用途: http://code.google.com/intl/zh-TW/android/reference/android/widget/TextView.html#attr_android:autoLink 原來,只需要透過「autoLink」屬性,並將此屬性設定為「web」即可做出我們想要的功能。 修改...
jollen 發表於 January 5, 2009 11:08 PM
如果要繼續體驗 View 的樂趣,那麼「WebView」這個 View 無疑是最佳人選。android.webkit.WebView 是使用「WebKit」技術的 View,主要的用途是「顯示網頁」。使用 WebView,我們可以在 Android 應用程式裡顯示自已的 HTML 文件,或是線上的網頁。 接下來請依照以下步驟,建立我們的第二個 Android 應用程式「Hello Web」。 建立新專案: HelloWeb 建立一個新的 Android 專案,如圖1。 圖1: 建立 Hello Web 專案 並且撰寫 HelloWeb.java 程式如下: package com.moko.web; import android.app.Activity; import android.os.Bundle; import android.webkit.WebView; import com.moko.web.R; public...
jollen 發表於 January 8, 2009 4:51 PM
android.widget.TableLayout 是一個「排版」的類別,假設現在我們想要做出如圖1的文字排版效果,那麼使用 TableLayout 就是標準的做法。傳統寫程式排版的做法不是非常的方便,所以我們將採用 XML layout 方式來實作。 圖1: 文字並排顯示 建立新專案: HelloLayout 建立新的專案「HelloLayout」,並撰寫程式碼如下: package com.moko.layout; import com.moko.layout.R; import android.app.Activity; import android.os.Bundle; public class HelloLayout extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState)...
jollen 發表於 January 12, 2009 3:15 PM
到目前為止,我們都著重在 Activity 以及 UI 的介紹,在 Android 應用程式裡,有一種沒有 UI 的類別(android.app.Service),稱之為 Service。簡單來說,Service 是一個 background process(背景程序),透過背景程序,我們可以實作一些不需要 UI 的功能,例如:在背景撥放音樂。 以下是利用 Eclipse 環境自動產生的類別 'MokoService': import android.app.Service; import android.content.Intent; import android.os.IBinder; public class MokoService extends Service { @Override public IBinder onBind(Intent intent) { // TODO Auto-generated...
jollen 發表於 January 12, 2009 4:02 PM
上一個課程裡,我們實作了一個 Service 的類別稱為 MokoService,現在我們想要在 Activity 裡載入並啟動 MokoService 類別,讓它可以在背景執行,請依以下步驟完成這個任務。。 修改 AndroidManifest.xml 在 Package Explorer 視窗裡找到目前 Android 專案的資訊描述檔,檔名是 AndroidManifest.xml。這是一個用來描述 Android 應用程式「整體資訊」的檔案,每個 Android 應用程式專案都會有一個。在這裡修改 Androidmanifest.xml 的目的是為了「在我們的 Android 應用程式裡加入一個 Service 類別」,這樣才有辦法啟動 Service。修改後的內容如下,紅色的部份是新增的描述:。 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.moko.hello" android:versionCode="1" android:versionName="1.0.0"> <application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="true">...
jollen 發表於 January 19, 2009 10:45 AM
Activity 是一個有 UI 的類別,Service 則是一個沒有 UI 的類別。要知道 Activity 是否啟動,只要看看手機是否出現畫面即可;要知道 Service 是否有啟動,最容易的方式就是透過「除錯」的方式。以下我們實際以一個完整專案方式來對 Android 應用程式做除錯。 建立 MokoService 類別 點擊 Eclipse 的 File -> New -> Class 項目,利用 Eclipse 的自動新增功能,在先前的 HelloMoko 專案裡建立 MokoService 類別,如圖1。欄位「Superclass」應填入 android.app.Service。 圖1: 建立 MokoService 類別 修改 MokoService 實作 在新增的...
jollen 發表於 January 19, 2009 10:39 PM
AndroidManifest.xml 是一個用來描述 Android 應用程式「整體資訊」的設定檔。簡單來說,這是一個「自我介紹」檔,我們可以向 Android 系統「介紹」我們的 Android 應用程式,以便讓 Android 系統完整地了解我們的應用程式資訊。 在 [教學, #9] 中,我們提及:「在這裡修改 AndroidManifest.xml 的目的是為了『在我們的 Android 應用程式裡加入一個 Service 類別』,這樣才有辦法啟動 Service...」這個工作的目的是為了向 Android 系統做二項自我介紹。說明如下。 1. 應用程式「實作了一個 MokoService 類別」 <application android:icon="@drawable/icon" android:label="@string/app_name"> ... <service android:name=".MokoService"> ... </service> ... </application> 在 application 標籤裡加入...
jollen 發表於 April 12, 2009 11:46 AM
「Android Day Package -- Android 應用程式新手入門」整理了這陣子我在研討會的演講材料,包含: 簡報一份 Android 入門教學文件共11集 範例程式4例 因為研討會是一天的演講活動,因此這些內容很適合新手做為「學習 Android 應用程式」的入門教材,大約只需要一天的時間,就能初步了解 Android 的開發工具使用,並了解 Android 的應用程式模式,故取名為「Android Day Package」,期望能提供一個「Android 新手一天入門」的教學套件。請不吝指教。 簡報的部份是受零組件雜誌邀請,進行一天的 Android 演講活動,所特別製作的簡報;範例則是參考 Android SDK 所撰寫的實例,範例是配搭簡報進行實例講解所使用的程式碼。[下載 Android Day Package] 後,可搭配以下共11份教學文件學習;以下的教學文件是為製作簡報時的筆記,特別整理成一份教學文件與大家分享。 課程主題 Android Day Package 提供以下的課程主題。 1. 開放手機平台發展現況 (1hr) ‧開放手機平台陣營 ‧授權模式比較...
jollen 發表於 April 19, 2009 2:30 PM
LinuxDevices.com 報導了一則很酷的消息 [Android-based PMP to ship in October]。 一家名為 [GiiNii] 的公司,將在 10 月份開始銷售使用 Android 平臺的 PMP(portable media player);該公司在明年的 1 月份也會銷售 Android 平臺的 DPF(digital picture frame)。 (圖片來源:GiiNii) 這台名為 Movit Mini 的 PMP 實際上就是一個「MID」概念的產品,但 GiiNii 並不將 Movit Mini 稱為 MID,而是將它定位為 PMP。Movit Mini...
jollen 發表於 May 6, 2009 11:20 PM
上週六(5/2)舉辦「Android Day」訓練活動,上午的活動是「Android 的機會」議程,下午舉辦了一場免費的 Android 訓練課程。Android Day 訓練活動的目的除了希望可以認識朋友,並面對面與大家交換不同的想法外,也希望可以幫助對 Android 應用程式有興趣的朋友,能一天就入門 Android 應用程式設計。對於想初步了解 Android 應用程式設計方法的朋友相當有幫助;透過 Android Day 訓練課程希望能幫助大家節省一開始的自學時間。 上午的議程,由小弟我、高煥堂老師與 David(gOS 執行長)以自由論壇形式,與大家討論 Android 產品端與推廣方面的想法。由於 Android 的 middleware 技術(包含調校、移植等)對產品的發展是一個重要的技術能力,因此高煥堂老師提出一個 shared object(shared library)工作小組的計畫,此外,高老師也針對 middleware 的觀念做了一些說明;David 也從「授權」的角度來分析,為什麼採用 APL(Apache License)授權的 Android 平臺,比起過去以 GPL 授權為主的桌面 Linux 與...
jollen 發表於 May 10, 2009 9:58 PM
本週六將於北京舉行的「Android 技術大會」上發表有關「Android 移植」的技術演說,配合該演講,最近將陸續整理一些筆記以搭配講稿供與會朋友參考。 Android 的技術優點 Android 平臺的好處是「將開發者侷限在應用層(application level)」的開發,並透過一個設計良好的 application framework 將 library 層「包裝起來」。傳統 GNU/Linux 系統的「開源模式」是「從裡到外」全面開放,應用程式來自四面八方,每個應用程式底層使用到的 library 並不相同,這讓 Linux 平臺的軟體發展容易失控,造成 Linux distribution 上雖然收錄了豐富的應用程式,但相對的也要包山包海地納入非常多的 shared library。 Android 雖然也採用了其他 open source 的專案成果,但 Android 以很聰明的方式,解決傳統 Linux 開放手機平臺的「相依性」問題,這也是過去長久以來,匯整使用(leverage)開放源碼專案開發產品的大問題。Application framework 採用 Java 程式語言,並軟性的將開發者限制在 application level 是...
jollen 發表於 May 19, 2009 10:57 PM
中國版的 Android 系統 OMS 現身 (China's Android OS,OMS - Open Mobile System)。 日前一則新聞 [大陸OPhone商機 台商幕後推手] 以及 [中移動5月中下旬發佈Ophone手機 主介面已可上網流覽] 報導了中國移動(China Mobile)所推出的 OPhone 手機,採用 OMS 作業系統。本週在北京與 OMS(Open Mobile System)的開發商「播思通讯(BORQS)」人員餐敘,OMS 的開發者也拿出了 OMS 的參考設計(reference design)實機讓現場朋友實機操作。 OMS 採用的正是 Google 的 Android 作業系統,如同上述報導所提,OMS 是 BORQS 與...
jollen 發表於 May 22, 2009 10:55 AM
上週受邀至「首屆亞太區 Android 技術大會」發表演說,由於大會希望能多著重在技術層面的主題,因此整理了過去研究 Android/FreeRunner 的一些資料,並將「重點」部份做了一次概念性的說明。Android 的分支(branch)是以「產品」的概念做維護,因此若在目前 Cupcake 能支援的平臺(architecture)上做移植的話,是一個較簡單的工作,只需要在 vendor/ 裡新增自已的 product 並修改 AndroidBoard.mk、AndroidProducts.mk 以及 BoardConfig.mk 即可完成一個 Board/Product 的新分支。 關於底層的部份,以 armv4(如 s3c2443)的 architecture 為例,將重要的工作項目做了整理式的說明。在此提供簡報電子檔下載 [Android Porting Highlights]。...
jollen 發表於 June 3, 2009 5:21 PM
Android應用程式的UI可以使用XML來定義,這個部份在前面的教學裡介紹過。要定義Android應用程式的選單,我們同樣可以使用XML來做描述,請看以下的說明。 建立 Menu 步驟 1. 建立選單的XML檔 在Android專案的res/目錄下新增一個menu/子目錄,然後建立options_menu.xml文件。 圖1: 建立menu/目錄 圖2: 建立options_menu.xml文件 2. 以XML定義選單內容 在options_menu.xml檔案裡,定義我們想要的選單內容。以下是一個範例: <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/new_message" android:title="New Message" /> <item android:id="@+id/quit" android:title="Quit" /> </menu> 3. 將選單加入應用程式 要如何在應用程式啟動時加入我們定義好的選單呢?在onCreateOptionsMenu()事件裡以MenuInflater類別將定義好的選單加入應用程式: public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.options_menu, menu);...
jollen 發表於 June 4, 2009 12:20 AM
Toast是Android提供「快顯訊息」類別,使用時請import以下套件: import android.widget.Toast; 這是一個很好用的類別,特別是在初步建立Android應用程式的控制或行為時,可以輔助我們進行初步的測試工作。 配合上述的選單範例,我們將onOptionsItemSelected()回呼函數實作修改如下: public boolean onOptionsItemSelected(MenuItem item) { int item_id = item.getItemId(); switch (item_id){ case R.id.new_message: Toast.makeText( this, "Please enter your message." + " Your message is at max 255 characters.", Toast.LENGTH_LONG).show(); break; case R.id.quit: Toast.makeText( this, "Going...
jollen 發表於 June 10, 2009 2:56 PM
最少的元件、最舒適的介面 自從有了圖形化應用程式之後,對話盒(dialog)一直是元老級的元件(widget);智慧型手機開始流行後,對話盒仍然是手機介面的重要圖形元件。 在Apple的iPhone問世後,觸控螢幕(touch screen)一直是智慧型手機的標準規格,因此傳統的滑鼠點擊(click)式介面,並不完全適合手指觸控的操作方式,再加上手機觸控螢幕尺吋較小,因此手機應用程式的介面設計,已經與傳統的桌面環境相當不同。 Android的元件庫考量了小尺吋的觸控螢幕,在基本元件的設計上,Android也為使用者做了很體貼的考量。以Android手機應用程式來說,經常使用的元件已經不再像過去的點擊式系統那麼多又複雜;以使用性的角度來看,常被使用的元件如下: * 選單(Menu) * 對話盒(Dialog) * 快顯訊息(Toast) 使用以上三個元件,以及其「變化形」,就能建構一個好用的應用程式介面;再加上Android針對上述的手機操作特性,對其元件庫做了很好的使用設計,因此使用很少的元件,也能提供使用者一個舒適好用的操作介面。 何謂對話盒? 對話盒,故名其思,是一個讓應用程式與使用者「對話」的元件。應用程式透過對話盒與使用者進行下述的對話: * 詢問問題:使用者回答 Yes/No * 詢問偏好:使用者選擇自已偏好的項目,可以是單選,也可以是複選 * 說明狀態:讓使用者知道應用程式目前的狀態,例如:顯示「處理中」、「載入中」等訊息 Android提供的對話盒物件為android.app.Dialog,實作上繼承自Dialog的AlertDialog物件是最基本的對話盒物件。使用AlertDialog對話盒,可以詢問使用者問題,也可以詢問使用者偏好。接下來介紹AlertDialog對話盒的設計方法。 建立AlertDialog對話盒 延續「HelloMenu」範例,現在我們想要加入以下的使用情境: * 使用者按下Menu鍵 * 使用者觸壓 “New Message” 選項 * 出現對話盒、詢問使用者 “Yes/No” 由以上的使用情境來看,應該在onOptionsItemSelected()裡判斷到R.id.new_message項目時,在UI上建立一個對話盒。以下是修改後的onOptionsItemSelected()完整程式碼,完整範例名稱為HelloAlertDialog: public boolean onOptionsItemSelected(MenuItem item) {...
jollen 發表於 June 17, 2009 10:46 AM
CNET ASIA上的一則報導[Android to replace Garmin-Asus' current Linux platform]指出,Garmin-Asus的nuvifone G60將改採Android作業系統。 (圖片來源:CNET) 2009年二月,Garmin與Asus正式宣佈策略聯盟,並以「Garmin-Asus」雙品牌策略進行行銷。nuvifone G60是Garmin-Asus雙品牌行銷策略下的第一個產物,nuvifone G60則是以導航功能為主軸的手機。 根據報導指出,Garmin-Asus現有的Linux平臺將只使用在G60裝置上,未來的裝置會採用Windows Mobile或者是Android作業系統。 如同Garmin的PND產品都是採用Linux作業系統一樣,原本nuvifone G60也計畫採用Linux作業系統,不久前,在engadget上的報導也出現實機照片;但是,隨著CNET這則報導的出現,整個開發計畫是否有了改變,頗令人好奇。 Android原本就對Google Map有很好的支援,再加上nuvifone G60是以導航以及地圖應用為主的手機,若是改採Android作業系統,也是一個合理的做法。 * Update: 2009/6/19...
jollen 發表於 June 18, 2009 11:15 PM
學會產生基本的UI後,接著就要學習UI的事件處理(UI Events),才能讓UI與使用者「互動」。 什麼是事件監聽器(Event Listener) UI的使用者事件處理,即View如何處理使用者的操作,是一個重要的課題。View是重要的類別,它是與使用者互動的前線;在Android框架的設計中,以事件監聽器(event listener)的方式來處理UI的使用者事件。 Android框架提供了非常良好的UI事件處理機制。先前的教學提到,View是繪製UI的類別,每個View物件都可以向Android框架註冊一個事件監聽器。每個事件監聽器都包含一個回呼函數(callback method), 這個回呼函數(callback method)主要的工作就是回應或處理使用者的操作。 Event Listener: 以Click Listener為例 以「使用者觸碰(touch)」的動作來說,當View要處理使用者觸碰的事件時,就要向Android框架註冊View.OnClickListener事件監聽器;當「touch」事件發生時,Android框架便回呼事件監聽器裡的回呼函數。 View.OnClickListener是click listener,故名思意,這是UI的「Click動作監聽器」;當使用者對View進行Click操作時(即觸控畫面上的UI元件),Android框架便會回呼這個View.OnClickListener的回呼函數。 View.OnClickListerner的回呼函數為OnClick()。 這裡所提到的監聽器泛指event listener,主要用來「監聽」使用者的各種動作。除了View.OnClickListener外,Android框架還有以下的event listener(及其callback method): View.OnLongClickListener: onLongClick() View.OnFocusChangeListener: onFocusChange() View.OnKeyListener: onKey() View.OnTouchListener: onTouch() View.OnCreateContextMenuListener: onCreateContextMenu() 另外一種處理UI事件的機制為事件處理器(event handler),event handler與event listener是不一樣的二種處理機制。在自訂Android component的教學裡,再介紹這個部份。...
jollen 發表於 June 18, 2009 11:18 PM
Event Listener的用法: 以Click Listener為例 以Android所提供的View.OnClickListener來說明程式實作方法。一個較為良好的實作方法是在我們的Acitivty類別裡實作View.OnClickListener介面,即: import android.view.View; public class HelloClickListener extends Activity implements View.OnClickListener { ... } 每一個View都可以註冊一個event listener,當Android框架收到「click」事件後,便回呼event listener的callback method。以Button類別(按鈕元件)為例,當我們想要處理使用者觸控按鈕的事件時,就要呼叫Button類別的setOnClickListener()方法來註冊click listener。上述的實作方方法是,直接在我們的Activity類別HelloClickListener裡實作View.OnClickListener,因此上述Button類別的click listener為「this」。 上述的實作觀念,可用圖1來表示。 圖1: HelloClickListener類別實作View.OnClickListener介面 註冊click listener的程式碼如下: public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Button button = (Button)findViewById(R.id.btn); button.setOnClickListener(this);...
jollen 發表於 June 20, 2009 3:20 PM
在這篇教學裡,我們將用一個非常簡單的範例來初步體驗Android的「styles」功能。 什麼是樣式(Styles)? Android的樣式設計(style)是一個很重要的功能,因為它可以讓應用程式裡的元件(widget)「長」得跟別人很不一樣。樣式設計的使用規定如下: 在Android專案裡以XML資源檔來定義「樣式」 一個Android專案可以定義多個樣式 讓widget套用其中一個樣式 Android的styles功能,主要的對象是widget,樣式是為了套用到widget上;另外Android還提供佈景(theme)功能,可以做更大範圍的套用。 如何定義樣式 定義樣式的方式如下: 1. 在Android專案的「res/values」資料夾裡建立styles.xml樣式定義檔。如圖1。 圖1: 建立styles.xml 2.在styles.xml裡定義樣式,以下是一個範例: <?xml version="1.0" encoding="utf-8"?> <resources> <style name="myText"> <item name="android:textSize">18sp</item> <item name="android:textColor">#880</item> </style> </resources> styles.xml的寫法說明如下: 1. 在 <resource>標籤裡定義資源項目, <style>標籤用來定義樣式資源 2. <style>的name屬性定義此樣式的名字,widget使用此名字以套用樣式 3. <item>標籤定義此樣式的內容 4. <item>的name屬性為android:textSize時,表示定義此樣式的字體大小,在此設定字體大小為18sp 5. <item>的name屬性為android:textColor時,表示定義此樣式的字體顏色,在此設定字體顏色為#880(RGB) 6....
jollen 發表於 June 21, 2009 1:30 PM
上一節提到佈景(theme)是可以大範圍套用的UI美化功能,其套用範圍為「整個螢幕」,從程式碼的角度來看,佈景可以套用到以下二個範圍: 整個應用程式(application) 整個activity 接下來,我們以一個很簡單的例子,來說明如何套用佈景到application。在一些應用,我們可能不想要顯示視窗標題(title),怎麼做出這個功能呢?利用佈景設定的方式即可達成。以下是實作方法。 在styles.xml裡加入以下內容: <?xml version="1.0" encoding="utf-8"?> <resources> <style name="myTheme"> <item name="android:windowNoTitle">true </style> </resources> 修改AndroidManifest.xml,在標籤裡加上「theme」屬性: <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.moko.hellotheme" android:versionCode="1" android:versionName="1.0.0"> <application android:icon="@drawable/icon" android:label="@string/app_name" android:theme="@style/myTheme"> <activity android:name=".HelloTheme" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>...
jollen 發表於 July 10, 2009 5:46 PM
App Widget是Cupcake(Android 1.5)所提供的一個功能,這是一個很實用而且能有很大創意想像空間的功能。什麼是App Widget呢?請看底下的操作示範。 在Android桌面長壓約3秒,出現一個選單,如圖1。 圖1:新增項目至桌面 2. 選擇「Widget」,加入”HelloWidget” 圖2:加入自行設計的Widget 桌面上出現了一個「Widget」 圖3:在Android桌面上出現我們自已設計的App Widget 圖4:加入了音樂撥放器App Widget至桌面 這就是App Widget的應用,可以將一個小塊程式(program piece)嵌入到桌面上。App Widget也是一種UI組件,先前所介紹的TextView、WebView等也泛稱為Widget,二者在應用上的差異該怎麼思考呢?以下是幾點看法: 1. App Widget是有生命的UI組件,他會自動更新本身的內容 2. Widget是沒有生命的UI組件,它不會自我更新,只能等待使用者的操作 3. 應用上,App Widget能提供不斷更新的內容,很適合用來設計天氣、時鐘、新聞等主動式應用程式 4. Widget應用上只用來製作UI,而UI因為只能等待使用者來操作,所以過去我們所撰寫的Android應用程式都是屬於被動式應用程式 讓App Widget能「主動」更新自身內容的方法是透過一個「時間觸發裝置」,Android框架會根據我們設定的時間間隔,不斷地callback我們的App Widget。後續將再說明App Widget的做法,並解釋這個部份。...
jollen 發表於 July 10, 2009 6:00 PM
Android的ApiDemo範例庫提供了一個很不錯的App Widget範例;不過,對初學者來說,這個範例可能稍嫌繁瑣。在這裡另外提供一個HelloAppWidget範例如下: /* 範例:HelloAppWidget.java */ package com.moko.hellowidget; import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProvider; import android.content.Context; import android.widget.RemoteViews; public class HelloAppWidgetProvider extends AppWidgetProvider { public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { final int N = appWidgetIds.length; for (int i=0; i<N; i++)...
jollen 發表於 July 11, 2009 11:46 PM
以下分別說明HelloAppWidget的實作,以及技術重點。 appwidget_provider.xml-描述App Widget屬性的資源檔 這個檔案主要描述App Widget的幾個屬性: 長度(width) 高度(height) 更新頻率 UI layout檔 以下是appwidget_provider.xml的完整內容: <?xml version="1.0" encoding="utf-8"?> <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" android:minWidth="85dp" android:minHeight="30dp" android:updatePeriodMillis="3000" android:initialLayout="@layout/main" > </appwidget-provider> 說明如下: 1. <appwidget-provider>標籤定義App Widget的屬性 2. android:minWidth定義寬度 3. android:minHeight屬性定義長度 4. android:updatePeriodMillis定義App Widget的更新頻率,Android框架每隔這段時間,會callback AppWidgetProvider類別的onUpdate()事件;此屬性的時間單位為1/1000秒,以上述的定義來說,等於3秒鐘的時間(3000/1000=3) 5. android:initialLayout屬性指定此App Widget的UI layout定義檔,”@”符號在Android的XML定義檔案,代表「目錄」之意,因此”@layout/main”表示「layout目錄下的main.xml檔案」 以上共四項屬性,是App Widget最基本的屬性,必須良好定義。其中android:updatePeriodMillis屬性可省略,代表不更新App...
jollen 發表於 July 11, 2009 11:52 PM
main.xml-描述App Widget的UI 這個檔案在前面的教學裡介紹過了,它的主要用途是描述UI。我們想要設計一個能嵌進桌面,並顯示文字的App Widget,因此必須使用Android的TextView類別。 以下是main.xml的完整內容: <?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="wrap_content" android:layout_height="wrap_content" android:id="@+id/appwidget_text" android:textColor="#ff000000" /> </LinearLayout> 我們的App Widget使用LinearLayout來安排佈局,而UI為一個TextView物件。在這裡,我們將此TextView物件的id定義為”appwidget_text”。...
jollen 發表於 July 11, 2009 11:54 PM
HelloAppWidgetProvider.java-實作App Widget供應者 程式碼已經在前面的教學裡展示過了,當時只提到一個很基本的重點:使用AppWidgetProvider類別。在這裡,我們先說明設計的部份,才能了解程式如何實作。程式碼的說明稍後再做補充。 圖1:設計App Widget 從圖1的設計裡可以知道(配合查詢Android Reference文件),當程式繼承了AppWidgetProvidr類別後,也繼承了二個主要的method: onUpdate() onDelete() App Widget使用AppWidgetProvider類別,即App Widget的「供應者」,供應什麼東西給誰呢?可以想像成是,我們的應用程式,供應App Widget給Android桌面。 到目前為止,我們知道只需要AppWidgetProvider即可實成一個很陽春的App Widget。而完整的App Widget應該包含三個單元(unit): 1. Provider:此處說明的「供應者」 2. Configure:App Widget的設定單元,用途是提供一個「介面」供使用者輸入資料 3. Receiver:繼承自BroadcastReceiver的單元,即廣播接收器,用來接收Android框架所送出的事件(event) 在後續的教學裡,我們會繼續說明configure與receiver單元的觀念與實作。...
jollen 發表於 July 11, 2009 11:57 PM
AndroidManifest.xml-加入App Widget的程式資訊 AndroidManifest.xml檔案的用途在前面的教學裡介紹過了。以下是其完整內容: <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.moko.hellowidget" android:versionCode="1" android:versionName="1.0"> <application android:icon="@drawable/icon" android:label="@string/app_name"> <receiver android:name=".HelloAppWidgetProvider"> <meta-data android:name="android.appwidget.provider" android:resource="@xml/appwidget_provider" /> <intent-filter> <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> </intent-filter> </receiver> </application> <uses-sdk android:minSdkVersion="3" /> </manifest> 說明如下: 1. 在<application>裡加入<receiver>標籤,指定android:name屬性為主要的provider類別,即”HelloAppWidgetProvider”,請注意,「.」表示後面的字串為一個「類別名稱」,不要忽略了這個重要的小數點 2. 在<receiver>裡加入<meta-data>標籤,指定android:resource屬性為App Widget的資源檔名稱,以我們的範例來說,就是「@xml/appwidget_provider」,即「xml目錄下的appwidget_provider.xml檔案」 3. 在<receiver>裡加入<intent-filter>標籤,讓我們的App Widget可以接收APPWIDGET_UPDATE事件(event)...
jollen 發表於 July 12, 2009 2:10 PM
HelloAppWidgetProvider.java 程式碼說明 圖1: HelloAppWidgetProvider的設計 圖1是目前我們的HelloAppWidget範例設計,說明如下: onUpdate(): 收到ACTION_APPWIDGET_UPDATE廣撥時,框架會callback此method onDelete(): 收到ACTION_APPWIDGET_DELETE廣撥時,框架會callback此method AppWidgetManager: 管理App Widget的類別 先前,在AndroidManifest.xml裡我們讓HelloAppWidgetProider類別可以接收ACTION_APPWIDGET_UPDATE廣撥事件;ACTION_APPWIDGET_UPDATE是最主要的App Widget事件,當AppWidgetProvider被要求為App Widget提供”RemoteView”時,就會收到這個事件。 什麼是RemoteViews? 什麼是RemoteView呢?先看一下框架的設計,如圖2。 簡單來說,「RemoteViews」就是表示UI的類別。res/layout/main.xml描述了應用程式的UI,UI裡當然包含許多組件(Widget),而在先前的教學裡講到了一個觀念「Android應用程式的UI就是一個View tree」,view tree就是「View Hierarchy」。 總結來說,RemotViews是一個用來表示View Hierarchy的類別。透過RemoteViews可以找到UI裡的每一個組件。 圖2: RemoteView的設計(點擊看全圖) 程式說明: HelloAppWidgetProvider.java onUpdate()的程式實作: public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { final int N...
jollen 發表於 July 16, 2009 12:27 PM
什麼是Intent(意圖)? 強大的事件處理「Intent」(意圖)是Android很強大的一種機制。 在 Android 應用程式框架中,有一個非常聰明的事件處理機制,稱之為「Intent」。Intent(意圖)的作用與事件(event)很像,但與傳統的事件處理仍然有些差異。傳統的事件處理,講求的是「處理者(handler)的觸發」,當一事件發生時,便callback讓事件的處理者,或是直接將該事件轉送(forward)給應用程式,由應用程式決定處理方式。 在「Intent」這樣的事件處理觀念裡,Android 試圖將事件解釋為「應用程式的意圖」或是「使用者的意圖」,並試著去解釋該意圖的目的,若 Android 系統本身能理解應用程式的意圖,便會「自行」去處理該意圖所應執行的工作。 Android的做法是,讓每個意圖(Intent)都帶有一個動作(action),並根據不同的動作去行動。 關於前述教學提到的Intent 在前面的教學裡,我們用到二次Intent如下: 1. 自行定義一個Intent、設定Service可接收此Intent,並透過「送出Intent給框架」的方式,請框架啟動該Service 2. 使用Android內部定義的動作「ACTION_VIEW」,來「檢視」(view)一個「URL」資料,當框架看到內部定義的ACTION_VIEW動作時,便「自行」處理該Intent;處理的方式是啟動WebView並連上網站 以前述的教學為例,使用內建的動作“ACTION_VIEW”就可以很容易做出一個「啟動瀏覽器(WebView類別)上網」的應用程式。 透過這二個例子我們知道,Intent的動作可以是自行定義與框架內部定義二種。Android框架的Intent有很多方便實用的「內建動作」,以下我們說明Android內建Intent的美麗之處。 Android內建的Intent Action Android的框架確實是讓每個Intent都包含了一個動作,就稱為action。 為了讓大家更容易了解Intent的基本觀念,我們採用「體驗」的方式來說明如何使用內建的Action。現在,我們列舉以下三個情境,並分別實作其範例: HelloIntentDialer: 啟動撥號器(dialer)並撥號 HelloIntentMusic: 使用者按下「Select Music」後,可以由音樂清單裡選擇音樂並撥放 HelloIntentWallpaper: 啟動Android內建的「背景圖選擇器」,讓使用者更換背景 第二個範例”HelloIntentMusic”其實是ApiDemo裡的範例,而且是很容易能了解Intent內涵的好程式。 除了action外,Intent還可以包含另外一項資訊「data」。 Intent的action指定這個Intent的「動作」是什麼,框架會依指定的動作進行處理;有些action可以附帶一筆資料,這個資料是以Uri的格式撰寫,在HelloIntentDialer的範例會再做說明。 內建的Intent有哪些呢?請參考Android Reference Guide中的Intent類別說明。上述三個範例分別使用以下三個action: 1. ACTION_CALL: 撥號 2. ACTION_GET_CONTENT:...
jollen 發表於 July 17, 2009 3:13 AM
前言 能取得Android OS原始碼,並修改裡頭的內容,有時候也頗有樂趣。最近和幾位朋友聊到「Android框架的改造」,以及如何吸引對Android框架技術有興趣的同好一起交流的議題;我個人認為,一開始如果能丟出一個比較有樂趣的議題,或許可以有拋磚引玉的效果。 上週在北京進行Android培訓課程時,與eoeAndroid社群也進行了想法的交流,由於大家都體認到Android底層技術的重要性及其價值,而且eoeAndroid社群裡也有許多技術好手,所以就和eoeAndroid的創辦人靳岩兄有了一個共同主持研究Android底層技術「同好小組」的想法,希望能透過社群的方式,集合大家的智慧,一起把底層技術研究清楚。 因為要讓大家能有焦點,所以「發題」很重要,這個工作就由落在我身上了。由於第一次希望題目能簡單,並且有趣一點,至少要能達到發球的效果,吸引大家開始關心Android底層技術,所以原則是:希望能用最簡單的方式、讓大家體驗修改底層的樂趣。 題目說明: Launcher 第一次的題目是「Launcher」的修改。 Launcher就是Android的應用程式啟動器,Launcher的功能還包含:桌面的切換、應用程式快捷(shortcut)功能、背景圖(Wallpaper)功能等等。因此,修改Launcher可以改變一些很深層的UI功能。 在Android的桌面最下方,有一個圖示,按下後可以拉出應用程式圖示清單,這是Launcher提供的功能。這一次,因為我們覺得這個Launcher的圖示太製式化了,越看越不好看,所以想要修改一下,換張圖,要怎麼做到呢? 範例展示 例如,圖1是原始的圖示;圖2是修改後的圖示。 圖1: 原始圖示 圖2: 幫Launcher妝扮一下 實作說明 1/4: 取得Android原始碼與EeePC移植 這個功能並不難做,事實上,完全不用寫程式。只要把圖檔重做就可以了。只不過前提是,要知道: 1. 如何取得Android OS原始程式碼 2. 如何編譯Android OS 最簡單的做法是: 1. 下載Android原始碼後、取得EeePC的移植(product) 2. 編譯「TARGET_PRODUCT」為eee_701 3. 由於Launcher都是用Java語法寫成的,所以不會有架構(ARM/x86/...)的問題,編譯後可以取得Launcher.apk;APK套件是不分處理器平臺的 先學會如何由Android原始碼編譯出eee_701的image,才有辦法繼續進行。 實作說明 2/4: 修改圖檔 在Android原始碼的 packages/apps/ 目錄裡,存放了Android內建的應用程式原始碼,Launcher是Android的一個應用程式,所以從這裡找到它的原始碼,並進行修改工程。...
jollen 發表於 August 7, 2009 11:25 AM
HelloIntentDialer是一個自動撥號程式,執行時會自動撥號到指定的電話。這樣的程式要怎麼寫呢?先看到HelloIntentDialer.java的完整程式如下: package com.moko.hellointentdialer; import android.app.Activity; import android.content.Intent; import android.net.Uri; import android.os.Bundle; public class HelloIntentDialer extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Intent dial =...
jollen 發表於 August 7, 2009 11:13 PM
上一篇教學提到如何利用Intent實作「自動撥放」程式。而另外一個較具代表性的Intent應用就是「內容選擇器」。例如,要怎麼實作一個音樂撥放機呢?先說明音樂撥放器HelloIntentSelect範例的使用情境如下: 1. 執行HelloIntentSelect後,出現一個「撥放音樂」的按鈕 2. 按下按鈕後,選擇一個音樂檔撥放 實作「選擇音樂檔」的做法是使用Intent的「chooser」觀念。程式做法如下: 1. 建立action為ACTION_GET_CONTENT的Intent: Intent intent = new Intent(Intent.ACTION_GET_CONTENT); 2.設定Intent的mime type,例如:設定Intent的mime type為聲音檔案: intent.setType("audio/*"); 3.建立內容選擇器並送出Intent: startActivity(Intent.createChooser(intent, "Select music")); 以上的程式是根據Android的Reference Guide寫出來的。當Intent action為ACTION_GET_CONTENT時,表示要根據mime type來「取得內容」(get content),因此呼叫setType()方法,來定義內容的mime type。 定義好mime type後,再呼叫createChooser()方法來產生能取得此mime type內容的「選擇器」,簡單說,就是一個「檔案選取程式」。 利用Android的Intent觀念,我們以不到十行的程式碼實作了一個音樂撥放器。 Action的屬性寫法與常數寫法 Intent的action寫法有二種。第一種寫法是屬性(attribute)寫法,例如第一個HelloIntentDialer範例: dial.setAction("android.intent.action.CALL"); 在「android.intent.action」套件(package)裡,定義了action的屬性。第二種寫法是常數寫法,例如第二個HelloIntentSelect範例: Intent intent = new Intent(Intent.ACTION_GET_CONTENT);...
jollen 發表於 August 22, 2009 10:52 PM
Android提供「SET_WALLPAPER」的內建Intent,當框架收到這個Intent時,就會啟動「背景圖選擇器」,讓我們選取新的背景圖。送出SET_WALLPAPER intent的程式寫法如下: Intent intent = new Intent(Intent.ACTION_SET_WALLPAPER); startActivity(Intent.createChooser(intent, "Select Wallpaper")); 根據Reference Guide的說明,SET_WALLPAPER會啟動一個內容選擇器,所以同時地,我們先呼叫createChooser()方法建立一個內容選擇器後,再送出Intent。 完整程式碼: HelloIntentWallpaper.java package com.moko.hellointentwallaper; import com.moko.hellointentwallaper.R; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Button; public class HelloIntentWallpaper extends Activity implements View.OnClickListener { /**...
jollen 發表於 August 22, 2009 11:05 PM
什麼是NinePatch圖檔 NinePatch是一種「可延展」的PNG圖檔。NinePatch圖檔的用途是製作「可隨文字大小縮放」的圖片,如圖1。 圖1: 文字背景可隨著文字大小縮放 NinePatch是很有用的圖片格式,可做為widget的「背景圖」。如圖1的範例,其應用程式的設計如下: 文字部份使用TextView元件 使用TextView的XML attribute來設定文字大小 使用TextView的XML attribute來設定一張背景圖 使用NinePatch圖片做為背景圖,如此一來背景圖就可以隨著文字大小縮放 首先,第一個工作就是「製作NinePatch圖檔」,方式如下。 Step 1. 準備一張原始的PNG圖檔,如圖2。 圖2: 原始PNG圖檔(arrow.png) Step 2. 啟動Android提供的draw9patch工具,直接執行Android SDK tools/目錄下的draw9patch執行檔即可,如圖3。 圖3: Android SDK提供的draw9patch工具(點擊看原圖) Step 3. 開啟原始PNG圖檔,編輯圖檔,如圖4。 圖4: 開始編輯圖檔(點擊看原圖) 如何編輯NinePatch圖檔 NinePatch圖檔的製作方式是「繪製二條線」,分別在原始圖檔的上方與左方繪出二條「黑線」,黑線所交集的區域即為「可延展」區域。如下圖的粉紅色區域。 圖5: 定義延展區 「可延展區」是Android框架用來擺放文字的區域,換句話說,文字(TextView)只會被放置在粉紅色區域,並且擺放的原則是「對準粉紅區域的中心點」,即上下置中、左右也置中。非「可延展區」,即綠色部份,並不會隨著文字的大小縮放延展。所以: 1. 綠色區域是固定大小區域 2. 粉紅色區域是可延展區域、文字擺放於此 圖中的「二條黑線」是怎麼畫出來的呢?方式如下。...