第 2 節 介面佈局檔 第 1 項 說明 第 2 項 原始碼 第 3 節 主程式開發 第 1 項 主程式 - 基本設定 第 2 項 主程式 - 產生亂數 第 3 項 主程式 - 數字靠邊 數字加總 第 4 節 加入手

Similar documents
Java講義

主程式 : public class Main3Activity extends AppCompatActivity { ListView listview; // 先整理資料來源,listitem.xml 需要傳入三種資料 : 圖片 狗狗名字 狗狗生日 // 狗狗圖片 int[] pic =new

多媒體應用 13 新增專案並完成版面配置 <ExMusic01> <activity_main.xml> ImageView ID imgplay ImageView ID imgstop ImageView ID imgfront TextView ID txtsong TextView ID t

Java講義

Android Service

單步除錯 (1/10) 打開 Android Studio, 點選 Start a new Android Studio project 建立專案 Application name 輸入 BMI 點下 Next 2 P a g e

res/layout 目录下的 main.xml 源码 : <?xml version="1.0" encoding="utf 8"?> <TabHost android:layout_height="fill_parent" xml

Database_001

Android Fragment

Java講義

Dynamic Layout in Android

用手機直接傳值不透過網頁連接, 來當作搖控器控制家電 ( 電視遙控器 ) 按下按鍵發送同時會回傳值來確定是否有送出 問題 :1. 應該是使用了太多 thread 導致在傳值上有問題 2. 一次按很多次按鈕沒辦法即時反應

0511-Android程式之GPS應用_專題週記4

预览图 : (2) 在 SelectCity.java 中增加控件, 用于绑定 select_city 文件的 ListView, TextView,EditTest 等控件 代码和注释如下 :

實作SQLiteOpenHelper類別

ShareText

RecyclerView and CardVew

投影片 1

Microsoft Word - 02.目錄.doc

Android + NFC

任務二 : 產生 20 個有炸彈的磚塊, 放在隨機的位置編輯 Block 類別的程式碼 import greenfoot.; // (World, Actor, GreenfootImage, Greenfoot and MouseInfo) Write a description of class

建立Android新專案

Microsoft Word - 01.DOC

書面

The golden pins of the PCI card can be oxidized after months or years

建立Android新專案

詞 彙 表 編 號 詞 彙 描 述 1 預 約 人 資 料 中 文 姓 名 英 文 姓 名 身 份 證 字 號 預 約 人 電 話 性 別 2 付 款 資 料 信 用 卡 別 信 用 卡 號 信 用 卡 有 效 日 期 3 住 房 條 件 入 住 日 期 退 房 日 期 人 數 房 間 數 量 入

教育部補助資訊軟體人才培育先導計畫 100 年度課程發展專案計畫 實驗課程名稱 : IPC(Inter-Process Communication) 開發教師 : 張晉源老師 開發學生 : 林政揚 學校系所 : 樹德科技大學資訊工程學系

PowerPoint 簡報

幻灯片 1

Android Android Android SDK iv

untitled

EJB-Programming-4-cn.doc

Android 编程基础 Android 开发教程 & 笔记 1

Microsoft Word - 第1章 Android基本概念.docx

雲端 Cloud Computing 技術指南 運算 應用 平台與架構 10/04/15 11:55:46 INFO 10/04/15 11:55:53 INFO 10/04/15 11:55:56 INFO 10/04/15 11:56:05 INFO 10/04/15 11:56:07 INFO

TPM BIOS Infineon TPM Smart TPM Infineon TPM Smart TPM TPM Smart TPM TPM Advanced Mode...8

使用手冊

Microsoft PowerPoint - 12 特色开发.ppt [兼容模式]

epub83-1

840 提示 Excel - Excel -- Excel (=) Excel ch0.xlsx H5 =D5+E5+F5+G5 (=) = - Excel 00

Microsoft Word - 第3章.doc

SDK 概要 使用 Maven 的用户可以从 Maven 库中搜索 "odps-sdk" 获取不同版本的 Java SDK: 包名 odps-sdk-core odps-sdk-commons odps-sdk-udf odps-sdk-mapred odps-sdk-graph 描述 ODPS 基

目 錄 一 ANDROID 開發系統需求 作業系統 開發工具... 1 二 安裝 ANDROID 開發工具 安裝 JDK 使用 APT-GET 安裝 使用套件管理程式安裝... 9 三 ANDROID 程式撰寫... 1

Android 开发教程

Java java.lang.math Java Java.util.Random : ArithmeticException int zero = 0; try { int i= 72 / zero ; }catch (ArithmeticException e ) { // } 0,

CC213

Android + WebService

Lecture01_Android介绍

Java

Microsoft Word - 第3章 Activity.doc

Spyder Anaconda Spyder Python Spyder Python Spyder Spyder Spyder 開始 \ 所有程式 \ Anaconda3 (64-bit) \ Spyder Spyder IPython Python IPython Sp

Fun Time (1) What happens in memory? 1 i n t i ; 2 s h o r t j ; 3 double k ; 4 char c = a ; 5 i = 3; j = 2; 6 k = i j ; H.-T. Lin (NTU CSIE) Referenc

untitled

Microsoft PowerPoint - 07.Android 介面元件-TableLayout、Toast、AlertDialog

1: public class MyOutputStream implements AutoCloseable { 3: public void close() throws IOException { 4: throw new IOException(); 5: } 6:

運算子多載 Operator Overloading


概述

建立Android新專案

建模与图形思考

投影片 1

Chapter 1: Introduction

6-1 Table Column Data Type Row Record 1. DBMS 2. DBMS MySQL Microsoft Access SQL Server Oracle 3. ODBC SQL 1. Structured Query Language 2. IBM

Lecture01_Android介绍

Microsoft PowerPoint - VB14.ppt

Microsoft PowerPoint - 05.Android 介面元件-RelativeLayout、Button、TextVeiw、EditText

任务实施 (1) 创建项目 图 3-1 欢迎界面 首先创建一个工程, 将其命名为 BoXueGu, 指定包名为 com.boxuegu (2) 导入界面图片将欢迎界面所需要的背景图片 launch_bg.png 导入到 drawable 文件夹中, 项目的 icon 图标 app_icon.png

ltu

untitled

1.JasperReport ireport JasperReport ireport JDK JDK JDK JDK ant ant...6

封面-12

建立Android新專案

FETnet - Acer Iconia Tab  (A500 Wi-Fi 版) 平板電腦操作指南

(TestFailure) JUnit Framework AssertionFailedError JUnit Composite TestSuite Test TestSuite run() run() JUnit

<4D F736F F F696E74202D20332D322E432B2BC3E6CFF2B6D4CFF3B3CCD0F2C9E8BCC6A1AAD6D8D4D8A1A2BCCCB3D0A1A2B6E0CCACBACDBEDBBACF2E707074>

Microsoft Word zw

Microsoft Word - 第5章.doc

小应用 Magic8

mvc

新版 明解C++入門編

2 WF 1 T I P WF WF WF WF WF WF WF WF 2.1 WF WF WF WF WF WF

3.1 num = 3 ch = 'C' 2

0 0 = 1 0 = 0 1 = = 1 1 = 0 0 = 1

Transcription:

Android 講義 2016.07.03 目錄 第 1 章 資料存取... 1 第 1 節 使用 SharedPreferences... 1 第 1 項 介面佈局檔... 1 第 2 項 建立主程式的內容 - 儲存偏好設定... 1 第 3 項 驗證儲存偏好的動作... 3 第 4 項 建立主程式的內容 - 提取偏好設定... 3 第 2 節 簡單使用 SQLite... 5 第 1 項 介面佈局檔... 5 第 2 項 建立 SQLiteOpenHelper 的子類別... 5 第 3 項 修改主程式... 7 第 4 項 驗證看看 -sqlite3 指令... 9 第 5 項 顯示資料表內容... 9 第 2 章 專案猜數字比大小... 11 第 1 節 建立專案... 11 第 1 項 建立介面佈局檔... 11 第 2 項 主程式... 12 第 3 章 專案建立 WebView 程式... 15 第 1 節 修改 AndroidManifest.xml 檔案... 15 第 2 節 修改 main.xml... 16 第 3 節 建立 mainwebview.xml... 16 第 1 項 建立 Activity 主程式... 17 第 2 項 建立 golink01 程式... 18 第 4 章 專案音樂播放程式... 20 第 1 節 最陽春的音樂播放程式... 20 第 1 項 建立空白的新專案... 20 第 2 項 加入 MediaPlayer 物件... 20 第 3 項 改善一下, 離開程式時也能停止音樂的播放... 22 第 4 項 按下播放按鈕才開始播放... 23 第 5 章 專案 2048 遊戲... 26 第 1 節 遊戲介紹... 26 第 1 項 玩法... 26 第 2 項 程式運作概念... 27 Android 講義 v0.8 i 王振民

第 2 節 介面佈局檔... 29 第 1 項 說明... 29 第 2 項 原始碼... 30 第 3 節 主程式開發... 34 第 1 項 主程式 - 基本設定... 34 第 2 項 主程式 - 產生亂數... 36 第 3 項 主程式 - 數字靠邊 數字加總... 38 第 4 節 加入手勢... 42 第 1 項 移除 Button 物件... 43 第 2 項 加入手勢... 44 第 6 章 專案 GPS 服務... 48 第 1 項 設定 manifest 的使用授權項目... 48 第 2 項 建立介面佈局檔... 49 第 3 項 建立連結資料庫的 dbhelper... 52 第 4 項 建立主程式... 53 第 5 項 建立第二個程式 - 佈景主題... 58 第 6 項 建立第二個程式 - 主程式... 59 Android 講義 v0.8 ii 王振民

第 1 章 資料存取 第 1 節 使用 SharedPreferences SharedPreferences( 存取偏好設定 ) 請建立新的專案, 分別再依以下動作進行 第 1 項 介面佈局檔 1. 建立 TextView, 顯示文字為 姓名 2. 建立 EditText, 設定 id 為 et01 3. 建立 TextView, 顯示文字為 興趣 4. 建立 EditText, 設定 id 為 et02 5. 建立 Button, 設定 id 為 bt01, 顯示文字為 儲存偏好設定 6. 執行程式, 看看是否可以正常顯示介面佈局檔的內容 第 2 項 建立主程式的內容 - 儲存偏好設定 1. 請開啟主程式, 進行 et01 et02 bt01 等物件的宣告 物件的實體建立, 並且將 bt01 設定傾聽程式, 參考程式碼如下 : public class MainActivity extends Activity { EditText et01; EditText et02; Button bt01; public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); setupview(); private void setupview() { Android 講義 v0.8 1 王振民

et01 = (EditText) findviewbyid(r.id.et01); et02 = (EditText) findviewbyid(r.id.et02); bt01 = (Button) findviewbyid(r.id.bt01); bt01.setonclicklistener(bt01click); { Button.OnClickListener bt01click = new Button.OnClickListener() public void onclick(view v) { ; 2. 在 bt01click 方法裡輸入相關程式, 參考範例程式如下 : { Button.OnClickListener bt01click = new Button.OnClickListener() public void onclick(view v) { // 將資料儲存到 SharedPreferences 的 sp01 物件. SharedPreferences sp01 = getsharedpreferences("t04shareprefs", 0); sp01.edit().putstring("et01text", et01.gettext().tostring()).putstring("et02text", et02.gettext().tostring()).commit(); // 顯示一個 Toast, 一秒鐘. Toast.makeText(getApplicationContext(), " 資料儲存完成 ", Toast.LENGTH_SHORT).show(); ; 3. 執行程式, 在二個欄位裡輸入資料, 再按一下 bt01, 使系統觸發事件, 執行 bt01click 的動作 Android 講義 v0.8 2 王振民

第 3 項 驗證儲存偏好的動作 前項動作執行後, 我們可以驗證看看 驗證動作如下 : 1. 開啟命令提示字元 2. 執行 adb shell 如果沒有執行 顯示找不到命令的話, 表示系統的 path 路徑沒有指定到 adb 的位置 adb 的程式是放在 android-sdk 目錄下的 platform-tools 的目錄裡, 可以手動切換路徑 也可以考慮將它的路徑加入到 path 環境變數裡 3. 進入到 adb shell 後, 可以執行 ls -l 顯示目錄裡的內容, 使用 cd 執行切換工作目錄 以我的例子來看, 我需要先執行 cd /data/data, 在這裡就會看到系統所安裝的所有資料夾, 一個程式會有一個資料夾, 資料夾的名稱就是 package name 4. 我的 package name 是 com.example.t04sharepreference, 因此, 我就需要再輸入 cd com.example.t04sharepreference, 再使用 ls -l 顯示目錄裡的內容, 會看到有一個 shared_prefs 目錄, 裡頭有一個 t04shareprefs.xml 的檔案, 這個檔案就是我們所儲存的偏好設定, 它是一個標準 xml 格式的檔案 5. 我們可以執行 cat t04shareprefs.xml 看看裡頭的內容, 其實就是我們在 android 的程式裡所輸入的內容 第 4 項 建立主程式的內容 - 提取偏好設定 我們會希望程式每次執行時, 都能先將前次所儲存的偏好設定, 主動的讀取 出來, 程式撰寫的動作如下 : 1. 我們在 findview 方法裡, 呼叫一個 loadsharedprefs 的方法, 參考程式 碼如下 : private void setupview() { et01 = (EditText) findviewbyid(r.id.et01); et02 = (EditText) findviewbyid(r.id.et02); bt01 = (Button) findviewbyid(r.id.bt01); bt01.setonclicklistener(bt01click); loadsharedprefs(); Android 講義 v0.8 3 王振民

private void loadsharedprefs() { 2. 在 loadsharedprefs 方法裡, 使用 private void loadsharedprefs() { /** * 第 1 個參數設定我們的偏好設定的檔案名稱是 t04shareprefs, * 第 2 個參數表示只允許程式本身開啟, 不允許其它程式使用. */ SharedPreferences sp01 = getsharedpreferences("t04shareprefs", 0); /** * 取得之前儲存的資料, 如果沒有的話, 預設傳回 " 請輸入資料 " 的字串 * 這裡為了簡單及方便理解, 因此另外宣告二個字串變數儲存資料 */ String s01 = sp01.getstring("et01text", " 請輸入資料 "); String s02 = sp01.getstring("et02text", " 請輸入資料 "); et01.settext(s01.tostring()); et02.settext(s02.tostring()); 3. 請先離開程式, 再重新執行程式, 應該會發現前次輸入的資料會自動填 入到 et01 與 et02 的欄位裡 練習題 : 目前的偏好設定儲存, 必須按下 儲存偏好設定 的按鈕, 才會有作用, 請將程式修改, 當使用者直接離開程式時, 也能由程式將資料儲存後再離開程式 Android 講義 v0.8 4 王振民

第 2 節 簡單使用 SQLite 我們要使用 SQLite 的話, 需要使用 SQLiteOpenHelper 以及 SQLiteDatabase 這二個類別來建立 以及存取資料庫, 其中的 SQLiteOpenHelper 是一個幫助類別 (Helper Class), SQLiteOpenHelper 主要的目的是協助我們建立資料表, 以及資料庫的版本管理, 因此, 我們需要建立一個繼承自 SQLiteOpenHelper 的類別 由 SQLiteOpenHelper 所建立出來的資料庫, 是一個 SQLiteDatabase 類別的物件, 因此, 我們可以透過 SQLiteDatabase 所提供的方法該行新增 刪除 更新資料表的內容 以下請建立新專案, 再依照底下的動作進行 第 1 項 介面佈局檔 1. 建立一個 TextView, 顯示文字為 只存記事本 2. 建立一個 EditText, 設定 id 為 et01, 顯示文字為空的 3. 建立一個 Button, 設定 id 為 bt01, 顯示文字為 儲存記事 4. 建立一個 TextView, 設定 id 為 tv01 第 2 項 建立 SQLiteOpenHelper 的子類別 1. 在 src / 套件名稱 按 右鍵 / New / Class 2. 在 Name 的欄位輸入 mydbhelper, 做為類別的名稱 3. 按 Superclass 右方的 Browse... 4. 在上方的 Choose a type 欄位輸入 SQLiteOpenHelper, 底下的 Matching items 會顯示符合的項目, 點選該項目, 按 OK 5. 按 Finish, 建立類別, 同時, 依系統的建議, 修正錯誤的訊息 6. 目前為止, 程式碼類似以下內容 : public class mydbhelper extends SQLiteOpenHelper { public dbhelper(context context, String name, CursorFactory factory, int version) { super(context, name, factory, version); // TODO Auto-generated constructor stub public void oncreate(sqlitedatabase arg0) { Android 講義 v0.8 5 王振民

{ public void onupgrade(sqlitedatabase arg0, int arg1, int arg2) 7. 修改 oncreate() 的方法 ( 也就是覆寫父類別的方法 ), 我們要建立自己要 使用的資料表, 程式碼參考如下, 其中的 arg0 是系統在 oncreate 方法裡自行宣告的一個 SQLiteDatabase 物件, 我是直接使用這個名稱, 也可以修改物件的名稱 ( 例如改為 db), 使物件名稱比較具有意義 : public void oncreate(sqlitedatabase arg0) { arg0.execsql( "Create Table t05note (" + "_id integer primary key autoincrement, " + "tnote text)" ); 8. 修改 onupgrade 方法, 內容參考如下 : { public void onupgrade(sqlitedatabase arg0, int arg1, int arg2) arg0.execsql("drop Table if exists t05note"); oncreate(arg0); 9. 這個檔案完成了 Android 講義 v0.8 6 王振民

第 3 項 修改主程式 1. 宣告各個物件 以及建立 findview 方法, 參考如下 : public class MainActivity extends Activity { SQLiteDatabase db01; mydbhelper dbhelper01; String databasetable = "t05note"; EditText et01; TextView tv01; Button bt01; public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); setupview(); private void setupview() { 2. 建立 findview 方法裡的各個物件的實體, 參考程式碼如下 : private void setupview() { et01 = (EditText) findviewbyid(r.id.et01); tv01 = (TextView) findviewbyid(r.id.tv01); bt01 = (Button) findviewbyid(r.id.bt01); dbhelper01 = new mydbhelper(this, databasetable, null, 1); db01 = dbhelper01.getwritabledatabase(); 3. 執行程式看看, 應該能正常執行, 而且, 我們可以開啟命令提示字元視 窗, 驗證看看資料庫是否己經建立完成, 指令參考如下 : A. 執行 adb shell 進入 android 的模擬器的系統 B. 再執行 cd /data/data/ C. 輸入 ls -l 查看應該有一個和 package name 相同的目錄, 以我的 為例, 我會看到 com.example.t05sqlite 的目錄 Android 講義 v0.8 7 王振民

D. 執行 cd com.example.t05sqlite, 再輸入 ls -l 查看, 應該會產 生一個 databases 的資料夾, 而且, 裡頭會有個 t05note 的 檔案 E. 看到有 databases 的資料夾, 而且裡頭有個 t05note 的檔案, 就表示有呼叫 SQLite 建立資料庫, 也建立好了資料表 4. 在程式碼的空白處按 右鍵 / Source / Override/Implement Methods, 勾選 onstop(), 按 OK 5. 在 onstop 的方法裡, 我們要關閉資料庫, 釋放資源, 參考程式碼如下 : protected void onstop() { super.onstop(); db01.close(); 6. 建立 bt01click 事件, 參考如下 : private void setupview() { et01 = (EditText) findviewbyid(r.id.et01); tv01 = (TextView) findviewbyid(r.id.tv01); bt01 = (Button) findviewbyid(r.id.bt01); dbhelper01 = new mydbhelper(this, databasetable, null, 1); db01 = dbhelper01.getwritabledatabase(); bt01.setonclicklistener(bt01click); { Button.OnClickListener bt01click = new Button.OnClickListener() public void onclick(view v) { ; 7. 建立 bt01click 裡的 onclick 事件, 參考如下 : { Button.OnClickListener bt01click = new Button.OnClickListener() Android 講義 v0.8 8 王振民

public void onclick(view v) { long id; ContentValues cv01 = new ContentValues(); cv01.put("tnote", et01.gettext().tostring()); id = db01.insert(databasetable, null, cv01); Toast.makeText(getApplicationContext(), " 記錄新增完成 :" + id, Toast.LENGTH_SHORT).show(); ; 8. 執行程式, 輸入一些文字, 再按 儲存記事, 應該會顯示 記錄新增 完成 : x 的 toast 第 4 項 驗證看看 -sqlite3 指令 前項動作, 我們使用命令提示字元模式, 查看 databases 目錄與 t05note 檔 案, 從這個狀態可以再做更細的驗證動作, 請依以下動作操作 : 1. 輸入 sqlite3 t05note, 會進入 sqlite 的命令提示的環境 2. 畫面顯示, 可以輸入.help 取得一些協助, 試試看 3. 輸入.databases, 可以查看我們目前取用的資料庫 4. 輸入.tables, 可以得知我們目前有那些資料表 5. 一般的 sql 指令, 例如新增 刪除, 在這裡是可以通用的, 例如輸入 select * from t05note;, 就可以顯示所有記錄 6. 輸入.quit 可以離開 sqlite3 的命令提示環境 第 5 項 顯示資料表內容 1. 在 findview 方法裡, 呼叫 showtables 方法, 參考如下 : private void setupview() { et01 = (EditText) findviewbyid(r.id.et01); tv01 = (TextView) findviewbyid(r.id.tv01); bt01 = (Button) findviewbyid(r.id.bt01); dbhelper01 = new mydbhelper(this, databasetable, null, 1); db01 = dbhelper01.getwritabledatabase(); Android 講義 v0.8 9 王振民

bt01.setonclicklistener(bt01click); showtables(); private void showtables() { 2. 建立 showtables 方法裡的程式碼, 參考如下 : private void showtables() { String[] colnames = new String[] {"_id", "tnote"; String s01 = ""; Cursor c01 = db01.query(databasetable, colnames, null, null, null, null, null); for (int i=0; i<colnames.length; i++) { s01 = s01 + colnames[i] + "\t"; s01 = s01 + "\n"; c01.movetofirst(); for (int i=0; i<c01.getcount(); i++) { // s01 = s01 + c01.getstring( c01.getcolumnindex( colnames[0] ) ) + "\t"; s01 = s01 + c01.getstring(0) + "\t"; s01 = s01 + c01.getstring(1) + "\n"; c01.movetonext(); tv01.settext(s01.tostring()); 3. 執行程式看看, 應該可以列出所有的記錄 Android 講義 v0.8 10 王振民

第 2 章 專案猜數字比大小 這個程式是個簡單的遊戲, 目要是由電腦亂數產生一個 1~99 之間的數字, 由我們來猜猜這個數字是多少, 我們猜數字時, 電腦會回應我們, 要再大一些, 或者是再小一些, 藉此提示我們猜到最後的那個數字 第 1 節 建立專案 為 a01 請依前面介紹的動作, 建立一個新的 Android 專案, 專案名稱就隨便設定 第 1 項 建立介面佈局檔 我們使用最基本的介面就可以, 建立以下幾個元件 : 1. 一個輸入文字框 (EditText), 提供使用者可以輸入數字 2. 一個按鈕 (Button), 在前一個 EditText 欄位輸入數字之後, 按下按鈕, 由 系統判斷數是否正確, 或者是顯示提示文字 3. 三個文字顯示框 (TextView), 輔助使用者測猜數字使用, 一個要顯示使 用者猜測數字區間的最小值, 另一個是顯示最大值, 另一個顯示是否猜 中數字 參考如下 : <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:gravity="center_horizontal" android:orientation="vertical" > <EditText android:id="@+id/et01" android:layout_width="match_parent" android:layout_height="wrap_content" android:inputtype="number" android:text="50" android:textsize="20sp" /> <Button android:id="@+id/bt01" android:layout_width="match_parent" android:layout_height="wrap_content" Android 講義 v0.8 11 王振民

android:text=" 比大小 " /> android:id="@+id/tv01" android:layout_width="match_parent" android:layout_height="wrap_content" android:text=" 最小值 " android:textsize="20sp" /> android:id="@+id/tv02" android:layout_width="match_parent" android:layout_height="wrap_content" android:text=" 最大值 " android:textsize="20sp" /> android:id="@+id/tv03" android:layout_width="match_parent" android:layout_height="wrap_content" android:text=" 繼續加油 " android:textsize="20sp" /> </LinearLayout> 第 2 項 主程式 參考如下 : package tw.a01; import android.app.activity; import android.os.bundle; import android.view.view; import android.widget.button; import android.widget.edittext; import android.widget.textview; public class A01GuessNumber extends Activity { EditText et01; Button bt01; TextView tv01; TextView tv02; TextView tv03; Integer pcnum; Android 講義 v0.8 12 王振民

Integer a02=0; // 計算猜了幾次 public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.mainguessnumber); setupviewcomponent(); private void setupviewcomponent() { et01 = (EditText) findviewbyid(r.id.et01); bt01 = (Button) findviewbyid(r.id.bt01); tv01 = (TextView) findviewbyid(r.id.tv01); tv02 = (TextView) findviewbyid(r.id.tv02); tv03 = (TextView) findviewbyid(r.id.tv03); pcnum=(int) (Math.random()*99+1); // tv03.settext(tv03.gettext() + pcnum.tostring()); tv01.settext("0"); tv02.settext("100"); bt01.setonclicklistener(bt01click); { Button.OnClickListener bt01click = new Button.OnClickListener() public void onclick(view v) { int a01; String s01=""; a02=a02+1; a01=integer.parseint(et01.gettext().tostring()); if (a01>pcnum) { s01=" 再小一些 "; tv02.settext(et01.gettext().tostring()); else if (a01<pcnum) { s01=" 再大一些 "; tv01.settext(et01.gettext().tostring()); else if (a01==pcnum) { Android 講義 v0.8 13 王振民

次!!"; s01=" 恭禧你猜到了 ~~ 總共猜了 " + a02 + " 次! 再重玩一 a02=0; setupviewcomponent(); tv03.settext(s01); ; Android 講義 v0.8 14 王振民

第 3 章 專案建立 WebView 程式 請先安裝好 Android 的開發環境, 建立一個專案, 接下來看看我們使用簡單 的 WebView 就能建立一個很實用的程式哦! 第 1 節 修改 AndroidManifest.xml 檔案 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="tw.idv.kingbig.browserintent" android:versioncode="1" android:versionname="1.0" > <uses-sdk android:minsdkversion="7" /> <uses-permission android:name="android.permission.internet" /> <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" > <activity android:label="@string/app_name" android:name=".browserintentactivity" > <intent-filter > <action android:name="android.intent.action.main" /> <category android:name="android.intent.category.launcher" /> </intent-filter> </activity> <activity android:name=".golink01" android:label="@string/app_name_link01"> </activity> <activity android:name=".golink02" android:label="@string/app_name_link02"> </activity> </application> Android 講義 v0.8 15 王振民

</manifest> 第 2 節 修改 main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <Button android:id="@+id/golink01_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text=" 文字 1" /> <Button android:id="@+id/golink02_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text=" 文字 2" /> </LinearLayout> </LinearLayout> 第 3 節 建立 mainwebview.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="horizontal" > <WebView Android 講義 v0.8 16 王振民

android:id="@+id/web_view" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1.0" /> </LinearLayout> 第 1 項 建立 Activity 主程式 package tw.idv.kingbig.browserintent; import android.app.activity; import android.content.intent; import android.os.bundle; import android.view.view; import android.widget.button; public class BrowserIntentActivity extends Activity implements android.view.view.onclicklistener { /** Called when the activity is first created. */ private Button golink01button; private Button golink02button; public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.main); findviews(); private void findviews() { golink01button = (Button)findViewById(R.id.golink01_button); golink01button.setonclicklistener(this); golink02button = (Button)findViewById(R.id.golink02_button); golink02button.setonclicklistener(this); Android 講義 v0.8 17 王振民

; public void onclick(view v) { switch (v.getid()) { case R.id.golink01_button: Intent igolink01 = new Intent(this, golink01.class); startactivity(igolink01); break; case R.id.golink02_button: Intent igolink02 = new Intent(this, golink02.class); startactivity(igolink02); break; 第 2 項 建立 golink01 程式 package tw.idv.kingbig.browserintent; import android.app.activity; import android.os.bundle; import android.view.view; import android.webkit.webview; public class golink01 extends Activity implements android.view.view.onclicklistener { /** Called when the activity is first created. */ private WebView webview; public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.mainwebview); findviews(); private void findviews() { Android 講義 v0.8 18 王振民

webview=(webview) findviewbyid(r.id.web_view); openbrowser(); ; private void openbrowser() { String s01=new String("http://www.kingbig.idv.tw/indexAndroid.php?Act=2300&MP=2 4"); webview.getsettings().setjavascriptenabled(true); webview.loadurl(s01); public void onclick(view v) { Android 講義 v0.8 19 王振民

第 4 章 專案音樂播放程式 第 1 節 最陽春的音樂播放程式 第 1 項 建立空白的新專案 1. 請執行 File / New / Project, 選擇 Android / Android Application Project, 建立一個空白的專案 2. 開啟 layout 的介面佈局檔案, 建立一個按鈕, 將它命名為 bt01 ( android:id="@+id/bt01" ), 將它的顯示文字改為 播放音樂 (android:text=" 播放音樂 ") 3. 在 res 右鍵 / New / Folder, 建立一個 raw 資料夾 4. 請將一個 mp3 檔案複製到 /res/raw/ 底下, 請注意檔案名稱必須符合 res 的命名限制 第 2 項 加入 MediaPlayer 物件 1. 開啟主程式, 也許是 MainActivity.java, 一開始, 它的內容可能如下 : package com.example.t01music; import android.os.bundle;... 略 public class MainActivity extends Activity { public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); 2. 加入 MediaPlayer 物件的宣告, 請依程式的建議進行相關的 import 動 作, 如下 : Android 講義 v0.8 20 王振民

package com.example.t01music; import android.media.mediaplayer;... 略 public class MainActivity extends Activity { MediaPlayer mp01 = null; public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); 3. 宣告 mp3 的音樂物件, 如下 : package com.example.t01music; import android.media.mediaplayer;... 略 public class MainActivity extends Activity { MediaPlayer mp01 = null; int music01 = R.raw.fir02; public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); 4. 在 oncreate() 輸入 setupview(); 的敘述, 並依建議動作處理, 產生一 個 setupview() 的方法... 略 public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); setupview(); Android 講義 v0.8 21 王振民

private void setupview() { 5. 連結 mp3 檔案, 進行播放動作, 參考程式如下 :... 略 private void setupview() { mp01 = new MediaPlayer(); mp01 = MediaPlayer.create(this, music01); mp01.start(); 6. 執行程式吧 ~ 聽聽看, 是否有音樂播放出來? 第 3 項 改善一下, 離開程式時也能停止音樂的播放 剛剛我們所寫的程式, 如果還在播放的狀態, 我們就離開程式, 執行 android 的其它程式, 有沒有注意到, 音樂還在播放! 我們要改善這個狀況, 請依以下動作執行 : 1. 在程式碼的空白處按 右鍵 / Source / Override/Implement Methods 2. 在這裡找一找, 勾選 onpause(), 按 OK, 就會發現在程式碼裡頭, 多出以下的程式區塊 protected void onpause() { super.onpause(); 請加入以下二行程式 : protected void onpause() { super.onpause(); mp01.stop(); mp01.release(); Android 講義 v0.8 22 王振民

1. 再重新執行程式, 在音樂尚未播放完畢前, 離開程式, 如果音樂也就停 止播放, 表示這個動作完成了! 第 4 項 按下播放按鈕才開始播放 目前的程式, 會在執行時就直接播放音樂, 我們要修改一下, 在按下 播放 音樂 時, 才開始播放, 請依以下動作操作 : 1. 先宣告 Button 類別的 bt01 物件, 再由 R 取出相對應的資源, 指定給 bt01 物件, 再宣告 bt01 的傾聽程式, 參考如下 :... 略 public class MainActivity extends Activity { MediaPlayer mp01 = null; int music01 = R.raw.fir02; Button bt01; public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); setupview(); @SuppressLint("ParserError") private void setupview() { bt01 = (Button) findviewbyid(r.id.bt01); bt01.setonclicklistener(bt01click); mp01 = MediaPlayer.create(this, music01); mp01.start(); protected void onpause() { super.onpause(); mp01.stop(); mp01.release(); Android 講義 v0.8 23 王振民

2. 在我們使用 setonclicklistener() 宣告傾聽程式後, 會顯示錯誤訊息, 我 們必須手動輸入程式, 建立 bt01click, 請特別注意的是, 請將 bt01click 當做是一個物件, 它是經由 Button.OnClickListener 的宣告, 所產生的一 個物件, 因此, 最後的大括弧結束時, 必須再加一個 ; 結束 程式 碼參考如下 :... 略 public class MainActivity extends Activity { MediaPlayer mp01 = null; int music01 = R.raw.fir02; Button bt01;... 略 private void setupview() { bt01 = (Button) findviewbyid(r.id.bt01); bt01.setonclicklistener(bt01click); mp01 = MediaPlayer.create(this, music01); mp01.start(); { Button.OnClickListener bt01click = new Button.OnClickListener() ;... 略 3. 系統會提示我們, bt01click 的物件還需要 Add unimplemented { methods, 請依程式的建議處理, 會在 bt01click 物件裡, 再宣告 onclick() 的事件, 這個區塊的程式碼如下 : Button.OnClickListener bt01click = new Button.OnClickListener() public void onclick(view v) { ; Android 講義 v0.8 24 王振民

4. 將 mp01 指定物件與 mp01 播放的二行程式, 移到 bt01click 的 onclick() 方法裡, 同時, 再稍微修改一下程式, 主要是將 MediaPlayer.create(this, music01) 改為 MediaPlayer.create(getApplicationContext(), music01), 將 this 改為 getapplicationcontext() 的原因, 是原本的 MediaPlayer.create() 方法, 是在主要的 Activity 裡執行, 因此只要使用 this 關鍵字就可以取得 這個 Activity 的物件 當我們將 MediaPlayer.create() 方法移到 bt01click 的物件時, this 所參考的物件 可能會不正確, 因此, 我們必須將它改為 getapplicationcontext() 方 法, 透過呼叫這個方法來取得我們 主要的 Activity 是那一個物件, 這 樣一來,mp01 還是可以正確的取得播放的音樂資源, 進行後續播放的 動作 程式碼參考如下 :... 略 public class MainActivity extends Activity {... 略 private void setupview() { bt01 = (Button) findviewbyid(r.id.bt01); bt01.setonclicklistener(bt01click);... 略 Button.OnClickListener bt01click = new Button.OnClickListener() { public void onclick(view v) { mp01 = MediaPlayer.create( getapplicationcontext(), music01); mp01.start(); ; 5. 執行程式試試看, 程式執行後, 必須等我們按 播放音樂 的按鈕後, 才會有音樂囉! 練習題 1: 目前有 播放音樂 的按鈕, 請自行建立 停止播放 的按鈕, 而且, 在按下 停止播放 按鈕時, 要能停止音樂的播放動作 練習題 2: 試試看, 建立一個 暫停 / 播放 的按鈕, 按一下可以暫停音樂的播放, 再按一下, 可以繼續音樂的播放 Android 講義 v0.8 25 王振民

第 5 章 專案 2048 遊戲 2048 這套遊戲不論在網頁版 或者是 android 版, 都非常盛行 因此, 我們自己來寫一個, 當做專案開發的練習吧! 首先, 請先參考 建立第一個 android 程式 的章節內容, 先建立新的 android 專案, 在這個章節裡, 我以 math2048 做為專案名稱, 以 tw.idv.kingbig.android.math2048 做為 package name 第 1 節 遊戲介紹 第 1 項 玩法 Android 講義 v0.8 26 王振民

第 2 項 程式運作概念 假設目前的狀況, 如果方向是向左滑 0 2 0 2 2 0 4 0 2 0 2 4 0 0 0 2 先將所有數字靠邊 2 2 0 0 2 4 0 0 2 2 4 0 2 0 0 0 數字相同相加 4 0 0 0 2 4 0 0 4 4 0 0 2 0 0 0 以下說明詳細的運作方式, 我們以 step by step 的方式解說 假設目前的狀況, 第一列為 01, 02, 03, 04, 第二列為 05, 06, 07, 08, 其餘依 序類推 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 承前面所述, 我們以底下這個例子來說明 0 2 0 2 2 0 4 0 2 0 2 4 0 0 0 2 Android 講義 v0.8 27 王振民

由上圖來看, 第 01 格是 0, 將 02-04 格向左移 2 0 2 0 2 0 4 0 2 0 2 4 0 0 0 2 從上圖來看, 第 02 格是 0, 將 03-04 格向左移 2 2 0 0 2 0 4 0 2 0 2 4 0 0 0 2 從上圖來看, 第 03 格是 0, 將 04 格向左移, 第一列第一次判斷完成, 其 餘動作暫時跳過, 第四列再說明 2 2 0 0 2 0 4 0 2 0 2 4 0 0 0 2 第二列的流程如前所述, 結果如下 2 2 0 0 2 4 0 0 2 0 2 4 0 0 0 2 第三列的流程亦同, 結果如下 2 2 0 0 2 4 0 0 2 2 4 0 0 0 0 2 從上圖來看, 第四列, 第 13 格是 0, 將 14-16 向左移 2 2 0 0 2 4 0 0 2 2 4 0 0 0 2 0 Android 講義 v0.8 28 王振民

從上圖來看, 第四列, 第 14 格是 0, 將 15-16 向左移 2 2 0 0 2 4 0 0 2 2 4 0 0 2 0 0 從上圖來看, 第四列, 第 15 格是 0, 將 16 向左移 2 2 0 0 2 4 0 0 2 2 4 0 0 2 0 0 從上圖來看, 最前方還有個 0, 並未完全消除, 因此, 數字並未完全移到 最邊緣 2 2 0 0 2 4 0 0 2 2 4 0 0 2 0 0 因此, 判斷是 0, 同時移動資料的動作不能只做一次, 至少要做二次, 最 後結果如下 2 2 0 0 2 4 0 0 2 2 4 0 2 0 0 0 第 2 節 介面佈局檔 第 1 項 說明 程式初期, 我們先用 TextView 元件顯示數字, 而且, 我以 LinearLayout 做為介面佈局的方式, 以一個垂直方向的 LinearLayout 為主, 在其中加入數個水平方向的 LinearLayout, 做為子容器, 再將 TextView 放在子容器裡 等整個程式趨近完整時, 我們再回來調整這部份, 加入更多的視覺效果 同時, 先建立四個 Button, 分別做為上 下 左 右的四個方向, 當程式趨近完整後, 我們再加入手勢, 移除 Button Android 講義 v0.8 29 王振民

第 2 項 原始碼 以下為介面佈局檔的原始碼 其中, 每一個 TextView 的寬度和高度, 我都是先依裝置的螢幕解析度來設定的, 不見得適用於你的螢幕, 因此請依你的設備自行調整 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:paddingbottom="@dimen/activity_vertical_margin" android:paddingleft="@dimen/activity_horizontal_margin" android:paddingright="@dimen/activity_horizontal_margin" android:paddingtop="@dimen/activity_vertical_margin" tools:context="tw.idv.kingbig.android.math2048.mainactivity$plac eholderfragment" > android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_world" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > android:id="@+id/tv01" android:layout_width="80dp" android:layout_height="80dp" android:gravity="center" android:text="textview" android:textsize="20dp" /> android:id="@+id/tv02" android:layout_width="80dp" android:layout_height="80dp" android:gravity="center" android:text="textview" android:textsize="20dp" /> Android 講義 v0.8 30 王振民

android:id="@+id/tv03" android:layout_width="80dp" android:layout_height="80dp" android:gravity="center" android:text="textview" android:textsize="20dp" /> android:id="@+id/tv04" android:layout_width="80dp" android:layout_height="80dp" android:gravity="center" android:text="textview" android:textsize="20dp" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > android:id="@+id/tv05" android:layout_width="80dp" android:layout_height="80dp" android:gravity="center" android:text="textview" android:textsize="20dp" /> android:id="@+id/tv06" android:layout_width="80dp" android:layout_height="80dp" android:gravity="center" android:text="textview" android:textsize="20dp" /> android:id="@+id/tv07" android:layout_width="80dp" android:layout_height="80dp" android:gravity="center" android:text="textview" android:textsize="20dp" /> android:id="@+id/tv08" android:layout_width="80dp" android:layout_height="80dp" Android 講義 v0.8 31 王振民

android:gravity="center" android:text="textview" android:textsize="20dp" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > android:id="@+id/tv09" android:layout_width="80dp" android:layout_height="80dp" android:gravity="center" android:text="textview" android:textsize="20dp" /> android:id="@+id/tv10" android:layout_width="80dp" android:layout_height="80dp" android:gravity="center" android:text="textview" android:textsize="20dp" /> android:id="@+id/tv11" android:layout_width="80dp" android:layout_height="80dp" android:gravity="center" android:text="textview" android:textsize="20dp" /> android:id="@+id/tv12" android:layout_width="80dp" android:layout_height="80dp" android:gravity="center" android:text="textview" android:textsize="20dp" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > Android 講義 v0.8 32 王振民

android:id="@+id/tv13" android:layout_width="80dp" android:layout_height="80dp" android:gravity="center" android:text="textview" android:textsize="20dp" /> android:id="@+id/tv14" android:layout_width="80dp" android:layout_height="80dp" android:gravity="center" android:text="textview" android:textsize="20dp" /> android:id="@+id/tv15" android:layout_width="80dp" android:layout_height="80dp" android:gravity="center" android:text="textview" android:textsize="20dp" /> android:id="@+id/tv16" android:layout_width="80dp" android:layout_height="80dp" android:gravity="center" android:text="textview" android:textsize="20dp" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:orientation="horizontal" > <Button android:id="@+id/btup" android:layout_width="80dp" android:layout_height="40dp" android:gravity="center" android:text="up" android:textsize="12dp" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" Android 講義 v0.8 33 王振民

android:layout_height="wrap_content" android:gravity="center" android:orientation="horizontal" > <Button android:id="@+id/btleft" android:layout_width="80dp" android:layout_height="40dp" android:gravity="center" android:text="left" android:textsize="12dp" /> <Button android:id="@+id/btdown" android:layout_width="80dp" android:layout_height="40dp" android:gravity="center" android:text="down" android:textsize="12dp" /> <Button android:id="@+id/btright" android:layout_width="80dp" android:layout_height="40dp" android:gravity="center" android:text="right" android:textsize="12dp" /> </LinearLayout> </LinearLayout> 第 3 節 主程式開發 前項的介面佈局檔完成後, 就可以點選 MainActivity.java 檔案, 執行程式, 看看顯示出來的視窗是否正確 第 1 項 主程式 - 基本設定 首先, 先宣告基本的元件 package tw.idv.kingbig.android.math2048; 略 Android 講義 v0.8 34 王振民

public class MainActivity extends Activity { int num = 16; TextView tv01, tv02, tv03, tv04, tv05, tv06, tv07, tv08, tv09, tv10, tv11, tv12, tv13, tv14, tv15, tv16; Button btup, btleft, btdown, btright; int[] pcnum = new int[num + 1]; protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); if (savedinstancestate == null) { getfragmentmanager().begintransaction().add(r.id.container, new PlaceholderFragment()).commit(); protected void onresume() { super.onresume(); setupview(); private void setupview() { public boolean oncreateoptionsmenu(menu menu) { 略 public boolean onoptionsitemselected(menuitem item) { 略 /** * A placeholder fragment containing a simple view. */ public static class PlaceholderFragment extends Fragment { Android 講義 v0.8 35 王振民

略 將宣告的元作, 和 Layout 檔案裡的元件連結在一起 private void setupview() { tv01 = (TextView) findviewbyid(r.id.tv01); tv02 = (TextView) findviewbyid(r.id.tv02); tv03 = (TextView) findviewbyid(r.id.tv03); tv04 = (TextView) findviewbyid(r.id.tv04); tv05 = (TextView) findviewbyid(r.id.tv05); tv06 = (TextView) findviewbyid(r.id.tv06); tv07 = (TextView) findviewbyid(r.id.tv07); tv08 = (TextView) findviewbyid(r.id.tv08); tv09 = (TextView) findviewbyid(r.id.tv09); tv10 = (TextView) findviewbyid(r.id.tv10); tv11 = (TextView) findviewbyid(r.id.tv11); tv12 = (TextView) findviewbyid(r.id.tv12); tv13 = (TextView) findviewbyid(r.id.tv13); tv14 = (TextView) findviewbyid(r.id.tv14); tv15 = (TextView) findviewbyid(r.id.tv15); tv16 = (TextView) findviewbyid(r.id.tv16); btup = (Button) findviewbyid(r.id.btup); btdown = (Button) findviewbyid(r.id.btdown); btleft = (Button) findviewbyid(r.id.btleft); btright = (Button) findviewbyid(r.id.btright); init(); 第 2 項 主程式 - 產生亂數 各個元件的初始化, 同時產生亂數 private void init() { Android 講義 v0.8 36 王振民

for (int a01 = 0; a01 <= num; a01++) { pcnum[a01] = 0; initrandom(); shownumber(); private void initrandom() { int a01 = ((int) (Math.random() * 2 + 1)) * 2; int f01 = 0; // flag int c01 = 0; // count int a02 = 0; // position while (f01 == 0) { c01++; a02 = (int) (Math.random() * num + 1); if (pcnum[a02] == 0) { f01 = 1; pcnum[a02] = a01; // 這裡暫時先用偷懶的方式處理 if (c01 > 100) { Toast.makeText(this, "Game Over", Toast.LENGTH_LONG).show(); break; Log.d("a2048", "a01: " + a01 + ", a02: " + a02); private void shownumber() { tv01.settext(integer.tostring(pcnum[1])); tv02.settext(integer.tostring(pcnum[2])); tv03.settext(integer.tostring(pcnum[3])); tv04.settext(integer.tostring(pcnum[4])); tv05.settext(integer.tostring(pcnum[5])); tv06.settext(integer.tostring(pcnum[6])); tv07.settext(integer.tostring(pcnum[7])); Android 講義 v0.8 37 王振民

tv08.settext(integer.tostring(pcnum[8])); tv09.settext(integer.tostring(pcnum[9])); tv10.settext(integer.tostring(pcnum[10])); tv11.settext(integer.tostring(pcnum[11])); tv12.settext(integer.tostring(pcnum[12])); tv13.settext(integer.tostring(pcnum[13])); tv14.settext(integer.tostring(pcnum[14])); tv15.settext(integer.tostring(pcnum[15])); tv16.settext(integer.tostring(pcnum[16])); 第 3 項 主程式 - 數字靠邊 數字加總 宣告按鈕的傾聽程式 private void setupview() { 略 btup = (Button) findviewbyid(r.id.btup); btdown = (Button) findviewbyid(r.id.btdown); btleft = (Button) findviewbyid(r.id.btleft); btright = (Button) findviewbyid(r.id.btright); init(); btup.setonclicklistener(btupclick); btdown.setonclicklistener(btdownclick); btleft.setonclicklistener(btleftclick); btright.setonclicklistener(btrightclick); 建立各個按鈕的觸發事件 Button.OnClickListener btupclick = new Button.OnClickListener() { Android 講義 v0.8 38 王振民

public void onclick(view v) { int n01 = 0; // 目前要比對的位置 for (int i01 = 1; i01 <= 4; i01++) { n01 = 0; for (int x = 1; x <= 4; x++) { for (int i02 = 0; i02 < 3; i02++) { n01 = i01 + i02 * 4; if (pcnum[n01] == 0) { for (int i03 = n01; i03 < i01 + 3 * 4; i03 = i03 + 4) { pcnum[i03] = pcnum[i03 + 4]; pcnum[i01 + 3 * 4] = 0; for (int i02 = 0; i02 < 3; i02++) { n01 = i01 + i02 * 4; if (pcnum[n01] == pcnum[n01 + 4]) { pcnum[n01] = pcnum[n01] * 2; for (int i03 = n01 + 4; i03 < i01 + 3 * 4; i03 = i03 + 4) { pcnum[i03] = pcnum[i03 + 4]; pcnum[i01 + 3 * 4] = 0; initrandom(); shownumber(); ; Button.OnClickListener btdownclick = new Button.OnClickListener() { public void onclick(view v) { Android 講義 v0.8 39 王振民

int n01 = 0; // 目前要比對的位置 for (int i01 = 1; i01 <= 4; i01++) { - 4) { n01 = 0; for (int x = 1; x <= 4; x++) { for (int i02 = 3; i02 > 0; i02--) { n01 = i01 + i02 * 4; if (pcnum[n01] == 0) { for (int i03 = n01; i03 > i01; i03 = i03 pcnum[i03] = pcnum[i03-4]; pcnum[i01] = 0; - 4) { for (int i02 = 3; i02 > 0; i02--) { n01 = i01 + i02 * 4; if (pcnum[n01] == pcnum[n01-4]) { pcnum[n01] = pcnum[n01] * 2; for (int i03 = n01-4; i03 > i01; i03 = i03 pcnum[i03] = pcnum[i03-4]; pcnum[i01] = 0; initrandom(); shownumber(); ; Button.OnClickListener btleftclick = new Button.OnClickListener() { public void onclick(view v) { int n01 = 0; // 目前要比對的位置 for (int i01 = 0; i01 < 4; i01++) { Android 講義 v0.8 40 王振民

n01 = 0; for (int x = 1; x <= 4; x++) { for (int i02 = 1; i02 < 4; i02++) { n01 = i01 * 4 + i02; if (pcnum[n01] == 0) { for (int i03 = i01 * 4 + i02; i03 < i01 * 4 + 4; i03++) { pcnum[i03] = pcnum[i03 + 1]; pcnum[i01 * 4 + 4] = 0; for (int i02 = 1; i02 < 4; i02++) { n01 = i01 * 4 + i02; if (pcnum[n01] == pcnum[n01 + 1]) { pcnum[n01] = pcnum[n01] * 2; for (int i03 = i01 * 4 + i02 + 1; i03 < i01 * 4 + 4; i03++) { pcnum[i03] = pcnum[i03 + 1]; pcnum[i01 * 4 + 4] = 0; initrandom(); shownumber(); ; Button.OnClickListener btrightclick = new Button.OnClickListener() { public void onclick(view v) { int n01 = 0; // 目前要比對的位置 for (int i01 = 0; i01 < 4; i01++) { n01 = 0; for (int x = 1; x <= 4; x++) { for (int i02 = 4; i02 > 1; i02--) { Android 講義 v0.8 41 王振民

* 4 + 1; i03--) { n01 = i01 * 4 + i02; if (pcnum[n01] == 0) { for (int i03 = i01 * 4 + i02; i03 > i01 pcnum[i03] = pcnum[i03-1]; pcnum[i01 * 4 + 1] = 0; for (int i02 = 4; i02 > 1; i02--) { n01 = i01 * 4 + i02; if (pcnum[n01] == pcnum[n01-1]) { pcnum[n01] = pcnum[n01] * 2; for (int i03 = i01 * 4 + i02-1; i03 > i01 * 4 + 1; i03--) { pcnum[i03] = pcnum[i03-1]; pcnum[i01 * 4 + 1] = 0; initrandom(); shownumber(); ; 執行程式, 應該可以使用四個按鈕進行遊戲了 第 4 節 加入手勢 上述動作完成後, 等會要進行比較大的修改, 因此, 請先將整個專案備份一 下, 留個保障 Android 講義 v0.8 42 王振民

第 1 項 移除 Button 物件 請將介面佈局檔的四個 Button 元件移除, 包含這四個 Button 元件的容器也 可以一併移除 同時, 將 MainActivity.java 檔案內容裡, 有關 Button 的內容將它們註解或者 直接移除 : private void setupview() { 略 // btup = (Button) findviewbyid(r.id.btup); // btdown = (Button) findviewbyid(r.id.btdown); // btleft = (Button) findviewbyid(r.id.btleft); // btright = (Button) findviewbyid(r.id.btright); init(); // btup.setonclicklistener(btupclick); // btdown.setonclicklistener(btdownclick); // btleft.setonclicklistener(btleftclick); // btright.setonclicklistener(btrightclick); 將原本的 btupclick btdownclick btleftclick btrightclick 程式, 改為以下 的 method 方式 private void swiperight() { int n01 = 0; // 目前要比對的位置 略 initrandom(); shownumber(); private void swipeleft() { int n01 = 0; // 目前要比對的位置 略 Android 講義 v0.8 43 王振民

initrandom(); shownumber(); private void swipedown() { int n01 = 0; // 目前要比對的位置 略 initrandom(); shownumber(); private void swipeup() { int n01 = 0; // 目前要比對的位置 略 initrandom(); shownumber(); 第 2 項 加入手勢 public class MainActivity extends Activity { int num = 16; TextView tv01, tv02, tv03, tv04, tv05, tv06, tv07, tv08, tv09, tv10, tv11, tv12, tv13, tv14, tv15, tv16; Button btup, btleft, btdown, btright; int[] pcnum = new int[num + 1]; private GestureDetectorCompat mdetector; public final static int SWIPE_UP = 1; public final static int SWIPE_DOWN = 2; public final static int SWIPE_LEFT = 3; public final static int SWIPE_RIGHT = 4; public int SWIPE_DIRECTION = 0; 略 private void setupview() { Android 講義 v0.8 44 王振民

init(); // btup.setonclicklistener(btupclick); // btdown.setonclicklistener(btdownclick); // btleft.setonclicklistener(btleftclick); // btright.setonclicklistener(btrightclick); mdetector = new GestureDetectorCompat(this, new MyGestureListener()); 略 private void swiperight() { 略 private void swipeleft() { 略 private void swipedown() { 略 private void swipeup() { 略 public boolean ontouchevent(motionevent event) { SWIPE_DIRECTION=0; this.mdetector.ontouchevent(event); Log.d("a2048", "ontouchevent: " + SWIPE_DIRECTION); switch (SWIPE_DIRECTION) { case SWIPE_UP: swipeup(); break; case SWIPE_DOWN: swipedown(); break; case SWIPE_LEFT: Android 講義 v0.8 45 王振民

swipeleft(); break; case SWIPE_RIGHT: swiperight(); break; return super.ontouchevent(event); /** * http://developer.android.com/training/gestures/detector.html */ class MyGestureListener extends GestureDetector.SimpleOnGestureListener { private static final String DEBUG_TAG = "a2048"; private static final int SWIPE_MIN_DISTANCE = 120; private static final int SWIPE_MAX_OFF_PATH = 250; private static final int SWIPE_THRESHOLD_VELOCITY = 200; public boolean ondown(motionevent event) { // Log.d(DEBUG_TAG, "ondown: " + event.tostring()); return true; event2, public boolean onfling(motionevent event1, MotionEvent float velocityx, float velocityy) { // Log.d(DEBUG_TAG, "onfling: " + event1.tostring() + // event2.tostring()); // Log.d("a2048", "onfling"); boolean isswipe = false; SWIPE_DIRECTION = 0; try { // right to left swipe if (event1.getx() - event2.getx() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) { isswipe = true; Android 講義 v0.8 46 王振民

SWIPE_DIRECTION = 3; // left to right swipe else if (event2.getx() - event1.getx() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) { isswipe = true; SWIPE_DIRECTION = 4; // up to down swipe else if (event2.gety() - event1.gety() > SWIPE_MIN_DISTANCE && Math.abs(velocityY) > SWIPE_THRESHOLD_VELOCITY) { isswipe = true; SWIPE_DIRECTION = 2; // down to up swipe else if (event1.gety() - event2.gety() > SWIPE_MIN_DISTANCE && Math.abs(velocityY) > SWIPE_THRESHOLD_VELOCITY) { isswipe = true; SWIPE_DIRECTION = 1; catch (Exception e) { // Log.d("a2048", "xy: (" + event1.getx() + ", " + event1.gety() + // ")-(" + event2.getx() + ", " + event2.gety() + ")" ); return isswipe; 完成! Android 講義 v0.8 47 王振民

第 6 章 專案 GPS 服務 這個程式範例, 在 Android 2.1 的環境就可以正常執行, 不過, 這個專案裡我們先用簡單的方式來完成 GPS 的服務, 比較進階而完整的方式, 容後再做 第 1 項 設定 manifest 的使用授權項目 請開啟 AndroidManifest.xml 檔案, 請加入以下四行 users-permission 這四行 uses-permission 分別代表允許取得 GPS 的精細座標位置 允許使用者所輸入的模擬位置 允許使用 3g 或 wifi 的方式取得的概略位置 允許存取網際網路 前三項的 uses-permission 是抓取座標位置要用的, 而第四項則是要由網路傳回 Google Maps 時, 會需要使用網路連線 傳回資料 <uses-sdk android:minsdkversion="7" android:targetsdkversion="7" /> <uses-permission android:name="android.permission.access_fine_location" /> <uses-permission android:name="android.permission.access_mock_location" /> <uses-permission android:name="android.permission.access_coarse_location" /> <uses-permission android:name="android.permission.internet" /> 這個檔案還有其他的設定要做, 等稍後我們再回來這裡設定, 目前暫時先設 定這四項使用授權即可 記得存檔 Android 講義 v0.8 48 王振民

第 2 項 建立介面佈局檔 1. 請先開啟介面佈局檔, 拖拉元件如下圖 : 2. 直接瀏覽 xml 檔案的話, 參考內容如下 : <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="fill_parent" android:layout_height="fill_parent" > android:id="@+id/txtlabel01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignparentleft="true" android:layout_alignparenttop="true" android:text=" 緯度 :" tools:context=".mainactivity" /> android:id="@+id/txttext01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignparenttop="true" Android 講義 v0.8 49 王振民

android:layout_torightof="@+id/txtlabel01" android:text="textview" /> android:id="@+id/txtlabel02" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignparentleft="true" android:layout_below="@+id/txtlabel01" android:text=" 經度 :" /> android:id="@+id/txttext02" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignbaseline="@+id/txtlabel02" android:layout_alignbottom="@+id/txtlabel02" android:layout_torightof="@+id/txtlabel02" android:text="textview" /> android:id="@+id/txtlabel03" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignparentleft="true" android:layout_below="@+id/txtlabel02" android:text=" 精確度 :" /> android:id="@+id/txttext03" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignbaseline="@+id/txtlabel03" android:layout_alignbottom="@+id/txtlabel03" android:layout_torightof="@+id/txtlabel03" android:text="textview" /> android:id="@+id/txtlabel04" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignparentleft="true" android:layout_below="@+id/txtlabel03" android:text=" 高度 :" /> android:id="@+id/txttext04" android:layout_width="wrap_content" android:layout_height="wrap_content" Android 講義 v0.8 50 王振民

android:layout_alignbaseline="@+id/txtlabel04" android:layout_alignbottom="@+id/txtlabel04" android:layout_torightof="@+id/txtlabel04" android:text="textview" /> android:id="@+id/txtlabel05" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignparentleft="true" android:layout_below="@+id/txtlabel04" android:text=" 時間 :" /> android:id="@+id/txttext05" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignbaseline="@+id/txtlabel05" android:layout_alignbottom="@+id/txtlabel05" android:layout_torightof="@+id/txtlabel05" android:text="textview" /> android:id="@+id/txtlabel06" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignparentleft="true" android:layout_below="@+id/txtlabel05" android:text=" 速度 :" /> android:id="@+id/txttext06" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignbaseline="@+id/txtlabel06" android:layout_alignbottom="@+id/txtlabel06" android:layout_torightof="@+id/txtlabel06" android:text="textview" /> android:id="@+id/txtlabel07" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignparentleft="true" android:layout_below="@+id/txtlabel06" android:text=" 方位 :" /> android:id="@+id/txttext07" Android 講義 v0.8 51 王振民

android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignbaseline="@+id/txtlabel07" android:layout_alignbottom="@+id/txtlabel07" android:layout_torightof="@+id/txtlabel07" android:text="textview" /> <Button android:id="@+id/btnhistorylist" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignparentleft="true" android:layout_below="@+id/txtlabel07" android:text=" 歷史記錄 " /> <WebView android:id="@+id/webview1" android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_alignparentleft="true" android:layout_alignparentright="true" android:layout_below="@+id/btnhistorylist" /> </RelativeLayout> 第 3 項 建立連結資料庫的 dbhelper public class mydbhelper extends SQLiteOpenHelper { public mydbhelper(context context, String name, CursorFactory factory, int version) { super(context, name, factory, version); // TODO Auto-generated constructor stub public void oncreate(sqlitedatabase arg0) { // 這個是資料表的結構 // 其中的 gtdate datetime 有問題, 請暫時忽略 arg0.execsql( "create table gpstracer (" + "_id integer primary key autoincrement, " + Android 講義 v0.8 52 王振民

")" ); "gtdate datetime, " + "gtlatitude long, " + "gtlongitude long, " + "gtaccuracy long, " + "gtaltitude long, " + "gttime long, " + "gtspeed long, " + "gtbearing long" + { public void onupgrade(sqlitedatabase arg0, int arg1, int arg2) arg0.execsql("drop table if exists gpstracer"); oncreate(arg0); 第 4 項 建立主程式 public class MainActivity extends Activity { TextView txtlabel01; TextView txtlabel02; TextView txtlabel03; TextView txtlabel04; TextView txtlabel05; TextView txtlabel06; TextView txtlabel07; TextView txttext01; TextView txttext02; TextView txttext03; TextView txttext04; TextView txttext05; TextView txttext06; TextView txttext07; Button btnhistorylist; WebView wv01; // 宣告資料庫相關的物件 Android 講義 v0.8 53 王振民

mydbhelper dbhelper01; // 使用繼承自 SQLiteOpenHelper 類別所產生的物件, 協助我們建立資料庫連結的動作 SQLiteDatabase gpstracerdb; // 連結資料庫進行查詢 新增資料的動作 String databasetable = "gpstracer"; // 宣告資料表的名稱, 這行可以不用 LocationManager lm01; // 宣告一個 LocationManager 類別的 lm01 物件 // 宣告一個 LocationListener 類別的 lm01listener 物件, // 在 new LocationListener() 產生物件時, 會同時建立其中的幾個 method public LocationListener lm01listener = new LocationListener() { //gps 的狀態改變時, 會呼叫這個 method public void onstatuschanged(string provider, int status, Bundle extras) { switch (status) { case LocationProvider.AVAILABLE: Log.v("status", "AVAILABLE"); break; case LocationProvider.OUT_OF_SERVICE: Log.v("status", "OUT_OF_SERVICE"); break; case LocationProvider.TEMPORARILY_UNAVAILABLE: Log.v("status", "TEMPORARILY_UNAVAILABLE"); break; public void onproviderenabled(string provider) { public void onproviderdisabled(string provider) { // 當座標改變時, 會呼叫這個 method public void onlocationchanged(location location) { Android 講義 v0.8 54 王振民

txttext01.settext(string.valueof(location.getlatitude())); txttext02.settext(string.valueof(location.getlongitude())); txttext03.settext(string.valueof(location.getaccuracy())); txttext04.settext(string.valueof(location.getaltitude())); txttext05.settext(string.valueof(location.gettime())); txttext06.settext(string.valueof(location.getspeed())); txttext07.settext(string.valueof(location.getbearing())); wv01.loadurl("http://maps.google.com/maps/api/staticmap?cente r=" + Double.toString(location.getLatitude()) +"," + Double.toString(location.getLongitude()) + "&zoom=16&size="+ "360x400&sensor=false&markers=color:blue%7Clabel:S%7C"+ Double.toString(location.getLatitude())+ "," + Double.toString(location.getLongitude())); // 以下動作是要將資料存到資料庫 long id; // 使用 ContentValues 以陣列 key-value 的方式儲存, // 其中的 key 就是欄位名稱,value 就是儲存的值 ( 要轉換為字串 ) ContentValues cv01 = new ContentValues(); cv01.put("gtdate", "current_timestamp"); cv01.put("gtlatitude", String.valueOf(location.getLatitude())); cv01.put("gtlongitude", String.valueOf(location.getLongitude())); cv01.put("gtaccuracy", String.valueOf(location.getAccuracy())); cv01.put("gtaltitude", String.valueOf(location.getAltitude())); cv01.put("gttime", String.valueOf(location.getTime())); cv01.put("gtspeed", String.valueOf(location.getSpeed())); cv01.put("gtbearing", String.valueOf(location.getBearing())); // 進行 insert 到資料表的動作 id=gpstracerdb.insert(databasetable, null, cv01); Android 講義 v0.8 55 王振民

Toast.makeText(getApplicationContext(), " 記錄新增完成 :" + id, Toast.LENGTH_SHORT).show(); ; public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); setupview(); // 自己建立的程式寫在這裡 private void setupview() { txtlabel01=(textview) findviewbyid(r.id.txtlabel01); txtlabel02=(textview) findviewbyid(r.id.txtlabel02); txtlabel03=(textview) findviewbyid(r.id.txtlabel03); txtlabel04=(textview) findviewbyid(r.id.txtlabel04); txtlabel05=(textview) findviewbyid(r.id.txtlabel05); txtlabel06=(textview) findviewbyid(r.id.txtlabel06); txtlabel07=(textview) findviewbyid(r.id.txtlabel07); txttext01=(textview) findviewbyid(r.id.txttext01); txttext02=(textview) findviewbyid(r.id.txttext02); txttext03=(textview) findviewbyid(r.id.txttext03); txttext04=(textview) findviewbyid(r.id.txttext04); txttext05=(textview) findviewbyid(r.id.txttext05); txttext06=(textview) findviewbyid(r.id.txttext06); txttext07=(textview) findviewbyid(r.id.txttext07); btnhistorylist=(button) findviewbyid(r.id.btnhistorylist); wv01=(webview) findviewbyid(r.id.webview1); // 透過 getsystemservice 去呼叫 LOCATION_SERVICE, 建立一個 LocationManager 的服務 //LOCATION_SERVICE 的完整服務是 android.content.context.location_service // 由 LOCATION_SERVICE 服務就可以取得系統提供的座標 高度 方位等各項服務 Android 講義 v0.8 56 王振民

lm01=(locationmanager) getsystemservice(location_service); // 以下動作在設定 LocationListener(lm01Listener 物件 ) 的最小變動時機, // 每 2 秒 (2000) 更新一次 // 每 5 公尺更新一次 // lm01.requestlocationupdates(locationmanager.network_provider, 2000, 5, lm01listener); lm01.requestlocationupdates(locationmanager.gps_provider, 2000, 5, lm01listener); // 連結資料庫的動作 dbhelper01 = new mydbhelper(this, databasetable, null, 1); gpstracerdb = dbhelper01.getwritabledatabase(); // 註冊一個按下歷史記錄的按鈕傾聽程式 btnhistorylist.setonclicklistener(btnhistorylistclick); // 程式如果關閉時, 要釋放 SQLiteDatabase 資源 protected void onstop() { super.onstop(); gpstracerdb.close(); // 程式如果暫停, 也要停止更新的動作 protected void onpause() { if (lm01!= null) { lm01.removeupdates(lm01listener); super.onpause(); // 程式如果由停止或暫停的狀態, 恢復為執行的狀態, // 必須要重新記錄更新的動作 protected void onresume() { Android 講義 v0.8 57 王振民

if (lm01!= null) { lm01.requestlocationupdates(locationmanager.gps_provider, 2000, 5, lm01listener); lm01.requestlocationupdates(locationmanager.network_provider, 2000, 5, lm01listener); super.onresume(); public boolean oncreateoptionsmenu(menu menu) { getmenuinflater().inflate(r.menu.activity_main, menu); return true; // 按下歷史記錄的按鈕時, 要呼叫另一個程式出來 Button.OnClickListener btnhistorylistclick = new Button.OnClickListener() { public void onclick(view arg0) { Intent i01 = new Intent(getApplication(), gpshistorylist.class); startactivity(i01); ; 第 5 項 建立第二個程式 - 佈景主題 <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" Android 講義 v0.8 58 王振民

xmlns:tools="http://schemas.android.com/tools" android:layout_width="fill_parent" android:layout_height="fill_parent" > <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="fill_parent" android:layout_height="fill_parent" > <Button android:id="@+id/btnreturn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignparentleft="true" android:layout_alignparenttop="true" android:text=" 返回 " /> android:id="@+id/txtlist01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignparentleft="true" android:layout_below="@+id/btnreturn" android:text="" /> </RelativeLayout> </ScrollView> 第 6 項 建立第二個程式 - 主程式 public class gpshistorylist extends Activity { TextView txtlist01; Button btnreturn; // 宣告資料庫相關的物件 mydbhelper dbhelper01; // 使用繼承自 SQLiteOpenHelper 類別所產生的物件, 協助我們建立資料庫連結的動作 SQLiteDatabase gpstracerdb; // 連結資料庫進行查詢 新增資料的動作 String databasetable = "gpstracer"; // 宣告資料表的名稱, 這行可以不用 public void oncreate(bundle savedinstancestate) { Android 講義 v0.8 59 王振民

super.oncreate(savedinstancestate); // 呼叫版面配置, 這裡只有一個返回鍵以及文字框 ( 顯示歷史資料使用的 ) setcontentview(r.layout.activity_gpshistorylist); setupview(); // 自己建立的程式寫在這裡 private void setupview() { txtlist01=(textview) findviewbyid(r.id.txtlist01); btnreturn=(button) findviewbyid(r.id.btnreturn); // 返回鍵, 要關閉自身的 activity btnreturn.setonclicklistener(btnreturnclick); // 連結資料庫 dbhelper01 = new mydbhelper(this, databasetable, null, 1); gpstracerdb = dbhelper01.getwritabledatabase(); String[] colnames = new String[] {"_id", "gtdate", "gtlatitude", "gtlongitude", "gtaccuracy", "gtaltitude", "gttime", "gtspeed", "gtbearing"; String s01=""; Cursor c01 = gpstracerdb.query(databasetable, colnames, null, null, null, null, "_id desc"); // 將內容以一個簡單的格式輸出 c01.movetofirst(); for (int i=0; i<c01.getcount(); i++) { s01 = s01 + "No." + c01.getstring(0) + ",\t\t\t\t"; // 顯示自動增加的編號 s01 = s01 + "Time:" + c01.getstring(6) + "\n"; // 顯示第 6 欄的日期, 換下一行 s01 = s01 + "Location:" + c01.getstring(2) + ",\t"; // 顯示經度 s01 = s01 + c01.getstring(3) + "\n"; // 顯示緯度, 換下一行 s01 = s01 + "Accuracy:" + c01.getstring(4) + ",\t"; // 顯示精確度 s01 = s01 + "Altitude:" + c01.getstring(5) + "\n"; // 顯示高度, 換下一行 s01 = s01 + "Speed:" + c01.getstring(7) + ",\t\t\t"; // 顯示速度 Android 講義 v0.8 60 王振民

s01 = s01 + "Bearing:" + c01.getstring(8) + "\n\n"; // 顯示方位 c01.movetonext(); txtlist01.settext(s01.tostring()); // 程式如果關閉時, 要釋放 SQLiteDatabase 資源 protected void onstop() { super.onstop(); gpstracerdb.close(); Button.OnClickListener btnreturnclick = new Button.OnClickListener() { public void onclick(view arg0) { finish(); ; Android 講義 v0.8 61 王振民