more: Jollen 的 Embedded Linux 教育訓練

Jollen's Blog「Android OS」裡的所有文章!

  

Jollen 的Android 教學,#1: Android 應用程式模式

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 的 Android 教學,#2: “Hello Moko” - Activity 與 View 的關係

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 的 Android 教學,#3: 第一個 Android 專案

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 的 Android 教學,#4: 使用 XML 安排 UI

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 的 Android 教學,#5: 使用 View 的 XML 屬性

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 的 Android 教學,#6: WebView 體驗與 findViewByID

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 的 Android 教學,#7: 如何讓文字並排顯示 - TableLayout

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 的 Android 教學,#8: 沒有 UI 的 Service

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 的 Android 教學,#9: 啟動 Service - startService()

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 的 Android 教學,#10: 如何檢查 Service 是否已啟動?使用 Android 除錯器

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 的 Android 教學,#11: AndroidManifest.xml 的用途是什麼?

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 標籤裡加入...

「Android Day Package -- Android 應用程式新手入門」

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) ‧開放手機平台陣營 ‧授權模式比較...

出現搭載 Android 平臺的 PMP 產品

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...

Android Day 活動紀錄:Android 應用程式新手入門訓練

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 的 Android Porting 手札 #1: Android 移植概觀

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 是...

中國移動 OPhone 現身:採用 OMS 系統的 Android 手機(實機附圖)

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 與...

