Android 学习资源

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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
史莱姆壁纸和粘史莱姆 史莱姆背景壁纸和史莱姆主题扩展,由LovelyTab提供。 安装它以获得最大的浏览体验。 免费打开有趣的新闻,事实并玩游戏,同时享受自己喜欢的高清主题和壁纸。 使用方法:-此史莱姆壁纸和施莱姆史莱姆扩展程序非常简单,只需单击“添加到镶边”即可自动添加。 -在左上角,单击设置以根据需要自定义所有选项。 -浏览时享受最好的墙纸和免费小部件单击“添加到Chrome”,即表示我接受并同意安装墙纸扩展程序“史莱姆背景墙纸”和“史莱姆主题”,并将“新标签”设置为https://search.lovelytab.com,由服务,使用条款和隐私政策。 使用条款:https://faq.lovelytab.com/page/eula隐私政策:https://faq.lovelytab.com/page/privacy功能:-本地时间选项–无论您身在何处都可以更改-天气会也可以匹配您当前的目的地-使用我们的新“史莱姆壁纸”和“施莱姆史莱姆”扩展程序,只需单击一下即可为喜欢的网站添加书签。 -单击左上角的操纵杆可免费玩游戏-阅读相关新闻和有趣的事实-史莱姆壁纸和粘史莱姆扩展程序可让您自定义和添加/删除这些选项。在此扩展程序中,您将找到几乎所有相关背景您还可以享受自己喜欢的主题,同人作品,应用程序,炫酷壁纸,全高清图像,甚至4K素材的浏览。 如何卸载:-单击Chrome浏览器右上角的水平三个点,转到设置,单击“扩展名”,然后找到要安装的扩展名。 点击垃圾桶图标即可,或者-只需右键单击工具栏上的心形按钮,然后单击“从Chrome删除”免责声明:Slime Background Wallpaper&Slime Theme是粉丝为粉丝和版权属于材料的各自所有者。 这是非官方的,如果有任何问题,请提醒我们,我们将予以解决。 在https://lovelytab.com上下载具有超赞全高清壁纸的更多免费扩展程序 支持语言:Bahasa Melayu,Deutsch,English,English (UK),English (United States),Français,Nederlands,Norsk,Tiếng Việt,Türkçe,català,dansk,eesti,español,hrvatski,italiano,latviešu,lietuvių,magyar,polski,português (Brasil),português (Portugal),română,slovenský,slovenščina,suomi,svenska,čeština,Ελληνικά,Српски,български,русский,українська,עברית,فارسی‎,हिन्दी,ไทย,‫العربية,中文 (简体),中文 (繁體),日本語,한국어
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值