「Android Porting Highlights」簡報上線

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 的 Android 教學,#12: 如何建立選單 Menu

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 的 Android 教學,#13: 快顯訊息 android.widget.Toast

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 的 Android 教學,#14: 什麼是對話盒 (Dialog)?如何建立對話盒?

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) {...

Garmin-Asus的nuvifone G60改用Android作業系統

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 的 Android 教學,#15: 什麼是事件監聽器(Event Listener)?

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 的 Android 教學,#16: Event Listener的用法: 以Click Listener為例

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 的 Android 教學,#17: 樣式設計(Styles)初體驗

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 的 Android 教學,#18: 佈景(Theme)初體驗

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 的 Android 教學,#19: 什麼是App Widget?

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 的 Android 教學,#20: 如何設計一個小型的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 的 Android 教學,#21: appwidget_provider.xml-描述App Widget屬性的資源檔

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 的 Android 教學,#22: main.xml-描述App Widget的UI

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 的 Android 教學,#23: HelloAppWidgetProvider.java-實作App Widget供應者

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 的 Android 教學,#24: AndroidManifest.xml-加入App Widget的程式資訊

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 的 Android 教學,#25: HelloAppWidgetProvider.java 程式碼說明

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 的 Android 教學,#26: 強大的Intent機制

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:...

Android的Launcher研究:客製化桌面UI

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 的 Android 教學,#27: 使用ACTION_CALL實作自動撥號: HelloIntentDialer

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 的 Android 教學,#28: HelloIntentSelect - 內容選擇器(Content Chooser)

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 的 Android 教學,#29: HelloIntentWallpaper - 背景圖選擇器

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 的 Android 教學,#30: R.drawable 應用-製作NinePatch圖檔

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. 粉紅色區域是可延展區域、文字擺放於此 圖中的「二條黑線」是怎麼畫出來的呢?方式如下。...

深耕校園、 清華大學Android種子教學培訓課程

jollen 發表於 August 29, 2009 11:36 AM

Android校園計畫 產學官三界過去在Android的發展做了很多腦力激盪的工作,這是一個很好的現象,有助於Android熱潮的延續,以及各界對Android作業系統的重視。提到Android研發能量的建立,最根本的治理方式是「深耕校園」。 因此,現階段要務是「深耕校園」。實際做法建議是「建立種子」。建立種子師資或種子學生,透過導入課程至大學課程的方式,讓大一與大二的學生「認識」並「開始接觸」Android作業系統;種子學生的建立,可以鎖定大三以上、研究生或是以實驗室為單位,做為培訓對象。這個階段的做法,可以建立採取「種子培訓營」的方式進行。 學生如果能被適當的訓練,就能將把創造力,或是想像力,轉換成「具體」的成果。一個實際的例子是,如果能訓練非資訊本科系的學生撰寫Android應用程式,學生才能有能力把想法轉換成「程式原型」、才能展現創意。因此「深耕校園」的目標應該是要更「普及」,而不是只導入本科系。 活動詳情可參閱嵌入式軟體聯盟網站,以下是課程資訊。希望藉由自已在教育訓練方面的經驗,貢獻棉薄之力。 課程簡介 本課程的目的是培訓大專校院之Android種子教學師資。課程針對Android系統,由底層框架、驅動程式、移植、到應用開發,做一完整的介紹,並利用OpenMoko FreeRunner手機為實驗平臺,實際動手實作。整個課程設計以符合業界實際需要為重點,藉由本課程之培訓,讓學校能充實Android研發能量,未來達到產學結合的效果。 時間:98年9月7日 (星期一) 至9月10日 (星期四) 地點:清華大學資訊電機館資工系3F 328室 資格:國內各大專校院教師或學生,對Android系統之教學及開發有濃厚興趣者 名額:40人 費用:NT$ 2,500 (含午餐、設備使用費、講義;報名後通知繳費) 主辦單位:教育部顧問室嵌入式軟體聯盟、清華大學電腦與通訊科技研發中心、清華大學資訊工程學系 協辦單位:Jollen’s Consulting、清華大學OpenLab 聯絡人: 吳少文小姐 Tel: 03-5742410 E-mail: swwu@mx.nthu.edu.tw...

清華大學Android種子教學培訓課程: Day1 上課紀錄

jollen 發表於 September 8, 2009 1:58 AM

第一天的「Android種子培訓課程」以應用開發為主軸,介紹了Android應用程式入門的課程。現場有許多大學的老師,因此在課程進行中,特別給了一些建議。針對Android應用程式入門教學來說,做「API走訪式」的教學比較無法切中正題,而且也讓課程顯得乏味。因此,我給了二點小建議: 1. Android應用的教學,以「應用程式的模式」為重心,因為Android應用程式的入門重點在於Activity/Service、R.java、XML layout、XML attributes、View(UI)、Intent等「模式」的觀念,所以最好不要採取API介紹式的教學方法 這裡的所提的「模式」即「撰寫程式」的方法。 2. 透過Android應用程式建立對框架(Framework)的基本認識。Android作業系統的一大重點在於「框架的設計」,而對應用程式進行較深度的分析,是了解框架設計的一個好方法。 例如,今天在課堂中所提到的「應用程式向框架取得(get)物件(object)」,而不是「應用程式自行建立物件("new"一個object)」的觀念。另外一個觀念,則是「應用程式要避免建立物件」,這是Android Dev Guide提到的「為效能而設計」的第一個條文。 第二天的課程將會開始介紹Android開發平臺,並展示一些「Lab」範例。...

Jollen 的 Android 教學,#31: R.drawable 應用-如何使用NinePatch圖檔

jollen 發表於 September 20, 2009 10:39 PM

上一篇日記介紹了「如何製作NinePatch圖檔」,因此有讀者問到「如何寫程式」,因此特別補上這篇教學。 開始寫程式: HelloNinePatch 範例HelloNinePatch的實作方式如下。 Step 1. 建立一個新的Android專案,命名為HelloNinePatch。 Step 2. 將arrow.9.png托曳(drag)到HelloNinePatch專案裡的「res/drawable」目錄下。如圖1。 圖1: 將arrow.9.png放進res/drawable資料夾 Step 3. 修改UI(res/layout/main.xml),設計出上一篇教學(#30)裡的圖2畫面。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" > <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="small world" android:textSize="12sp" android:background="@drawable/arrow" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="big world" android:textSize="24sp" android:background="@drawable/arrow" />...

Android 的 HAL 技術, #1: 簡介與發展現況

jollen 發表於 October 8, 2009 2:05 AM

Android 的 HAL(硬體抽像層)是 Google 因應廠商「希望不公開源碼」的要求下,所推出的新觀念,其架構如下圖。雖然 HAL 現在的「抽象程度」還不足,現階段實作還不是全面符合 HAL 的架構規劃,不過也確實給了我們很好的思考空間。 圖1:Android HAL 架構規劃 這是 Patrick Brady (Google) 在2008 Google I/O 所發表的演講「Anatomy & Physiology of an Android」中,所提出的 Android HAL 架構圖。從這張架構圖我們知道,HAL 的目的是為了把 Android framework 與 Linux kernel 完整「隔開」。讓 Android 不至過度依賴 Linux kernel,有點像是「kernel independent」的意思,讓...

Android 的 HAL 技術, #2: 採用Service架構方式

jollen 發表於 October 14, 2009 6:17 PM

在上一篇日記裡,我們介紹了Android HAL的大概念。接下來,將慢慢地進行細部的分析與研究。首先,我們先針對HAL的現況先做討論,後續再針對HAL的設計提出觀念。 圖1:採用Service架構與不採用Service架構 如圖1,應用程式存取驅動程式的過程,可區分為以下二種: 採用Service架構方式 不採用Service架構方式 採用Service架構方式是比較標準的做法,即圖上藍色線的部份;紅色線的部份為非Service架構式的做法。先前,在「Android 驅動開發關鍵技術:HAL及移植要領」演講中最後所提出的一個LED範例,即是一種非架構式的做法,簡報上有一段範例程式碼,歡迎下載參考。 Android HAL Introduction: libhardware and its legacyView more documents from Jollen Chen. 採取Service架構的方式,是建議的做法,當然因為這是標準架構,也應該採用。 Service在Android框架裡的角色是「存取底層硬體」,往上層的話,可以和應用程式溝通。因此,採用標準的Service做法,好處是在資料存取(data communication)的處理較為系統化。這方面,Android提供了標準的處理架構,後續再進行討論。 圖上的「core libraries」即是Service程式碼的實作,也就是,Android應用程式透過JNI(Dalvik)來到Service這一層,再透過Service載入*.so檔;而非標準做法則是讓應用程式直接透過JNI來載入*.so檔。 不使用Service架構 紅色的過程,因為不使用Service架構,因此「框架整合」的工作量比較小,甚致大部份的實作都不需要改動框架本身。這樣的做法,就有點像是「跳過framework」的方式;相對的,此時應用程式開發者需要考慮的設計議題就比較多。 例如,當遇到block operation時,是否需要獨立的Java thread來處理?...

Android 的 HAL 技術, #3: 小探Android Service與Native Service

jollen 發表於 November 27, 2009 1:59 AM

前二篇教學提到「採用Service架構整合HAL的做法」。這裡再針對HAL如何採用Service架構與框架整合做一個概念的介紹。 Android的Service分為二種:Android Service與Native Service。 Android Service Android Service又稱為Java Service,是實作在框架層(framework)裡的「Server」。這裡所講的「Service」是System Service,又稱為Server,與應用程式設計上所討論的Service(android.app.Service)不同。Android Service以Java撰寫。 Native Service Native Service則是實作在Runtime層裡的Server。架構設計上,我們有二個選擇,一個是實作Android Service、再透過JNI與HAL stub溝通;另一個選擇是,跳過Android Service,讓Application(Manager API)直接與Native Service溝通。 未來的Android發展趨勢,應會以第二種做法為主,即Manager API直接與Native Service溝通,以達到更好的效能表現。 延伸閱讀 * 2009.10.14: Android 的 HAL 技術, #2: 採用Service架構方式 * 2009.10.08: Android 的 HAL 技術, #1: 簡介與發展現況...

Android 的 HAL 技術, #4: Android Service 與 HAL Stub

jollen 發表於 November 28, 2009 9:56 PM

目前為止,我們提了「HAL Stub」的觀念,了解到 stub 是一種代理人的觀念,架構設計上,採取「provide operations」與「callback」機制,而不是採用「module」即 library 的 direct function call 做法。 接著,又提到「採取Service架構的方式」。在講解HAL stub的實作細節前,需要大略了解一下Android Service與HAL stub的關係;因為,架構設計上是「透過Android Service取得HAL stub提供的operations」。 取得HAL stub operations的程式碼實際上是實作在Native Service裡,相關的實作細節留待後續再做說明。 Android Service與HAL stub的關係 應用程式(Application)使用了Manager API,Manager API經由Android Service來到Native Service層,最後Native Service層再引用(invoke)HAL stub。這個過程,總共經過了以下3個介面,如下圖。 1. 這是一個 remote interface,應用程式與Android Service在不同的 process 上執行。 2. 這是...

Android 的 HAL 技術, #5: 繼承 HAL 的 struct hw_module_t

jollen 發表於 December 1, 2009 10:09 PM

撰寫 HAL stub 除了要具備系統程式(systems software)的觀念外(這是基礎),「思考方式的改變」也是重要的一堂課。 思考方式哪裡不同? 實作 HAL stub 的首要工作是「繼承 struct hw_module_t 抽象型別」。Class(類別)屬於一種抽象型號(ADT)。 首先,引入最重要的標頭檔(header file): #include <hardware/hardware.h> 接著,再定義一個「MODULE ID」。這個 mdoule ID 將會被 HAL 層用來尋找 HAL stub。我們舉最簡單的裝置類型「LED」來做為範例: #define LED_HARDWARE_MODULE_ID "led" 繼承 HAL 的 struct hw_module_t 抽象型別(即 base class 的概念),並取名為 struct led_module_t(即...

Android 的 HAL 技術, #7: 取得 Proxy Object

jollen 發表於 December 26, 2009 11:36 PM

延續上一則日記的介紹,在完成HAL Stub的實作後,緊接著的工作就是撰寫Native Service。 談了許多「Android Service」以及「HAL Stub」,這裡再補充一點。Android作業系統啟動時,會執行一個process稱為servicemanager。Servicemanager process負責管理、提供並保存「Android Service」。Android Service為Java層,因此接下來會透過JNI來呼叫C/C++層的Native Service。 廣義來說,Native Service也提供Runtime的功能,即Core Library層。Runtime的重要工作之一為「取得HAL Stub所提供的API」,因此這是撰寫完整Native Service的前哨站。 什麼是 Proxy Object? Native Service呼叫HAL的hw_get_module() API取得stub物件,即HAL_MODULE_INFO_SYM。 HAL會去尋找HAL Stub檔案,HAL Stub是以*.so檔的形式存在,並佈署於/system/lib/hw目錄下。HAL會根據module ID以及”ro.product.board”去尋找相對應的*.so檔,以我們的LED範例來說,HAL會回傳回led_module_t結構的物件(an instance of led_module_t class)給Native Service。 我們把HAL回傳給Native Service的資料稱為「Stub Object」或是「Proxy Object」,即先前所提及的「代理人」觀念。Native Service透過代理人與 Linux 驅動程式溝通。這個過程的觀念如圖1所示。 圖1:取得Proxy Object hw_get_module(),這是HAL所提供的API,也是實作HAL...

Android 的 HAL 技術, #8: 實作 HAL Stub

jollen 發表於 January 2, 2010 11:31 PM

承日記「Android 的 HAL 技術, #6: 小結 HAL stub 實作步驟」與「Android 的 HAL 技術, #7: 取得 Proxy Object」。在了解基本的觀念,以及架構上的設計後,接著就可以開始實作 HAL Stub 了。以下是 LED Stub 的實作範例,將程式碼儲存為 led.c: static struct hw_module_methods_t led_module_methods = { open: led_device_open };   const struct led_module_t HAL_MODULE_INFO_SYM = { common:...

「Jollen 的 Android Framework in a Nutshell 演講」講題規劃完畢

jollen 發表於 January 26, 2010 12:22 AM

從去年就開始構思的「Jollen 的 Android Framework in a Nutshell」演講,終於在上週六正式完成講題規劃了。初版講稿也開始進入檢查階段,第一場演講預估在二月底或三月初舉行,詳細的時間與地點,稍後將發佈於演講活動官網 [Jollen's Android Framework in a Nutshell 演講]。 「In a Nutshell」是本演講的核心理念,也是規劃講稿時所依循的精神;關於堅果殼精神,可參考先前日記 [「Jollen 的 Android Framework in a Nutshell」演講] 的說明。 講題的規劃將以一個實例「揭開」Android 框架的黑盒子、將 Android 結構做展開的動作,並分別介紹每個層面的技術重點;希望藉由這個精心規劃的演講活動,能幫助對 Android 框架與系統底層有興趣的朋友,有效率地掌握技術重點。...

「Android Framework Introduction」講座

jollen 發表於 February 1, 2010 11:58 PM

Android Framework 技術的重要性日漸提高,研究 Android Framework 架構或是內部結構成為一項重要的工作。明天(2/2)受邀至鴻海土城民生廠進行一場訓練課程,主題是「Android Framework Introduction」;議題雖然是「introduction」,但突然有個想法,希望能做更深入的 introduction。正好近期在整理研究資料,所以把抓出的議題也和大家分享。計畫介紹的技術主題(Features)如下: 1. Android Framework Features SystemServer & ServerThread Main Thread android.app.Activity 與 android.app.Service Android Process 模式 ServiceManager 與 getSystemService API JNI & Native Method Blocking & Long Operations VMThread & Thread Zygote...

MOSP: Mokoid Project (Mokoid Open Source Project) 上線

jollen 發表於 February 8, 2010 10:55 PM

為了能在「Jollen 的 Android Framework in a Nutshell 演講」上搭配範例做講解,因此「特製」了一個 LedManager 範例;此範例原來是「Android 框架與驅動程式整合: HAL 原理與實作訓練」培訓課程的實作範例,目前計畫以此範例的部份內容做為演講材料。歡迎有意參加 Jollen 的 Android Framework in a Nutshell 演講的朋友,事先下載 Mokoid 程式碼。 Mokoid 提供一個 LedTest 範例程式,同時,LedTest 也是 Mokoid 專案目前所提供的第一個「近乎完整」的範例。請大家參考 apps/LedTest/src/com/mokoid/LedTest/ 裡的程式碼。Mokoid 專案的第二個範例,計畫是「MotorManager」,目前仍處於測試階段,預計在《台北場》演講時釋出。 Mokoid 的目的是提供「教學開發板」一套完整的 architect code 供實驗課程使用,或是搭配正課做原理教學,當然,首要目的是應用在自已的培訓課程上。主要的理念是「去除使用 dirty code...

Jollen 的 Android 系統管理雜記, #1: 關於 android.uid.system 與 AID_SYSTEM

jollen 發表於 February 9, 2010 3:46 PM

在 [Mokoid] 的 LedTest 範例裡,找到 [AndroidManifest.xml] 檔案。這個檔案為應用程式的「交貨清單」;在開發 LedTest 的過程中,我們加入了一個屬性如下: <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.mokoid.LedTest" android:sharedUserId="android.uid.system"> 原來,ServiceManager 會去檢查應用程式的權限;Android 作業系統會根據 UID 做權限管制,這裡所講的 UID 就是 Linux 系統管理面所討論的 User ID,即使用者 ID。在 [frmeworks/base/cmds/servicemanager/service_manager.c] 裡,找到這段實作: int svc_can_register(unsigned uid, uint16_t *name) { unsigned n;   if ((uid == 0)...

Override Context.getSystemService()

jollen 發表於 February 26, 2010 10:12 PM

Context.getSystemService() 是一個很重要的 API,也是「Android 應用程式控制硬體」的起點。在一個開發項目中,如何擴展 getSystemService() 的實作成為一個重要的課題。 幾天前與客戶進行技術討論時,適巧討論到這個議題,因此在這裡做一個簡單的紀錄與大家分享。應用程式要存取手機上的 Sensor 裝置時,須取得 SensorManager 物件,程式寫法如下: public class mokoidSensor extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main);   SensorManager sensor = (SensorManager)getSystemService(SENSOR_SERVICE); sensor.getSensors();...

Jollen 的 Android 系統管理雜記, #2: Java Package 與 Jar File 對應設定

jollen 發表於 March 2, 2010 10:45 PM

經由 [Mokoid] 範例,我們可以學習到擴充(Extent)Android 框架的做法。搭配 Product Tree 的方式,我們將 LedManager 與 LedService 二個類別編譯成獨立的 jar 檔(mokoid.jar),mokoid.jar 會被 Android build system 自動佈署到 system.img 裡(system/framework/mokoid.jar)。 因為 mokoid.jar 裡的類別沒有做 preload,並不是「preload class」,所以需要額外的系統設定,才能讓 Android 作業系統找到 LedManager 與 LedService 二個類別。在 Mokoid 範例中,找到一個名為 com.mokoid.server.xml 的設定檔,內容如下: <?xml version="1.0" encoding="utf-8"?> <permissions> <library...

Top | 授權條款 | Jollen's Forum: Blog 評論、討論與搜尋
Copyright(c) 2006 www.jollen.org