diff --git a/AndroidTutorial4_1Update.md b/AndroidTutorial4_1Update.md
new file mode 100755
index 0000000..c58e904
--- /dev/null
+++ b/AndroidTutorial4_1Update.md
@@ -0,0 +1,166 @@
+# 錯誤修正:4-1 使用照相機與麥克風
+
+這一章加入的照相與錄音功能,把照片與錄音檔案名稱儲存在同一個欄位。在完成這一章的內容後依照下列的步驟修正錯誤:
+
+1. 開啟「Item.java」,加入下列的欄位與方法宣告:
+
+ // 錄音檔案名稱
+ private String recFileName;
+
+ public String getRecFileName() {
+ return recFileName;
+ }
+
+ public void setRecFileName(String recFileName) {
+ this.recFileName = recFileName;
+ }
+
+2. 同樣在「Item.java」,為建構子加入錄音檔案名稱參數:
+
+ // 錄音檔案名稱參數:String recFileName
+ public Item(long id, long datetime, Colors color, String title,
+ String content, String fileName, String recFileName,
+ double latitude, double longitude, long lastModify) {
+ this.id = id;
+ this.datetime = datetime;
+ this.color = color;
+ this.title = title;
+ this.content = content;
+ this.fileName = fileName;
+ // 錄音檔案名稱
+ this.recFileName = recFileName;
+ this.latitude = latitude;
+ this.longitude = longitude;
+ this.lastModify = lastModify;
+ }
+
+3. 開啟「ItemDAO.java」,加入與修改下列的欄位宣告:
+
+ ...
+ // 錄音檔案名稱
+ public static final String RECFILENAME_COLUMN = "recfilename";
+ ...
+ // 在「FILENAME_COLUMN」下方加入錄音檔案名稱欄位
+ public static final String CREATE_TABLE =
+ "CREATE TABLE " + TABLE_NAME + " (" +
+ ...
+ FILENAME_COLUMN + " TEXT, " +
+ RECFILENAME_COLUMN + " TEXT, " + // 增加錄音檔案名稱
+ ...";
+
+4. 同樣在「ItemDAO.java」,修改「insert」方法:
+
+ public Item insert(Item item) {
+ ContentValues cv = new ContentValues();
+ ...
+ cv.put(FILENAME_COLUMN, item.getFileName());
+ // 錄音檔案名稱
+ cv.put(RECFILENAME_COLUMN, item.getRecFileName());
+ ...
+ }
+
+5. 同樣在「ItemDAO.java」,修改「update」方法:
+
+ public boolean update(Item item) {
+ ContentValues cv = new ContentValues();
+
+ ...
+ cv.put(FILENAME_COLUMN, item.getFileName());
+ // 錄音檔案名稱
+ cv.put(RECFILENAME_COLUMN, item.getRecFileName());
+ ...
+ }
+
+6. 同樣在「ItemDAO.java」,修改「getRecord」方法:
+
+ public Item getRecord(Cursor cursor) {
+ ...
+ result.setFileName(cursor.getString(5));
+ // 錄音檔案名稱
+ result.setRecFileName(cursor.getString(6));
+ // 後續的編號都要加一
+ result.setLatitude(cursor.getDouble(7));
+ ...
+ }
+
+7. 同樣在「ItemDAO.java」,修改「sample」方法:
+
+ public void sample() {
+ // 增加錄音檔案名稱參數「""」
+ Item item = new Item(0, new Date().getTime(), Colors.RED, "關於Android Tutorial的事情.", "Hello content", "", "", 0, 0, 0);
+ Item item2 = new Item(0, new Date().getTime(), Colors.BLUE, "一隻非常可愛的小狗狗!", "她的名字叫「大熱狗」,又叫\n作「奶嘴」,是一隻非常可愛\n的小狗。", "", "", 25.04719, 121.516981, 0);
+ Item item3 = new Item(0, new Date().getTime(), Colors.GREEN, "一首非常好聽的音樂!", "Hello content", "", "", 0, 0, 0);
+ Item item4 = new Item(0, new Date().getTime(), Colors.ORANGE, "儲存在資料庫的資料", "Hello content", "", "", 0, 0, 0);
+
+ ...
+ }
+
+8. 開啟「MyDBHelper.java」,增加資料庫版本編號:
+
+ // 資料庫版本,資料結構改變的時候要更改這個數字,通常是加一
+ public static final int VERSION = 2;
+
+9. 開啟「ItemActivity.java」,增加錄音檔案名稱欄位變數:
+
+ // 錄音檔案名稱
+ private String recFileName;
+
+10. 同樣在「ItemActivity.java」,增加取得錄音檔案名稱的方法:
+
+ private File configRecFileName(String prefix, String extension) {
+ // 如果記事資料已經有檔案名稱
+ if (item.getRecFileName() != null && item.getRecFileName().length() > 0) {
+ recFileName = item.getRecFileName();
+ }
+ // 產生檔案名稱
+ else {
+ recFileName = FileUtil.getUniqueFileName();
+ }
+
+ return new File(FileUtil.getExternalStorageDir(FileUtil.APP_DIR),
+ prefix + recFileName + extension);
+ }
+
+11. 同樣在「ItemActivity.java」,修改啟動錄音元件的方法:
+
+ public void clickFunction(View view) {
+ int id = view.getId();
+
+ switch (id) {
+ ...
+ case R.id.record_sound:
+ // 修改呼叫方法的名稱為「configRecFileName」
+ final File recordFile = configRecFileName("R", ".mp3");
+
+ if (recordFile.exists()) {
+ ...
+ }
+ // 如果沒有錄音檔,啟動錄音元件
+ else {
+ goToRecord(recordFile);
+ }
+
+ break;
+ ...
+ }
+
+ }
+
+12. 同樣在「ItemActivity.java」,找到「onActivityResult」方法,修改設定錄音檔案名稱呼叫的方法:
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (resultCode == Activity.RESULT_OK) {
+ switch (requestCode) {
+ ...
+ case START_RECORD:
+ // 修改設定錄音檔案名稱
+ item.setRecFileName(recFileName);
+ break;
+ ...
+ }
+ }
+ }
+
+
+完成全部的修改以後執行應用程式,測試同一個記事資料照相與錄音的功能。
diff --git a/AndroidTutorial5_Migrate.md b/AndroidTutorial5_Migrate.md
new file mode 100755
index 0000000..294e6da
--- /dev/null
+++ b/AndroidTutorial5_Migrate.md
@@ -0,0 +1,81 @@
+#從Eclipse ADT轉移到Android Studio
+CodeDate的Android Studio系列專欄,在連載的中途發表Android 5 Lollipop,還有全新的開發工具Android Studio。因為版本與開發工具的變化非常大,因此決定把系列專欄昇級為Android 5與Android Studio,專欄與範例程式專案在2015/03/02同步更新。
+
+因為之前的範例程式專案採用Eclipse ADT,如果你已經依照之前的專欄撰寫應用程式,可以考慮將它轉移到Android Studio,再繼續依照後續的專欄學習全新的Android Studio。
+
+依照下列的步驟執行轉移的工作:
+
+1. 依照 的說明,安裝好Android Studio開發環境。
+2. 啟動Android Studio,選擇「Import project(Eclipse ADT, Gradle, etc.)」:
+
+ 
+
+3. 選擇使用Eclipse ADT開發的Android應用程式專案:
+
+ 
+
+4. 選擇轉移後的專案儲存位置,選擇「Next」:
+
+ 
+
+5. 選擇「Finish」:
+
+ 
+
+6. 等候Android Studio完成轉換工作並開啟專案後,你會發現專案有一些錯誤。開啟「MyAndroidTutorial -> app -> build.gradle」,參考下面的內容,修改並儲存這個檔案(注意applicationId的設定,必須參考你實際的專案修正):
+
+ apply plugin: 'com.android.application'
+
+ android {
+ compileSdkVersion 21
+ buildToolsVersion "21.1.2"
+
+ defaultConfig {
+ applicationId "net.macdidi.myandroidtutorial"
+ minSdkVersion 15
+ targetSdkVersion 21
+ versionCode 1
+ versionName "1.0"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+ }
+
+ dependencies {
+ compile fileTree(dir: 'libs', include: ['*.jar'])
+ compile 'com.android.support:appcompat-v7:21.0.3'
+ }
+
+7. 開啟「MyAndroidTutorial -> app -> src -> main -> AndroidManifest.xml」,參考下面的內容,修改並儲存這個檔案(移除SDK與版本設定):
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+8. 選擇「Try Again」:
+
+ 
+
+9. 選擇「Yes」讓Android Studio關閉與重新啟動專案:
+
+ 
+
+10. 接下來就可以依照專欄的內容,使用Android Studio開發工具繼續學習。
diff --git a/README.md b/README.md
index baf8deb..8327779 100644
--- a/README.md
+++ b/README.md
@@ -1,28 +1,42 @@
-#AndroidTutorial
+#Android Tutorial
+
+### 2015/10/22:Android Tutorial系列專欄已經更新為Android 6,於2015/10/22開始連載,每週一篇,第一篇專欄 [http://www.codedata.com.tw/mobile/android-6-tutorial-1-1/](http://www.codedata.com.tw/mobile/android-6-tutorial-1-1/) 。GitHub在 [https://github.com/macdidi5/Android-6-Tutorial](https://github.com/macdidi5/Android-6-Tutorial) 。
+
+### 2015/03/02:專欄與範例程式改為Android 5與Android Studio
+### 需要從Eclipse ADT專案轉移到Android Studio,請參考AndroidTutorial5_Migrate.md文件的說明
你對「Tutorial」有什麼樣的感覺?每一種技術的Tutorial都告訴你這是學習的開始,不過最後好像都會變成折磨的開始。或許可以找出一種方式,讓Tutorial變成大家會很想要點它的超連結!
要認識一種開發技術,每個人選擇的方式都會不太一樣,如果再加上只能使用非常簡短的時間,你會選擇哪一種方式呢?我的決定是選一個Android APP!
-這個Android APP會在短短六小時的課程內容,帶領你認識大部份Android APP開發時會遇到的主題,從APP的規劃開始,畫面、互動、資料庫、多媒體、檔案、服務、通知、位置、地圖還有小工具,這些就是你會學到的東西。
+這個Android APP會在六小時的課程內容,帶領你認識大部份Android APP開發時會遇到的主題,從APP的規劃開始,畫面、互動、資料庫、多媒體、檔案、服務、通知、位置、地圖還有小工具,這些就是你會學到的東西。
* Android Tutorial 第一堂
- * [西遊記裡的那隻潑猴](http://www.codedata.com.tw/mobile/android-tutorial-the-1st-class-1-sunwukong/)
- * [準備Android開發環境](http://www.codedata.com.tw/mobile/android-tutorial-the-1st-class-2-android-sdk/)
- * [開始設計Android應用程式](http://www.codedata.com.tw/mobile/android-tutorial-the-1st-class-3-app-project/)
- * [開發Android應用程式的準備工作](http://www.codedata.com.tw/mobile/android-tutorial-the-1st-class-4-before-developing-an-app/)
+ * [(1)西遊記裡的那隻潑猴](http://www.codedata.com.tw/mobile/android-tutorial-the-1st-class-1-sunwukong/)
+ * [(2)準備Android Studio開發環境](http://www.codedata.com.tw/mobile/android-tutorial-the-1st-class-2-android-sdk/)
+ * [(3)開始設計Android應用程式](http://www.codedata.com.tw/mobile/android-tutorial-the-1st-class-3-app-project/)
+ * [(4)開發Android應用程式的準備工作](http://www.codedata.com.tw/mobile/android-tutorial-the-1st-class-4-before-developing-an-app/)
* Android Tutorial 第二堂
- * [建立應用程式需要的資源](http://www.codedata.com.tw/mobile/android-tutorial-the-2nd-class-1-res/)
- * [設計應用程式使用者介面](http://www.codedata.com.tw/mobile/android-tutorial-the-2nd-class-2-ui/)
- * [應用程式與使用者的互動](http://www.codedata.com.tw/mobile/android-tutorial-the-2nd-class-3-interaction/)
- * 建立與使用Activity元件
+ * [(1)建立應用程式需要的資源](http://www.codedata.com.tw/mobile/android-tutorial-the-2nd-class-1-res/)
+ * [(2)設計應用程式使用者介面](http://www.codedata.com.tw/mobile/android-tutorial-the-2nd-class-2-ui/)
+ * [(3)應用程式與使用者的互動](http://www.codedata.com.tw/mobile/android-tutorial-the-2nd-class-3-interaction/)
+ * [(4)建立與使用Activity元件](http://www.codedata.com.tw/mobile/android-tutorial-the-2nd-class-4-activity/)
* Android Tutorial 第三堂
- * 為ListView元件建立自定畫面
- * 儲存與讀取應用程式資訊
- * 使用Android內建的SQLite資料庫
- * 存取Android檔案系統
+ * [(1)為ListView元件建立自定畫面](http://www.codedata.com.tw/mobile/android-tutorial-the-3rd-class-1-listview/)
+ * [(2)儲存與讀取應用程式資訊](http://www.codedata.com.tw/mobile/android-tutorial-the-3rd-class-2-preference)
+ * [(3)使用Android內建的SQLite資料庫](http://www.codedata.com.tw/mobile/android-tutorial-the-3rd-class-3-sqlite/)
* Android Tutorial 第四堂
- * 使用照相機與麥克風
+ * [(1)使用照相機與麥克風](http://www.codedata.com.tw/mobile/android-tutorial-the-4th-class-1-camera-microphone/)
+ * [(2)設計地圖應用程式 - Google Maps Android API v2](http://www.codedata.com.tw/mobile/android-tutorial-the-4th-class-google-maps-android-api-v2/)
+ * [(3)讀取裝置目前的位置 - Google Services Location](http://www.codedata.com.tw/mobile/android-tutorial-the-4th-class-3-google-services-location/)
+* Android Tutorial 第五堂
+ * [(1) 建立廣播接收元件 - BroadcastReceiver](http://www.codedata.com.tw/mobile/android-tutorial-the-5th-class-1-broadcastreceiver-alarmmanager/)
+ * [(2) 系統通知服務 - Notification](http://www.codedata.com.tw/mobile/android-tutorial-the-5th-class-2-notification/)
+ * [(3) 設計小工具元件 - AppWidget](http://www.codedata.com.tw/mobile/android-tutorial-the-5th-class-3-appwidget/)
+* Android Tutorial 第六堂
+ * [(1) Material Design - Theme與Transition](http://www.codedata.com.tw/mobile/android-tutorial-the-6th-class-material-design-theme-transition/)
+ * [(2) Material Design - RecylerView](http://www.codedata.com.tw/mobile/android-tutorial-the-6th-class-2-material-design-recylerview/)
+ * [(3) Material Design - Shared Element與自定動畫效果](http://www.codedata.com.tw/mobile/android-tutorial-the-6th-class-material-design-shared-element/)
===============
http://www.codedata.com.tw/author/michael
diff --git a/examples/0201/MyAndroidTutorial/.classpath b/examples/0201/MyAndroidTutorial/.classpath
deleted file mode 100644
index 7bc01d9..0000000
--- a/examples/0201/MyAndroidTutorial/.classpath
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
-
-
-
-
diff --git a/examples/0201/MyAndroidTutorial/.gitignore b/examples/0201/MyAndroidTutorial/.gitignore
new file mode 100644
index 0000000..afbdab3
--- /dev/null
+++ b/examples/0201/MyAndroidTutorial/.gitignore
@@ -0,0 +1,6 @@
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
diff --git a/examples/0201/MyAndroidTutorial/.idea/.name b/examples/0201/MyAndroidTutorial/.idea/.name
new file mode 100644
index 0000000..5bb7a85
--- /dev/null
+++ b/examples/0201/MyAndroidTutorial/.idea/.name
@@ -0,0 +1 @@
+MyAndroidTutorial
\ No newline at end of file
diff --git a/examples/0201/MyAndroidTutorial/.idea/compiler.xml b/examples/0201/MyAndroidTutorial/.idea/compiler.xml
new file mode 100644
index 0000000..217af47
--- /dev/null
+++ b/examples/0201/MyAndroidTutorial/.idea/compiler.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0201/MyAndroidTutorial/.idea/copyright/profiles_settings.xml b/examples/0201/MyAndroidTutorial/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..e7bedf3
--- /dev/null
+++ b/examples/0201/MyAndroidTutorial/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/examples/0201/MyAndroidTutorial/.idea/encodings.xml b/examples/0201/MyAndroidTutorial/.idea/encodings.xml
new file mode 100644
index 0000000..e206d70
--- /dev/null
+++ b/examples/0201/MyAndroidTutorial/.idea/encodings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/examples/0201/MyAndroidTutorial/.idea/gradle.xml b/examples/0201/MyAndroidTutorial/.idea/gradle.xml
new file mode 100644
index 0000000..fe865d3
--- /dev/null
+++ b/examples/0201/MyAndroidTutorial/.idea/gradle.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0201/MyAndroidTutorial/.idea/misc.xml b/examples/0201/MyAndroidTutorial/.idea/misc.xml
new file mode 100644
index 0000000..9076de5
--- /dev/null
+++ b/examples/0201/MyAndroidTutorial/.idea/misc.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0201/MyAndroidTutorial/.idea/modules.xml b/examples/0201/MyAndroidTutorial/.idea/modules.xml
new file mode 100644
index 0000000..327df67
--- /dev/null
+++ b/examples/0201/MyAndroidTutorial/.idea/modules.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0201/MyAndroidTutorial/.idea/scopes/scope_settings.xml b/examples/0201/MyAndroidTutorial/.idea/scopes/scope_settings.xml
new file mode 100644
index 0000000..922003b
--- /dev/null
+++ b/examples/0201/MyAndroidTutorial/.idea/scopes/scope_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0201/MyAndroidTutorial/.idea/vcs.xml b/examples/0201/MyAndroidTutorial/.idea/vcs.xml
new file mode 100644
index 0000000..def6a6a
--- /dev/null
+++ b/examples/0201/MyAndroidTutorial/.idea/vcs.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/examples/0201/MyAndroidTutorial/.project b/examples/0201/MyAndroidTutorial/.project
deleted file mode 100644
index b1de407..0000000
--- a/examples/0201/MyAndroidTutorial/.project
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
- MyAndroidTutorial
-
-
-
-
-
- com.android.ide.eclipse.adt.ResourceManagerBuilder
-
-
-
-
- com.android.ide.eclipse.adt.PreCompilerBuilder
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- com.android.ide.eclipse.adt.ApkBuilder
-
-
-
-
-
- com.android.ide.eclipse.adt.AndroidNature
- org.eclipse.jdt.core.javanature
-
-
diff --git a/examples/0201/MyAndroidTutorial/AndroidManifest.xml b/examples/0201/MyAndroidTutorial/AndroidManifest.xml
deleted file mode 100644
index 470193a..0000000
--- a/examples/0201/MyAndroidTutorial/AndroidManifest.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/examples/0201/MyAndroidTutorial/MyAndroidTutorial.iml b/examples/0201/MyAndroidTutorial/MyAndroidTutorial.iml
new file mode 100644
index 0000000..2a02201
--- /dev/null
+++ b/examples/0201/MyAndroidTutorial/MyAndroidTutorial.iml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0201/MyAndroidTutorial/app/.gitignore b/examples/0201/MyAndroidTutorial/app/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/examples/0201/MyAndroidTutorial/app/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/examples/0201/MyAndroidTutorial/app/app.iml b/examples/0201/MyAndroidTutorial/app/app.iml
new file mode 100644
index 0000000..c6c55c4
--- /dev/null
+++ b/examples/0201/MyAndroidTutorial/app/app.iml
@@ -0,0 +1,91 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0201/MyAndroidTutorial/app/build.gradle b/examples/0201/MyAndroidTutorial/app/build.gradle
new file mode 100644
index 0000000..b09f064
--- /dev/null
+++ b/examples/0201/MyAndroidTutorial/app/build.gradle
@@ -0,0 +1,25 @@
+apply plugin: 'com.android.application'
+
+android {
+ compileSdkVersion 21
+ buildToolsVersion "21.1.2"
+
+ defaultConfig {
+ applicationId "net.macdidi.myandroidtutorial"
+ minSdkVersion 15
+ targetSdkVersion 21
+ versionCode 1
+ versionName "1.0"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ compile fileTree(dir: 'libs', include: ['*.jar'])
+ compile 'com.android.support:appcompat-v7:21.0.3'
+}
diff --git a/examples/0201/MyAndroidTutorial/app/proguard-rules.pro b/examples/0201/MyAndroidTutorial/app/proguard-rules.pro
new file mode 100644
index 0000000..b5fa7ec
--- /dev/null
+++ b/examples/0201/MyAndroidTutorial/app/proguard-rules.pro
@@ -0,0 +1,17 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /Users/macdidi5/Library/Android/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
diff --git a/examples/0201/MyAndroidTutorial/app/src/androidTest/java/net/macdidi/myandroidtutorial/ApplicationTest.java b/examples/0201/MyAndroidTutorial/app/src/androidTest/java/net/macdidi/myandroidtutorial/ApplicationTest.java
new file mode 100644
index 0000000..2cb214e
--- /dev/null
+++ b/examples/0201/MyAndroidTutorial/app/src/androidTest/java/net/macdidi/myandroidtutorial/ApplicationTest.java
@@ -0,0 +1,13 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Application;
+import android.test.ApplicationTestCase;
+
+/**
+ * Testing Fundamentals
+ */
+public class ApplicationTest extends ApplicationTestCase {
+ public ApplicationTest() {
+ super(Application.class);
+ }
+}
\ No newline at end of file
diff --git a/examples/0201/MyAndroidTutorial/app/src/main/AndroidManifest.xml b/examples/0201/MyAndroidTutorial/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..c325305
--- /dev/null
+++ b/examples/0201/MyAndroidTutorial/app/src/main/AndroidManifest.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0201/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MainActivity.java b/examples/0201/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MainActivity.java
new file mode 100644
index 0000000..ba500a4
--- /dev/null
+++ b/examples/0201/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MainActivity.java
@@ -0,0 +1,24 @@
+package net.macdidi.myandroidtutorial;
+
+import android.os.Bundle;
+import android.support.v7.app.ActionBarActivity;
+import android.view.Menu;
+
+
+public class MainActivity extends ActionBarActivity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+ }
+
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ // Inflate the menu; this adds items to the action bar if it is present.
+ getMenuInflater().inflate(R.menu.menu_main, menu);
+ return true;
+ }
+
+}
diff --git a/examples/0201/MyAndroidTutorial/res/drawable-hdpi/ic_launcher.png b/examples/0201/MyAndroidTutorial/app/src/main/res/drawable-hdpi/ic_launcher.png
similarity index 100%
rename from examples/0201/MyAndroidTutorial/res/drawable-hdpi/ic_launcher.png
rename to examples/0201/MyAndroidTutorial/app/src/main/res/drawable-hdpi/ic_launcher.png
diff --git a/examples/0201/MyAndroidTutorial/res/drawable-mdpi/ic_launcher.png b/examples/0201/MyAndroidTutorial/app/src/main/res/drawable-mdpi/ic_launcher.png
similarity index 100%
rename from examples/0201/MyAndroidTutorial/res/drawable-mdpi/ic_launcher.png
rename to examples/0201/MyAndroidTutorial/app/src/main/res/drawable-mdpi/ic_launcher.png
diff --git a/examples/0201/MyAndroidTutorial/res/drawable-xhdpi/ic_launcher.png b/examples/0201/MyAndroidTutorial/app/src/main/res/drawable-xhdpi/ic_launcher.png
similarity index 100%
rename from examples/0201/MyAndroidTutorial/res/drawable-xhdpi/ic_launcher.png
rename to examples/0201/MyAndroidTutorial/app/src/main/res/drawable-xhdpi/ic_launcher.png
diff --git a/examples/0201/MyAndroidTutorial/app/src/main/res/drawable-xxhdpi/ic_launcher.png b/examples/0201/MyAndroidTutorial/app/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..4df1894
Binary files /dev/null and b/examples/0201/MyAndroidTutorial/app/src/main/res/drawable-xxhdpi/ic_launcher.png differ
diff --git a/examples/0201/MyAndroidTutorial/res/drawable/alarm_icon.png b/examples/0201/MyAndroidTutorial/app/src/main/res/drawable/alarm_icon.png
similarity index 100%
rename from examples/0201/MyAndroidTutorial/res/drawable/alarm_icon.png
rename to examples/0201/MyAndroidTutorial/app/src/main/res/drawable/alarm_icon.png
diff --git a/examples/0201/MyAndroidTutorial/res/drawable/location_icon.png b/examples/0201/MyAndroidTutorial/app/src/main/res/drawable/location_icon.png
similarity index 100%
rename from examples/0201/MyAndroidTutorial/res/drawable/location_icon.png
rename to examples/0201/MyAndroidTutorial/app/src/main/res/drawable/location_icon.png
diff --git a/examples/0201/MyAndroidTutorial/res/drawable/record_sound_icon.png b/examples/0201/MyAndroidTutorial/app/src/main/res/drawable/record_sound_icon.png
similarity index 100%
rename from examples/0201/MyAndroidTutorial/res/drawable/record_sound_icon.png
rename to examples/0201/MyAndroidTutorial/app/src/main/res/drawable/record_sound_icon.png
diff --git a/examples/0201/MyAndroidTutorial/app/src/main/res/drawable/retangle_drawable.xml b/examples/0201/MyAndroidTutorial/app/src/main/res/drawable/retangle_drawable.xml
new file mode 100644
index 0000000..51d1e84
--- /dev/null
+++ b/examples/0201/MyAndroidTutorial/app/src/main/res/drawable/retangle_drawable.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0201/MyAndroidTutorial/res/drawable/select_color_icon.png b/examples/0201/MyAndroidTutorial/app/src/main/res/drawable/select_color_icon.png
similarity index 100%
rename from examples/0201/MyAndroidTutorial/res/drawable/select_color_icon.png
rename to examples/0201/MyAndroidTutorial/app/src/main/res/drawable/select_color_icon.png
diff --git a/examples/0201/MyAndroidTutorial/res/drawable/take_picture_icon.png b/examples/0201/MyAndroidTutorial/app/src/main/res/drawable/take_picture_icon.png
similarity index 100%
rename from examples/0201/MyAndroidTutorial/res/drawable/take_picture_icon.png
rename to examples/0201/MyAndroidTutorial/app/src/main/res/drawable/take_picture_icon.png
diff --git a/examples/0201/MyAndroidTutorial/app/src/main/res/layout/activity_main.xml b/examples/0201/MyAndroidTutorial/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..dafb0f1
--- /dev/null
+++ b/examples/0201/MyAndroidTutorial/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
diff --git a/examples/0201/MyAndroidTutorial/app/src/main/res/menu/menu_main.xml b/examples/0201/MyAndroidTutorial/app/src/main/res/menu/menu_main.xml
new file mode 100644
index 0000000..7e74561
--- /dev/null
+++ b/examples/0201/MyAndroidTutorial/app/src/main/res/menu/menu_main.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
diff --git a/examples/0201/MyAndroidTutorial/app/src/main/res/values-en/strings.xml b/examples/0201/MyAndroidTutorial/app/src/main/res/values-en/strings.xml
new file mode 100644
index 0000000..c532533
--- /dev/null
+++ b/examples/0201/MyAndroidTutorial/app/src/main/res/values-en/strings.xml
@@ -0,0 +1,12 @@
+
+
+
+ MyAndroidTutorial
+ Hello world!
+ Settings
+
+ Title
+ Enter title
+ Content
+ Enter content
+
diff --git a/examples/0201/MyAndroidTutorial/app/src/main/res/values-w820dp/dimens.xml b/examples/0201/MyAndroidTutorial/app/src/main/res/values-w820dp/dimens.xml
new file mode 100644
index 0000000..63fc816
--- /dev/null
+++ b/examples/0201/MyAndroidTutorial/app/src/main/res/values-w820dp/dimens.xml
@@ -0,0 +1,6 @@
+
+
+ 64dp
+
diff --git a/examples/0201/MyAndroidTutorial/app/src/main/res/values/colors.xml b/examples/0201/MyAndroidTutorial/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..8d8f719
--- /dev/null
+++ b/examples/0201/MyAndroidTutorial/app/src/main/res/values/colors.xml
@@ -0,0 +1,6 @@
+
+
+ #CCCCCC
+ #AAAAAA
+ #DD999999
+
\ No newline at end of file
diff --git a/examples/0201/MyAndroidTutorial/app/src/main/res/values/dimens.xml b/examples/0201/MyAndroidTutorial/app/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..75e4541
--- /dev/null
+++ b/examples/0201/MyAndroidTutorial/app/src/main/res/values/dimens.xml
@@ -0,0 +1,8 @@
+
+
+ 16dp
+ 16dp
+
+ 6dp
+ 24sp
+
diff --git a/examples/0201/MyAndroidTutorial/app/src/main/res/values/strings.xml b/examples/0201/MyAndroidTutorial/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..d07b4bc
--- /dev/null
+++ b/examples/0201/MyAndroidTutorial/app/src/main/res/values/strings.xml
@@ -0,0 +1,12 @@
+
+
+
+ MyAndroidTutorial
+ Hello world!
+ Settings
+
+ 標題
+ 輸入標題
+ 內容
+ 輸入內容
+
diff --git a/examples/0201/MyAndroidTutorial/app/src/main/res/values/styles.xml b/examples/0201/MyAndroidTutorial/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..766ab99
--- /dev/null
+++ b/examples/0201/MyAndroidTutorial/app/src/main/res/values/styles.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
diff --git a/examples/0201/MyAndroidTutorial/bin/AndroidManifest.xml b/examples/0201/MyAndroidTutorial/bin/AndroidManifest.xml
deleted file mode 100644
index 470193a..0000000
--- a/examples/0201/MyAndroidTutorial/bin/AndroidManifest.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/examples/0201/MyAndroidTutorial/bin/MyAndroidTutorial.apk b/examples/0201/MyAndroidTutorial/bin/MyAndroidTutorial.apk
deleted file mode 100644
index c207fad..0000000
Binary files a/examples/0201/MyAndroidTutorial/bin/MyAndroidTutorial.apk and /dev/null differ
diff --git a/examples/0201/MyAndroidTutorial/bin/classes.dex b/examples/0201/MyAndroidTutorial/bin/classes.dex
deleted file mode 100644
index 05ee105..0000000
Binary files a/examples/0201/MyAndroidTutorial/bin/classes.dex and /dev/null differ
diff --git a/examples/0201/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/BuildConfig.class b/examples/0201/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/BuildConfig.class
deleted file mode 100644
index 30f5623..0000000
Binary files a/examples/0201/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/BuildConfig.class and /dev/null differ
diff --git a/examples/0201/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity.class b/examples/0201/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity.class
deleted file mode 100644
index ebf86cf..0000000
Binary files a/examples/0201/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity.class and /dev/null differ
diff --git a/examples/0201/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$attr.class b/examples/0201/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$attr.class
deleted file mode 100644
index 9d83559..0000000
Binary files a/examples/0201/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$attr.class and /dev/null differ
diff --git a/examples/0201/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$color.class b/examples/0201/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$color.class
deleted file mode 100644
index 10fa364..0000000
Binary files a/examples/0201/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$color.class and /dev/null differ
diff --git a/examples/0201/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$dimen.class b/examples/0201/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$dimen.class
deleted file mode 100644
index fef097c..0000000
Binary files a/examples/0201/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$dimen.class and /dev/null differ
diff --git a/examples/0201/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$drawable.class b/examples/0201/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$drawable.class
deleted file mode 100644
index ed9bcd0..0000000
Binary files a/examples/0201/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$drawable.class and /dev/null differ
diff --git a/examples/0201/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$id.class b/examples/0201/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$id.class
deleted file mode 100644
index be68360..0000000
Binary files a/examples/0201/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$id.class and /dev/null differ
diff --git a/examples/0201/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$layout.class b/examples/0201/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$layout.class
deleted file mode 100644
index 6b84f81..0000000
Binary files a/examples/0201/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$layout.class and /dev/null differ
diff --git a/examples/0201/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$menu.class b/examples/0201/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$menu.class
deleted file mode 100644
index a5baaf9..0000000
Binary files a/examples/0201/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$menu.class and /dev/null differ
diff --git a/examples/0201/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$string.class b/examples/0201/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$string.class
deleted file mode 100644
index 3fd356f..0000000
Binary files a/examples/0201/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$string.class and /dev/null differ
diff --git a/examples/0201/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$style.class b/examples/0201/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$style.class
deleted file mode 100644
index 5833285..0000000
Binary files a/examples/0201/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$style.class and /dev/null differ
diff --git a/examples/0201/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R.class b/examples/0201/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R.class
deleted file mode 100644
index 3be8276..0000000
Binary files a/examples/0201/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R.class and /dev/null differ
diff --git a/examples/0201/MyAndroidTutorial/bin/dexedLibs/android-support-v4-9b1d5d28bf7d59a4e392b3d4f78c1f13.jar b/examples/0201/MyAndroidTutorial/bin/dexedLibs/android-support-v4-9b1d5d28bf7d59a4e392b3d4f78c1f13.jar
deleted file mode 100644
index 80a2884..0000000
Binary files a/examples/0201/MyAndroidTutorial/bin/dexedLibs/android-support-v4-9b1d5d28bf7d59a4e392b3d4f78c1f13.jar and /dev/null differ
diff --git a/examples/0201/MyAndroidTutorial/bin/jarlist.cache b/examples/0201/MyAndroidTutorial/bin/jarlist.cache
deleted file mode 100644
index 0565465..0000000
--- a/examples/0201/MyAndroidTutorial/bin/jarlist.cache
+++ /dev/null
@@ -1,3 +0,0 @@
-# cache for current jar dependency. DO NOT EDIT.
-# format is
-# Encoding is UTF-8
diff --git a/examples/0201/MyAndroidTutorial/bin/res/crunch/drawable-hdpi/ic_launcher.png b/examples/0201/MyAndroidTutorial/bin/res/crunch/drawable-hdpi/ic_launcher.png
deleted file mode 100644
index bcfa058..0000000
Binary files a/examples/0201/MyAndroidTutorial/bin/res/crunch/drawable-hdpi/ic_launcher.png and /dev/null differ
diff --git a/examples/0201/MyAndroidTutorial/bin/res/crunch/drawable-mdpi/ic_launcher.png b/examples/0201/MyAndroidTutorial/bin/res/crunch/drawable-mdpi/ic_launcher.png
deleted file mode 100644
index 85848ff..0000000
Binary files a/examples/0201/MyAndroidTutorial/bin/res/crunch/drawable-mdpi/ic_launcher.png and /dev/null differ
diff --git a/examples/0201/MyAndroidTutorial/bin/res/crunch/drawable-xhdpi/ic_launcher.png b/examples/0201/MyAndroidTutorial/bin/res/crunch/drawable-xhdpi/ic_launcher.png
deleted file mode 100644
index 916901e..0000000
Binary files a/examples/0201/MyAndroidTutorial/bin/res/crunch/drawable-xhdpi/ic_launcher.png and /dev/null differ
diff --git a/examples/0201/MyAndroidTutorial/bin/res/crunch/drawable/alarm_icon.png b/examples/0201/MyAndroidTutorial/bin/res/crunch/drawable/alarm_icon.png
deleted file mode 100644
index ebeae27..0000000
Binary files a/examples/0201/MyAndroidTutorial/bin/res/crunch/drawable/alarm_icon.png and /dev/null differ
diff --git a/examples/0201/MyAndroidTutorial/bin/res/crunch/drawable/location_icon.png b/examples/0201/MyAndroidTutorial/bin/res/crunch/drawable/location_icon.png
deleted file mode 100644
index 6897a97..0000000
Binary files a/examples/0201/MyAndroidTutorial/bin/res/crunch/drawable/location_icon.png and /dev/null differ
diff --git a/examples/0201/MyAndroidTutorial/bin/res/crunch/drawable/record_sound_icon.png b/examples/0201/MyAndroidTutorial/bin/res/crunch/drawable/record_sound_icon.png
deleted file mode 100644
index 6fe2060..0000000
Binary files a/examples/0201/MyAndroidTutorial/bin/res/crunch/drawable/record_sound_icon.png and /dev/null differ
diff --git a/examples/0201/MyAndroidTutorial/bin/res/crunch/drawable/select_color_icon.png b/examples/0201/MyAndroidTutorial/bin/res/crunch/drawable/select_color_icon.png
deleted file mode 100644
index 4270ec5..0000000
Binary files a/examples/0201/MyAndroidTutorial/bin/res/crunch/drawable/select_color_icon.png and /dev/null differ
diff --git a/examples/0201/MyAndroidTutorial/bin/res/crunch/drawable/take_picture_icon.png b/examples/0201/MyAndroidTutorial/bin/res/crunch/drawable/take_picture_icon.png
deleted file mode 100644
index c812e2f..0000000
Binary files a/examples/0201/MyAndroidTutorial/bin/res/crunch/drawable/take_picture_icon.png and /dev/null differ
diff --git a/examples/0201/MyAndroidTutorial/bin/resources.ap_ b/examples/0201/MyAndroidTutorial/bin/resources.ap_
deleted file mode 100644
index 39f817a..0000000
Binary files a/examples/0201/MyAndroidTutorial/bin/resources.ap_ and /dev/null differ
diff --git a/examples/0201/MyAndroidTutorial/build.gradle b/examples/0201/MyAndroidTutorial/build.gradle
new file mode 100644
index 0000000..6356aab
--- /dev/null
+++ b/examples/0201/MyAndroidTutorial/build.gradle
@@ -0,0 +1,19 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+ repositories {
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:1.0.0'
+
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+}
+
+allprojects {
+ repositories {
+ jcenter()
+ }
+}
diff --git a/examples/0201/MyAndroidTutorial/gen/net/macdidi/myandroidtutorial/BuildConfig.java b/examples/0201/MyAndroidTutorial/gen/net/macdidi/myandroidtutorial/BuildConfig.java
deleted file mode 100644
index 5d44ea9..0000000
--- a/examples/0201/MyAndroidTutorial/gen/net/macdidi/myandroidtutorial/BuildConfig.java
+++ /dev/null
@@ -1,6 +0,0 @@
-/** Automatically generated file. DO NOT MODIFY */
-package net.macdidi.myandroidtutorial;
-
-public final class BuildConfig {
- public final static boolean DEBUG = true;
-}
\ No newline at end of file
diff --git a/examples/0201/MyAndroidTutorial/gen/net/macdidi/myandroidtutorial/R.java b/examples/0201/MyAndroidTutorial/gen/net/macdidi/myandroidtutorial/R.java
deleted file mode 100644
index d7fa44c..0000000
--- a/examples/0201/MyAndroidTutorial/gen/net/macdidi/myandroidtutorial/R.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/* AUTO-GENERATED FILE. DO NOT MODIFY.
- *
- * This class was automatically generated by the
- * aapt tool from the resource data it found. It
- * should not be modified by hand.
- */
-
-package net.macdidi.myandroidtutorial;
-
-public final class R {
- public static final class attr {
- }
- public static final class color {
- public static final int divider_color=0x7f040002;
- public static final int grey=0x7f040001;
- public static final int light_grey=0x7f040000;
- }
- public static final class dimen {
- public static final int default_padding=0x7f050000;
- public static final int title_txt_size=0x7f050001;
- }
- public static final class drawable {
- public static final int alarm_icon=0x7f020000;
- public static final int ic_launcher=0x7f020001;
- public static final int location_icon=0x7f020002;
- public static final int record_sound_icon=0x7f020003;
- public static final int retangle_drawable=0x7f020004;
- public static final int select_color_icon=0x7f020005;
- public static final int take_picture_icon=0x7f020006;
- }
- public static final class id {
- public static final int add_item=0x7f090001;
- public static final int delete_item=0x7f090003;
- public static final int facebook_item=0x7f090006;
- public static final int googleplus_item=0x7f090005;
- public static final int revert_item=0x7f090002;
- public static final int search_item=0x7f090000;
- public static final int share_item=0x7f090004;
- }
- public static final class layout {
- public static final int activity_main=0x7f030000;
- }
- public static final class menu {
- public static final int main_menu=0x7f080000;
- }
- public static final class string {
- public static final int app_name=0x7f060000;
- public static final int content=0x7f060005;
- public static final int enter_content=0x7f060006;
- public static final int enter_title=0x7f060004;
- public static final int hello_world=0x7f060002;
- public static final int title=0x7f060003;
- public static final int title_activity_main=0x7f060001;
- }
- public static final class style {
- /**
- Base application theme, dependent on API level. This theme is replaced
- by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
-
-
- Theme customizations available in newer API levels can go in
- res/values-vXX/styles.xml, while customizations related to
- backward-compatibility can go here.
-
-
- Base application theme for API 11+. This theme completely replaces
- AppBaseTheme from res/values/styles.xml on API 11+ devices.
-
- API 11 theme customizations can go here.
-
- Base application theme for API 14+. This theme completely replaces
- AppBaseTheme from BOTH res/values/styles.xml and
- res/values-v11/styles.xml on API 14+ devices.
-
- API 14 theme customizations can go here.
- */
- public static final int AppBaseTheme=0x7f070000;
- /** Application theme.
- All customizations that are NOT specific to a particular API-level can go here.
- */
- public static final int AppTheme=0x7f070001;
- }
-}
diff --git a/examples/0201/MyAndroidTutorial/gradle.properties b/examples/0201/MyAndroidTutorial/gradle.properties
new file mode 100644
index 0000000..1d3591c
--- /dev/null
+++ b/examples/0201/MyAndroidTutorial/gradle.properties
@@ -0,0 +1,18 @@
+# Project-wide Gradle settings.
+
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+# Default value: -Xmx10248m -XX:MaxPermSize=256m
+# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
+
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
\ No newline at end of file
diff --git a/examples/0201/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.jar b/examples/0201/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
Binary files /dev/null and b/examples/0201/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/examples/0201/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.properties b/examples/0201/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..0c71e76
--- /dev/null
+++ b/examples/0201/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
diff --git a/examples/0201/MyAndroidTutorial/gradlew b/examples/0201/MyAndroidTutorial/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/examples/0201/MyAndroidTutorial/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/examples/0201/MyAndroidTutorial/gradlew.bat b/examples/0201/MyAndroidTutorial/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/examples/0201/MyAndroidTutorial/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/examples/0201/MyAndroidTutorial/libs/android-support-v4.jar b/examples/0201/MyAndroidTutorial/libs/android-support-v4.jar
deleted file mode 100644
index 187bdf4..0000000
Binary files a/examples/0201/MyAndroidTutorial/libs/android-support-v4.jar and /dev/null differ
diff --git a/examples/0201/MyAndroidTutorial/proguard-project.txt b/examples/0201/MyAndroidTutorial/proguard-project.txt
deleted file mode 100644
index f2fe155..0000000
--- a/examples/0201/MyAndroidTutorial/proguard-project.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-# To enable ProGuard in your project, edit project.properties
-# to define the proguard.config property as described in that file.
-#
-# Add project specific ProGuard rules here.
-# By default, the flags in this file are appended to flags specified
-# in ${sdk.dir}/tools/proguard/proguard-android.txt
-# You can edit the include path and order by changing the ProGuard
-# include property in project.properties.
-#
-# For more details, see
-# http://developer.android.com/guide/developing/tools/proguard.html
-
-# Add any project specific keep options here:
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-# public *;
-#}
diff --git a/examples/0201/MyAndroidTutorial/project.properties b/examples/0201/MyAndroidTutorial/project.properties
deleted file mode 100644
index 4ab1256..0000000
--- a/examples/0201/MyAndroidTutorial/project.properties
+++ /dev/null
@@ -1,14 +0,0 @@
-# This file is automatically generated by Android Tools.
-# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
-#
-# This file must be checked in Version Control Systems.
-#
-# To customize properties used by the Ant build system edit
-# "ant.properties", and override values to adapt the script to your
-# project structure.
-#
-# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
-#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
-
-# Project target.
-target=android-19
diff --git a/examples/0201/MyAndroidTutorial/res/drawable/retangle_drawable.xml b/examples/0201/MyAndroidTutorial/res/drawable/retangle_drawable.xml
deleted file mode 100644
index e195342..0000000
--- a/examples/0201/MyAndroidTutorial/res/drawable/retangle_drawable.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/examples/0201/MyAndroidTutorial/res/layout/activity_main.xml b/examples/0201/MyAndroidTutorial/res/layout/activity_main.xml
deleted file mode 100644
index 52ef000..0000000
--- a/examples/0201/MyAndroidTutorial/res/layout/activity_main.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/examples/0201/MyAndroidTutorial/res/menu/main_menu.xml b/examples/0201/MyAndroidTutorial/res/menu/main_menu.xml
deleted file mode 100644
index 4bfad8e..0000000
--- a/examples/0201/MyAndroidTutorial/res/menu/main_menu.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/examples/0201/MyAndroidTutorial/res/values-en/strings.xml b/examples/0201/MyAndroidTutorial/res/values-en/strings.xml
deleted file mode 100644
index 34f4fed..0000000
--- a/examples/0201/MyAndroidTutorial/res/values-en/strings.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
- MyAndroidTutorial
- MainActivity
- Hello world!
-
- Title
- Enter title
- Content
- Enter content
-
-
diff --git a/examples/0201/MyAndroidTutorial/res/values-v11/styles.xml b/examples/0201/MyAndroidTutorial/res/values-v11/styles.xml
deleted file mode 100644
index 3c02242..0000000
--- a/examples/0201/MyAndroidTutorial/res/values-v11/styles.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
diff --git a/examples/0201/MyAndroidTutorial/res/values-v14/styles.xml b/examples/0201/MyAndroidTutorial/res/values-v14/styles.xml
deleted file mode 100644
index a91fd03..0000000
--- a/examples/0201/MyAndroidTutorial/res/values-v14/styles.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
diff --git a/examples/0201/MyAndroidTutorial/res/values/colors.xml b/examples/0201/MyAndroidTutorial/res/values/colors.xml
deleted file mode 100644
index c7b5d95..0000000
--- a/examples/0201/MyAndroidTutorial/res/values/colors.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
- #CCCCCC
- #AAAAAA
- #DDCCCCCC
-
diff --git a/examples/0201/MyAndroidTutorial/res/values/dimens.xml b/examples/0201/MyAndroidTutorial/res/values/dimens.xml
deleted file mode 100644
index fb03071..0000000
--- a/examples/0201/MyAndroidTutorial/res/values/dimens.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
- 6dp
- 2dp
- 24sp
-
diff --git a/examples/0201/MyAndroidTutorial/res/values/strings.xml b/examples/0201/MyAndroidTutorial/res/values/strings.xml
deleted file mode 100644
index b879ab4..0000000
--- a/examples/0201/MyAndroidTutorial/res/values/strings.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
- MyAndroidTutorial
- MainActivity
- Hello world!
-
- 標題
- 輸入標題
- 內容
- 輸入內容
-
-
diff --git a/examples/0201/MyAndroidTutorial/res/values/styles.xml b/examples/0201/MyAndroidTutorial/res/values/styles.xml
deleted file mode 100644
index 6ce89c7..0000000
--- a/examples/0201/MyAndroidTutorial/res/values/styles.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
-
-
-
-
-
-
diff --git a/examples/0201/MyAndroidTutorial/settings.gradle b/examples/0201/MyAndroidTutorial/settings.gradle
new file mode 100644
index 0000000..e7b4def
--- /dev/null
+++ b/examples/0201/MyAndroidTutorial/settings.gradle
@@ -0,0 +1 @@
+include ':app'
diff --git a/examples/0201/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/MainActivity.java b/examples/0201/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/MainActivity.java
deleted file mode 100644
index d15f032..0000000
--- a/examples/0201/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/MainActivity.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package net.macdidi.myandroidtutorial;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.view.Menu;
-import android.view.MenuInflater;
-
-public class MainActivity extends Activity {
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- }
-
- // 載入選單資源
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- MenuInflater menuInflater = getMenuInflater();
- menuInflater.inflate(R.menu.main_menu, menu);
- return true;
- }
-}
diff --git a/examples/0202/MyAndroidTutorial/.classpath b/examples/0202/MyAndroidTutorial/.classpath
deleted file mode 100644
index 7bc01d9..0000000
--- a/examples/0202/MyAndroidTutorial/.classpath
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
-
-
-
-
diff --git a/examples/0202/MyAndroidTutorial/.gitignore b/examples/0202/MyAndroidTutorial/.gitignore
new file mode 100644
index 0000000..afbdab3
--- /dev/null
+++ b/examples/0202/MyAndroidTutorial/.gitignore
@@ -0,0 +1,6 @@
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
diff --git a/examples/0202/MyAndroidTutorial/.idea/.name b/examples/0202/MyAndroidTutorial/.idea/.name
new file mode 100644
index 0000000..5bb7a85
--- /dev/null
+++ b/examples/0202/MyAndroidTutorial/.idea/.name
@@ -0,0 +1 @@
+MyAndroidTutorial
\ No newline at end of file
diff --git a/examples/0202/MyAndroidTutorial/.idea/compiler.xml b/examples/0202/MyAndroidTutorial/.idea/compiler.xml
new file mode 100644
index 0000000..217af47
--- /dev/null
+++ b/examples/0202/MyAndroidTutorial/.idea/compiler.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0202/MyAndroidTutorial/.idea/copyright/profiles_settings.xml b/examples/0202/MyAndroidTutorial/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..e7bedf3
--- /dev/null
+++ b/examples/0202/MyAndroidTutorial/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/examples/0202/MyAndroidTutorial/.idea/encodings.xml b/examples/0202/MyAndroidTutorial/.idea/encodings.xml
new file mode 100644
index 0000000..e206d70
--- /dev/null
+++ b/examples/0202/MyAndroidTutorial/.idea/encodings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/examples/0202/MyAndroidTutorial/.idea/gradle.xml b/examples/0202/MyAndroidTutorial/.idea/gradle.xml
new file mode 100644
index 0000000..fe865d3
--- /dev/null
+++ b/examples/0202/MyAndroidTutorial/.idea/gradle.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0202/MyAndroidTutorial/.idea/misc.xml b/examples/0202/MyAndroidTutorial/.idea/misc.xml
new file mode 100644
index 0000000..9076de5
--- /dev/null
+++ b/examples/0202/MyAndroidTutorial/.idea/misc.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0202/MyAndroidTutorial/.idea/modules.xml b/examples/0202/MyAndroidTutorial/.idea/modules.xml
new file mode 100644
index 0000000..327df67
--- /dev/null
+++ b/examples/0202/MyAndroidTutorial/.idea/modules.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0202/MyAndroidTutorial/.idea/scopes/scope_settings.xml b/examples/0202/MyAndroidTutorial/.idea/scopes/scope_settings.xml
new file mode 100644
index 0000000..922003b
--- /dev/null
+++ b/examples/0202/MyAndroidTutorial/.idea/scopes/scope_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0202/MyAndroidTutorial/.idea/vcs.xml b/examples/0202/MyAndroidTutorial/.idea/vcs.xml
new file mode 100644
index 0000000..def6a6a
--- /dev/null
+++ b/examples/0202/MyAndroidTutorial/.idea/vcs.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/examples/0202/MyAndroidTutorial/.project b/examples/0202/MyAndroidTutorial/.project
deleted file mode 100644
index b1de407..0000000
--- a/examples/0202/MyAndroidTutorial/.project
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
- MyAndroidTutorial
-
-
-
-
-
- com.android.ide.eclipse.adt.ResourceManagerBuilder
-
-
-
-
- com.android.ide.eclipse.adt.PreCompilerBuilder
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- com.android.ide.eclipse.adt.ApkBuilder
-
-
-
-
-
- com.android.ide.eclipse.adt.AndroidNature
- org.eclipse.jdt.core.javanature
-
-
diff --git a/examples/0202/MyAndroidTutorial/AndroidManifest.xml b/examples/0202/MyAndroidTutorial/AndroidManifest.xml
deleted file mode 100644
index 470193a..0000000
--- a/examples/0202/MyAndroidTutorial/AndroidManifest.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/examples/0202/MyAndroidTutorial/MyAndroidTutorial.iml b/examples/0202/MyAndroidTutorial/MyAndroidTutorial.iml
new file mode 100644
index 0000000..2a02201
--- /dev/null
+++ b/examples/0202/MyAndroidTutorial/MyAndroidTutorial.iml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0202/MyAndroidTutorial/app/.gitignore b/examples/0202/MyAndroidTutorial/app/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/examples/0202/MyAndroidTutorial/app/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/examples/0202/MyAndroidTutorial/app/app.iml b/examples/0202/MyAndroidTutorial/app/app.iml
new file mode 100644
index 0000000..c6c55c4
--- /dev/null
+++ b/examples/0202/MyAndroidTutorial/app/app.iml
@@ -0,0 +1,91 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0202/MyAndroidTutorial/app/build.gradle b/examples/0202/MyAndroidTutorial/app/build.gradle
new file mode 100644
index 0000000..b09f064
--- /dev/null
+++ b/examples/0202/MyAndroidTutorial/app/build.gradle
@@ -0,0 +1,25 @@
+apply plugin: 'com.android.application'
+
+android {
+ compileSdkVersion 21
+ buildToolsVersion "21.1.2"
+
+ defaultConfig {
+ applicationId "net.macdidi.myandroidtutorial"
+ minSdkVersion 15
+ targetSdkVersion 21
+ versionCode 1
+ versionName "1.0"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ compile fileTree(dir: 'libs', include: ['*.jar'])
+ compile 'com.android.support:appcompat-v7:21.0.3'
+}
diff --git a/examples/0202/MyAndroidTutorial/app/proguard-rules.pro b/examples/0202/MyAndroidTutorial/app/proguard-rules.pro
new file mode 100644
index 0000000..b5fa7ec
--- /dev/null
+++ b/examples/0202/MyAndroidTutorial/app/proguard-rules.pro
@@ -0,0 +1,17 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /Users/macdidi5/Library/Android/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
diff --git a/examples/0202/MyAndroidTutorial/app/src/androidTest/java/net/macdidi/myandroidtutorial/ApplicationTest.java b/examples/0202/MyAndroidTutorial/app/src/androidTest/java/net/macdidi/myandroidtutorial/ApplicationTest.java
new file mode 100644
index 0000000..2cb214e
--- /dev/null
+++ b/examples/0202/MyAndroidTutorial/app/src/androidTest/java/net/macdidi/myandroidtutorial/ApplicationTest.java
@@ -0,0 +1,13 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Application;
+import android.test.ApplicationTestCase;
+
+/**
+ * Testing Fundamentals
+ */
+public class ApplicationTest extends ApplicationTestCase {
+ public ApplicationTest() {
+ super(Application.class);
+ }
+}
\ No newline at end of file
diff --git a/examples/0202/MyAndroidTutorial/app/src/main/AndroidManifest.xml b/examples/0202/MyAndroidTutorial/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..c325305
--- /dev/null
+++ b/examples/0202/MyAndroidTutorial/app/src/main/AndroidManifest.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0202/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MainActivity.java b/examples/0202/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MainActivity.java
new file mode 100644
index 0000000..987d676
--- /dev/null
+++ b/examples/0202/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MainActivity.java
@@ -0,0 +1,34 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.Menu;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+
+public class MainActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ // 為ListView元件設定三筆資料
+ String[] data = {
+ "關於Android Tutorial的事情",
+ "一隻非常可愛的小狗狗!",
+ "一首非常好聽的音樂!"};
+ int layoutId = android.R.layout.simple_list_item_1;
+ ArrayAdapter adapter =
+ new ArrayAdapter(this, layoutId, data);
+ ListView item_list = (ListView) findViewById(R.id.item_list);
+ item_list.setAdapter(adapter);
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.menu_main, menu);
+ return true;
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0202/MyAndroidTutorial/res/drawable-hdpi/ic_launcher.png b/examples/0202/MyAndroidTutorial/app/src/main/res/drawable-hdpi/ic_launcher.png
similarity index 100%
rename from examples/0202/MyAndroidTutorial/res/drawable-hdpi/ic_launcher.png
rename to examples/0202/MyAndroidTutorial/app/src/main/res/drawable-hdpi/ic_launcher.png
diff --git a/examples/0202/MyAndroidTutorial/res/drawable-mdpi/ic_launcher.png b/examples/0202/MyAndroidTutorial/app/src/main/res/drawable-mdpi/ic_launcher.png
similarity index 100%
rename from examples/0202/MyAndroidTutorial/res/drawable-mdpi/ic_launcher.png
rename to examples/0202/MyAndroidTutorial/app/src/main/res/drawable-mdpi/ic_launcher.png
diff --git a/examples/0202/MyAndroidTutorial/res/drawable-xhdpi/ic_launcher.png b/examples/0202/MyAndroidTutorial/app/src/main/res/drawable-xhdpi/ic_launcher.png
similarity index 100%
rename from examples/0202/MyAndroidTutorial/res/drawable-xhdpi/ic_launcher.png
rename to examples/0202/MyAndroidTutorial/app/src/main/res/drawable-xhdpi/ic_launcher.png
diff --git a/examples/0202/MyAndroidTutorial/app/src/main/res/drawable-xxhdpi/ic_launcher.png b/examples/0202/MyAndroidTutorial/app/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..4df1894
Binary files /dev/null and b/examples/0202/MyAndroidTutorial/app/src/main/res/drawable-xxhdpi/ic_launcher.png differ
diff --git a/examples/0202/MyAndroidTutorial/res/drawable/alarm_icon.png b/examples/0202/MyAndroidTutorial/app/src/main/res/drawable/alarm_icon.png
similarity index 100%
rename from examples/0202/MyAndroidTutorial/res/drawable/alarm_icon.png
rename to examples/0202/MyAndroidTutorial/app/src/main/res/drawable/alarm_icon.png
diff --git a/examples/0202/MyAndroidTutorial/res/drawable/location_icon.png b/examples/0202/MyAndroidTutorial/app/src/main/res/drawable/location_icon.png
similarity index 100%
rename from examples/0202/MyAndroidTutorial/res/drawable/location_icon.png
rename to examples/0202/MyAndroidTutorial/app/src/main/res/drawable/location_icon.png
diff --git a/examples/0202/MyAndroidTutorial/res/drawable/record_sound_icon.png b/examples/0202/MyAndroidTutorial/app/src/main/res/drawable/record_sound_icon.png
similarity index 100%
rename from examples/0202/MyAndroidTutorial/res/drawable/record_sound_icon.png
rename to examples/0202/MyAndroidTutorial/app/src/main/res/drawable/record_sound_icon.png
diff --git a/examples/0202/MyAndroidTutorial/app/src/main/res/drawable/retangle_drawable.xml b/examples/0202/MyAndroidTutorial/app/src/main/res/drawable/retangle_drawable.xml
new file mode 100644
index 0000000..51d1e84
--- /dev/null
+++ b/examples/0202/MyAndroidTutorial/app/src/main/res/drawable/retangle_drawable.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0202/MyAndroidTutorial/res/drawable/select_color_icon.png b/examples/0202/MyAndroidTutorial/app/src/main/res/drawable/select_color_icon.png
similarity index 100%
rename from examples/0202/MyAndroidTutorial/res/drawable/select_color_icon.png
rename to examples/0202/MyAndroidTutorial/app/src/main/res/drawable/select_color_icon.png
diff --git a/examples/0202/MyAndroidTutorial/res/drawable/take_picture_icon.png b/examples/0202/MyAndroidTutorial/app/src/main/res/drawable/take_picture_icon.png
similarity index 100%
rename from examples/0202/MyAndroidTutorial/res/drawable/take_picture_icon.png
rename to examples/0202/MyAndroidTutorial/app/src/main/res/drawable/take_picture_icon.png
diff --git a/examples/0202/MyAndroidTutorial/app/src/main/res/layout/activity_main.xml b/examples/0202/MyAndroidTutorial/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..2adcfdd
--- /dev/null
+++ b/examples/0202/MyAndroidTutorial/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
diff --git a/examples/0202/MyAndroidTutorial/app/src/main/res/menu/menu_main.xml b/examples/0202/MyAndroidTutorial/app/src/main/res/menu/menu_main.xml
new file mode 100644
index 0000000..7e74561
--- /dev/null
+++ b/examples/0202/MyAndroidTutorial/app/src/main/res/menu/menu_main.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
diff --git a/examples/0202/MyAndroidTutorial/app/src/main/res/values-en/strings.xml b/examples/0202/MyAndroidTutorial/app/src/main/res/values-en/strings.xml
new file mode 100644
index 0000000..c532533
--- /dev/null
+++ b/examples/0202/MyAndroidTutorial/app/src/main/res/values-en/strings.xml
@@ -0,0 +1,12 @@
+
+
+
+ MyAndroidTutorial
+ Hello world!
+ Settings
+
+ Title
+ Enter title
+ Content
+ Enter content
+
diff --git a/examples/0202/MyAndroidTutorial/app/src/main/res/values-w820dp/dimens.xml b/examples/0202/MyAndroidTutorial/app/src/main/res/values-w820dp/dimens.xml
new file mode 100644
index 0000000..63fc816
--- /dev/null
+++ b/examples/0202/MyAndroidTutorial/app/src/main/res/values-w820dp/dimens.xml
@@ -0,0 +1,6 @@
+
+
+ 64dp
+
diff --git a/examples/0202/MyAndroidTutorial/app/src/main/res/values/colors.xml b/examples/0202/MyAndroidTutorial/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..8d8f719
--- /dev/null
+++ b/examples/0202/MyAndroidTutorial/app/src/main/res/values/colors.xml
@@ -0,0 +1,6 @@
+
+
+ #CCCCCC
+ #AAAAAA
+ #DD999999
+
\ No newline at end of file
diff --git a/examples/0202/MyAndroidTutorial/app/src/main/res/values/dimens.xml b/examples/0202/MyAndroidTutorial/app/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..02898ec
--- /dev/null
+++ b/examples/0202/MyAndroidTutorial/app/src/main/res/values/dimens.xml
@@ -0,0 +1,9 @@
+
+
+ 16dp
+ 16dp
+
+ 6dp
+ 24sp
+ 2dp
+
diff --git a/examples/0202/MyAndroidTutorial/app/src/main/res/values/strings.xml b/examples/0202/MyAndroidTutorial/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..d07b4bc
--- /dev/null
+++ b/examples/0202/MyAndroidTutorial/app/src/main/res/values/strings.xml
@@ -0,0 +1,12 @@
+
+
+
+ MyAndroidTutorial
+ Hello world!
+ Settings
+
+ 標題
+ 輸入標題
+ 內容
+ 輸入內容
+
diff --git a/examples/0202/MyAndroidTutorial/app/src/main/res/values/styles.xml b/examples/0202/MyAndroidTutorial/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..766ab99
--- /dev/null
+++ b/examples/0202/MyAndroidTutorial/app/src/main/res/values/styles.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
diff --git a/examples/0202/MyAndroidTutorial/bin/AndroidManifest.xml b/examples/0202/MyAndroidTutorial/bin/AndroidManifest.xml
deleted file mode 100644
index 470193a..0000000
--- a/examples/0202/MyAndroidTutorial/bin/AndroidManifest.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/examples/0202/MyAndroidTutorial/bin/MyAndroidTutorial.apk b/examples/0202/MyAndroidTutorial/bin/MyAndroidTutorial.apk
deleted file mode 100644
index 87f53e6..0000000
Binary files a/examples/0202/MyAndroidTutorial/bin/MyAndroidTutorial.apk and /dev/null differ
diff --git a/examples/0202/MyAndroidTutorial/bin/classes.dex b/examples/0202/MyAndroidTutorial/bin/classes.dex
deleted file mode 100644
index a5f9d50..0000000
Binary files a/examples/0202/MyAndroidTutorial/bin/classes.dex and /dev/null differ
diff --git a/examples/0202/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/BuildConfig.class b/examples/0202/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/BuildConfig.class
deleted file mode 100644
index 30f5623..0000000
Binary files a/examples/0202/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/BuildConfig.class and /dev/null differ
diff --git a/examples/0202/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity.class b/examples/0202/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity.class
deleted file mode 100644
index ba61e55..0000000
Binary files a/examples/0202/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity.class and /dev/null differ
diff --git a/examples/0202/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$attr.class b/examples/0202/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$attr.class
deleted file mode 100644
index 9d83559..0000000
Binary files a/examples/0202/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$attr.class and /dev/null differ
diff --git a/examples/0202/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$color.class b/examples/0202/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$color.class
deleted file mode 100644
index 10fa364..0000000
Binary files a/examples/0202/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$color.class and /dev/null differ
diff --git a/examples/0202/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$dimen.class b/examples/0202/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$dimen.class
deleted file mode 100644
index 9361e88..0000000
Binary files a/examples/0202/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$dimen.class and /dev/null differ
diff --git a/examples/0202/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$drawable.class b/examples/0202/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$drawable.class
deleted file mode 100644
index cef044a..0000000
Binary files a/examples/0202/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$drawable.class and /dev/null differ
diff --git a/examples/0202/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$id.class b/examples/0202/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$id.class
deleted file mode 100644
index 52cc877..0000000
Binary files a/examples/0202/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$id.class and /dev/null differ
diff --git a/examples/0202/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$layout.class b/examples/0202/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$layout.class
deleted file mode 100644
index 7314cb4..0000000
Binary files a/examples/0202/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$layout.class and /dev/null differ
diff --git a/examples/0202/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$menu.class b/examples/0202/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$menu.class
deleted file mode 100644
index c5a6690..0000000
Binary files a/examples/0202/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$menu.class and /dev/null differ
diff --git a/examples/0202/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$string.class b/examples/0202/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$string.class
deleted file mode 100644
index 2780c96..0000000
Binary files a/examples/0202/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$string.class and /dev/null differ
diff --git a/examples/0202/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$style.class b/examples/0202/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$style.class
deleted file mode 100644
index 262d556..0000000
Binary files a/examples/0202/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$style.class and /dev/null differ
diff --git a/examples/0202/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R.class b/examples/0202/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R.class
deleted file mode 100644
index 3be8276..0000000
Binary files a/examples/0202/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R.class and /dev/null differ
diff --git a/examples/0202/MyAndroidTutorial/bin/dexedLibs/android-support-v4-9b1d5d28bf7d59a4e392b3d4f78c1f13.jar b/examples/0202/MyAndroidTutorial/bin/dexedLibs/android-support-v4-9b1d5d28bf7d59a4e392b3d4f78c1f13.jar
deleted file mode 100644
index 80a2884..0000000
Binary files a/examples/0202/MyAndroidTutorial/bin/dexedLibs/android-support-v4-9b1d5d28bf7d59a4e392b3d4f78c1f13.jar and /dev/null differ
diff --git a/examples/0202/MyAndroidTutorial/bin/jarlist.cache b/examples/0202/MyAndroidTutorial/bin/jarlist.cache
deleted file mode 100644
index 0565465..0000000
--- a/examples/0202/MyAndroidTutorial/bin/jarlist.cache
+++ /dev/null
@@ -1,3 +0,0 @@
-# cache for current jar dependency. DO NOT EDIT.
-# format is
-# Encoding is UTF-8
diff --git a/examples/0202/MyAndroidTutorial/bin/res/crunch/drawable-hdpi/ic_launcher.png b/examples/0202/MyAndroidTutorial/bin/res/crunch/drawable-hdpi/ic_launcher.png
deleted file mode 100644
index bcfa058..0000000
Binary files a/examples/0202/MyAndroidTutorial/bin/res/crunch/drawable-hdpi/ic_launcher.png and /dev/null differ
diff --git a/examples/0202/MyAndroidTutorial/bin/res/crunch/drawable-mdpi/ic_launcher.png b/examples/0202/MyAndroidTutorial/bin/res/crunch/drawable-mdpi/ic_launcher.png
deleted file mode 100644
index 85848ff..0000000
Binary files a/examples/0202/MyAndroidTutorial/bin/res/crunch/drawable-mdpi/ic_launcher.png and /dev/null differ
diff --git a/examples/0202/MyAndroidTutorial/bin/res/crunch/drawable-xhdpi/ic_launcher.png b/examples/0202/MyAndroidTutorial/bin/res/crunch/drawable-xhdpi/ic_launcher.png
deleted file mode 100644
index 916901e..0000000
Binary files a/examples/0202/MyAndroidTutorial/bin/res/crunch/drawable-xhdpi/ic_launcher.png and /dev/null differ
diff --git a/examples/0202/MyAndroidTutorial/bin/res/crunch/drawable/alarm_icon.png b/examples/0202/MyAndroidTutorial/bin/res/crunch/drawable/alarm_icon.png
deleted file mode 100644
index ebeae27..0000000
Binary files a/examples/0202/MyAndroidTutorial/bin/res/crunch/drawable/alarm_icon.png and /dev/null differ
diff --git a/examples/0202/MyAndroidTutorial/bin/res/crunch/drawable/location_icon.png b/examples/0202/MyAndroidTutorial/bin/res/crunch/drawable/location_icon.png
deleted file mode 100644
index 6897a97..0000000
Binary files a/examples/0202/MyAndroidTutorial/bin/res/crunch/drawable/location_icon.png and /dev/null differ
diff --git a/examples/0202/MyAndroidTutorial/bin/res/crunch/drawable/record_sound_icon.png b/examples/0202/MyAndroidTutorial/bin/res/crunch/drawable/record_sound_icon.png
deleted file mode 100644
index 6fe2060..0000000
Binary files a/examples/0202/MyAndroidTutorial/bin/res/crunch/drawable/record_sound_icon.png and /dev/null differ
diff --git a/examples/0202/MyAndroidTutorial/bin/res/crunch/drawable/select_color_icon.png b/examples/0202/MyAndroidTutorial/bin/res/crunch/drawable/select_color_icon.png
deleted file mode 100644
index 4270ec5..0000000
Binary files a/examples/0202/MyAndroidTutorial/bin/res/crunch/drawable/select_color_icon.png and /dev/null differ
diff --git a/examples/0202/MyAndroidTutorial/bin/res/crunch/drawable/take_picture_icon.png b/examples/0202/MyAndroidTutorial/bin/res/crunch/drawable/take_picture_icon.png
deleted file mode 100644
index c812e2f..0000000
Binary files a/examples/0202/MyAndroidTutorial/bin/res/crunch/drawable/take_picture_icon.png and /dev/null differ
diff --git a/examples/0202/MyAndroidTutorial/bin/resources.ap_ b/examples/0202/MyAndroidTutorial/bin/resources.ap_
deleted file mode 100644
index e948dbb..0000000
Binary files a/examples/0202/MyAndroidTutorial/bin/resources.ap_ and /dev/null differ
diff --git a/examples/0202/MyAndroidTutorial/build.gradle b/examples/0202/MyAndroidTutorial/build.gradle
new file mode 100644
index 0000000..6356aab
--- /dev/null
+++ b/examples/0202/MyAndroidTutorial/build.gradle
@@ -0,0 +1,19 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+ repositories {
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:1.0.0'
+
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+}
+
+allprojects {
+ repositories {
+ jcenter()
+ }
+}
diff --git a/examples/0202/MyAndroidTutorial/gen/net/macdidi/myandroidtutorial/BuildConfig.java b/examples/0202/MyAndroidTutorial/gen/net/macdidi/myandroidtutorial/BuildConfig.java
deleted file mode 100644
index 5d44ea9..0000000
--- a/examples/0202/MyAndroidTutorial/gen/net/macdidi/myandroidtutorial/BuildConfig.java
+++ /dev/null
@@ -1,6 +0,0 @@
-/** Automatically generated file. DO NOT MODIFY */
-package net.macdidi.myandroidtutorial;
-
-public final class BuildConfig {
- public final static boolean DEBUG = true;
-}
\ No newline at end of file
diff --git a/examples/0202/MyAndroidTutorial/gen/net/macdidi/myandroidtutorial/R.java b/examples/0202/MyAndroidTutorial/gen/net/macdidi/myandroidtutorial/R.java
deleted file mode 100644
index 8d56545..0000000
--- a/examples/0202/MyAndroidTutorial/gen/net/macdidi/myandroidtutorial/R.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/* AUTO-GENERATED FILE. DO NOT MODIFY.
- *
- * This class was automatically generated by the
- * aapt tool from the resource data it found. It
- * should not be modified by hand.
- */
-
-package net.macdidi.myandroidtutorial;
-
-public final class R {
- public static final class attr {
- }
- public static final class color {
- public static final int divider_color=0x7f040002;
- public static final int grey=0x7f040001;
- public static final int light_grey=0x7f040000;
- }
- public static final class dimen {
- public static final int default_margin=0x7f050001;
- public static final int default_padding=0x7f050000;
- public static final int title_txt_size=0x7f050002;
- }
- public static final class drawable {
- public static final int alarm_icon=0x7f020000;
- public static final int ic_launcher=0x7f020001;
- public static final int location_icon=0x7f020002;
- public static final int record_sound_icon=0x7f020003;
- public static final int retangle_drawable=0x7f020004;
- public static final int select_color_icon=0x7f020005;
- public static final int take_picture_icon=0x7f020006;
- }
- public static final class id {
- public static final int add_item=0x7f090002;
- public static final int delete_item=0x7f090004;
- public static final int facebook_item=0x7f090007;
- public static final int googleplus_item=0x7f090006;
- public static final int item_list=0x7f090000;
- public static final int revert_item=0x7f090003;
- public static final int search_item=0x7f090001;
- public static final int share_item=0x7f090005;
- }
- public static final class layout {
- public static final int activity_main=0x7f030000;
- }
- public static final class menu {
- public static final int main_menu=0x7f080000;
- }
- public static final class string {
- public static final int app_name=0x7f060000;
- public static final int content=0x7f060005;
- public static final int enter_content=0x7f060006;
- public static final int enter_title=0x7f060004;
- public static final int hello_world=0x7f060002;
- public static final int title=0x7f060003;
- public static final int title_activity_main=0x7f060001;
- }
- public static final class style {
- /**
- Base application theme, dependent on API level. This theme is replaced
- by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
-
-
- Theme customizations available in newer API levels can go in
- res/values-vXX/styles.xml, while customizations related to
- backward-compatibility can go here.
-
-
- Base application theme for API 11+. This theme completely replaces
- AppBaseTheme from res/values/styles.xml on API 11+ devices.
-
- API 11 theme customizations can go here.
-
- Base application theme for API 14+. This theme completely replaces
- AppBaseTheme from BOTH res/values/styles.xml and
- res/values-v11/styles.xml on API 14+ devices.
-
- API 14 theme customizations can go here.
- */
- public static final int AppBaseTheme=0x7f070000;
- /** Application theme.
- All customizations that are NOT specific to a particular API-level can go here.
- */
- public static final int AppTheme=0x7f070001;
- }
-}
diff --git a/examples/0202/MyAndroidTutorial/gradle.properties b/examples/0202/MyAndroidTutorial/gradle.properties
new file mode 100644
index 0000000..1d3591c
--- /dev/null
+++ b/examples/0202/MyAndroidTutorial/gradle.properties
@@ -0,0 +1,18 @@
+# Project-wide Gradle settings.
+
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+# Default value: -Xmx10248m -XX:MaxPermSize=256m
+# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
+
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
\ No newline at end of file
diff --git a/examples/0202/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.jar b/examples/0202/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
Binary files /dev/null and b/examples/0202/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/examples/0202/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.properties b/examples/0202/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..0c71e76
--- /dev/null
+++ b/examples/0202/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
diff --git a/examples/0202/MyAndroidTutorial/gradlew b/examples/0202/MyAndroidTutorial/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/examples/0202/MyAndroidTutorial/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/examples/0202/MyAndroidTutorial/gradlew.bat b/examples/0202/MyAndroidTutorial/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/examples/0202/MyAndroidTutorial/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/examples/0202/MyAndroidTutorial/libs/android-support-v4.jar b/examples/0202/MyAndroidTutorial/libs/android-support-v4.jar
deleted file mode 100644
index 187bdf4..0000000
Binary files a/examples/0202/MyAndroidTutorial/libs/android-support-v4.jar and /dev/null differ
diff --git a/examples/0202/MyAndroidTutorial/proguard-project.txt b/examples/0202/MyAndroidTutorial/proguard-project.txt
deleted file mode 100644
index f2fe155..0000000
--- a/examples/0202/MyAndroidTutorial/proguard-project.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-# To enable ProGuard in your project, edit project.properties
-# to define the proguard.config property as described in that file.
-#
-# Add project specific ProGuard rules here.
-# By default, the flags in this file are appended to flags specified
-# in ${sdk.dir}/tools/proguard/proguard-android.txt
-# You can edit the include path and order by changing the ProGuard
-# include property in project.properties.
-#
-# For more details, see
-# http://developer.android.com/guide/developing/tools/proguard.html
-
-# Add any project specific keep options here:
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-# public *;
-#}
diff --git a/examples/0202/MyAndroidTutorial/project.properties b/examples/0202/MyAndroidTutorial/project.properties
deleted file mode 100644
index 4ab1256..0000000
--- a/examples/0202/MyAndroidTutorial/project.properties
+++ /dev/null
@@ -1,14 +0,0 @@
-# This file is automatically generated by Android Tools.
-# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
-#
-# This file must be checked in Version Control Systems.
-#
-# To customize properties used by the Ant build system edit
-# "ant.properties", and override values to adapt the script to your
-# project structure.
-#
-# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
-#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
-
-# Project target.
-target=android-19
diff --git a/examples/0202/MyAndroidTutorial/res/drawable/retangle_drawable.xml b/examples/0202/MyAndroidTutorial/res/drawable/retangle_drawable.xml
deleted file mode 100644
index e195342..0000000
--- a/examples/0202/MyAndroidTutorial/res/drawable/retangle_drawable.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/examples/0202/MyAndroidTutorial/res/layout/activity_main.xml b/examples/0202/MyAndroidTutorial/res/layout/activity_main.xml
deleted file mode 100644
index d0b752c..0000000
--- a/examples/0202/MyAndroidTutorial/res/layout/activity_main.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
-
-
-
-
-
-
diff --git a/examples/0202/MyAndroidTutorial/res/menu/main_menu.xml b/examples/0202/MyAndroidTutorial/res/menu/main_menu.xml
deleted file mode 100644
index 4bfad8e..0000000
--- a/examples/0202/MyAndroidTutorial/res/menu/main_menu.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/examples/0202/MyAndroidTutorial/res/values-en/strings.xml b/examples/0202/MyAndroidTutorial/res/values-en/strings.xml
deleted file mode 100644
index 34f4fed..0000000
--- a/examples/0202/MyAndroidTutorial/res/values-en/strings.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
- MyAndroidTutorial
- MainActivity
- Hello world!
-
- Title
- Enter title
- Content
- Enter content
-
-
diff --git a/examples/0202/MyAndroidTutorial/res/values-v11/styles.xml b/examples/0202/MyAndroidTutorial/res/values-v11/styles.xml
deleted file mode 100644
index 3c02242..0000000
--- a/examples/0202/MyAndroidTutorial/res/values-v11/styles.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
diff --git a/examples/0202/MyAndroidTutorial/res/values-v14/styles.xml b/examples/0202/MyAndroidTutorial/res/values-v14/styles.xml
deleted file mode 100644
index a91fd03..0000000
--- a/examples/0202/MyAndroidTutorial/res/values-v14/styles.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
diff --git a/examples/0202/MyAndroidTutorial/res/values/colors.xml b/examples/0202/MyAndroidTutorial/res/values/colors.xml
deleted file mode 100644
index c7b5d95..0000000
--- a/examples/0202/MyAndroidTutorial/res/values/colors.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
- #CCCCCC
- #AAAAAA
- #DDCCCCCC
-
diff --git a/examples/0202/MyAndroidTutorial/res/values/dimens.xml b/examples/0202/MyAndroidTutorial/res/values/dimens.xml
deleted file mode 100644
index fb03071..0000000
--- a/examples/0202/MyAndroidTutorial/res/values/dimens.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
- 6dp
- 2dp
- 24sp
-
diff --git a/examples/0202/MyAndroidTutorial/res/values/strings.xml b/examples/0202/MyAndroidTutorial/res/values/strings.xml
deleted file mode 100644
index b879ab4..0000000
--- a/examples/0202/MyAndroidTutorial/res/values/strings.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
- MyAndroidTutorial
- MainActivity
- Hello world!
-
- 標題
- 輸入標題
- 內容
- 輸入內容
-
-
diff --git a/examples/0202/MyAndroidTutorial/res/values/styles.xml b/examples/0202/MyAndroidTutorial/res/values/styles.xml
deleted file mode 100644
index 6ce89c7..0000000
--- a/examples/0202/MyAndroidTutorial/res/values/styles.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
-
-
-
-
-
-
diff --git a/examples/0202/MyAndroidTutorial/settings.gradle b/examples/0202/MyAndroidTutorial/settings.gradle
new file mode 100644
index 0000000..e7b4def
--- /dev/null
+++ b/examples/0202/MyAndroidTutorial/settings.gradle
@@ -0,0 +1 @@
+include ':app'
diff --git a/examples/0202/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/MainActivity.java b/examples/0202/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/MainActivity.java
deleted file mode 100644
index e83a859..0000000
--- a/examples/0202/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/MainActivity.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package net.macdidi.myandroidtutorial;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.widget.ArrayAdapter;
-import android.widget.ListView;
-
-public class MainActivity extends Activity {
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- // 為ListView元件設定三筆資料
- String[] data = {
- "關於Android Tutorial的事情",
- "一隻非常可愛的小狗狗!",
- "一首非常好聽的音樂!"};
- int layoutId = android.R.layout.simple_list_item_1;
- ArrayAdapter adapter =
- new ArrayAdapter(this, layoutId, data);
- ListView item_list = (ListView)findViewById(R.id.item_list);
- item_list.setAdapter(adapter);
- }
-
- // 載入選單資源
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- MenuInflater menuInflater = getMenuInflater();
- menuInflater.inflate(R.menu.main_menu, menu);
- return true;
- }
-}
diff --git a/examples/0203/MyAndroidTutorial/.classpath b/examples/0203/MyAndroidTutorial/.classpath
deleted file mode 100644
index 7bc01d9..0000000
--- a/examples/0203/MyAndroidTutorial/.classpath
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
-
-
-
-
diff --git a/examples/0203/MyAndroidTutorial/.gitignore b/examples/0203/MyAndroidTutorial/.gitignore
new file mode 100644
index 0000000..afbdab3
--- /dev/null
+++ b/examples/0203/MyAndroidTutorial/.gitignore
@@ -0,0 +1,6 @@
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
diff --git a/examples/0203/MyAndroidTutorial/.idea/.name b/examples/0203/MyAndroidTutorial/.idea/.name
new file mode 100644
index 0000000..5bb7a85
--- /dev/null
+++ b/examples/0203/MyAndroidTutorial/.idea/.name
@@ -0,0 +1 @@
+MyAndroidTutorial
\ No newline at end of file
diff --git a/examples/0203/MyAndroidTutorial/.idea/compiler.xml b/examples/0203/MyAndroidTutorial/.idea/compiler.xml
new file mode 100644
index 0000000..217af47
--- /dev/null
+++ b/examples/0203/MyAndroidTutorial/.idea/compiler.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0203/MyAndroidTutorial/.idea/copyright/profiles_settings.xml b/examples/0203/MyAndroidTutorial/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..e7bedf3
--- /dev/null
+++ b/examples/0203/MyAndroidTutorial/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/examples/0203/MyAndroidTutorial/.idea/encodings.xml b/examples/0203/MyAndroidTutorial/.idea/encodings.xml
new file mode 100644
index 0000000..e206d70
--- /dev/null
+++ b/examples/0203/MyAndroidTutorial/.idea/encodings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/examples/0203/MyAndroidTutorial/.idea/gradle.xml b/examples/0203/MyAndroidTutorial/.idea/gradle.xml
new file mode 100644
index 0000000..fe865d3
--- /dev/null
+++ b/examples/0203/MyAndroidTutorial/.idea/gradle.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0203/MyAndroidTutorial/.idea/misc.xml b/examples/0203/MyAndroidTutorial/.idea/misc.xml
new file mode 100644
index 0000000..9076de5
--- /dev/null
+++ b/examples/0203/MyAndroidTutorial/.idea/misc.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0203/MyAndroidTutorial/.idea/modules.xml b/examples/0203/MyAndroidTutorial/.idea/modules.xml
new file mode 100644
index 0000000..327df67
--- /dev/null
+++ b/examples/0203/MyAndroidTutorial/.idea/modules.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0203/MyAndroidTutorial/.idea/scopes/scope_settings.xml b/examples/0203/MyAndroidTutorial/.idea/scopes/scope_settings.xml
new file mode 100644
index 0000000..922003b
--- /dev/null
+++ b/examples/0203/MyAndroidTutorial/.idea/scopes/scope_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0203/MyAndroidTutorial/.idea/vcs.xml b/examples/0203/MyAndroidTutorial/.idea/vcs.xml
new file mode 100644
index 0000000..def6a6a
--- /dev/null
+++ b/examples/0203/MyAndroidTutorial/.idea/vcs.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/examples/0203/MyAndroidTutorial/.project b/examples/0203/MyAndroidTutorial/.project
deleted file mode 100644
index b1de407..0000000
--- a/examples/0203/MyAndroidTutorial/.project
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
- MyAndroidTutorial
-
-
-
-
-
- com.android.ide.eclipse.adt.ResourceManagerBuilder
-
-
-
-
- com.android.ide.eclipse.adt.PreCompilerBuilder
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- com.android.ide.eclipse.adt.ApkBuilder
-
-
-
-
-
- com.android.ide.eclipse.adt.AndroidNature
- org.eclipse.jdt.core.javanature
-
-
diff --git a/examples/0203/MyAndroidTutorial/AndroidManifest.xml b/examples/0203/MyAndroidTutorial/AndroidManifest.xml
deleted file mode 100644
index 470193a..0000000
--- a/examples/0203/MyAndroidTutorial/AndroidManifest.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/examples/0203/MyAndroidTutorial/MyAndroidTutorial.iml b/examples/0203/MyAndroidTutorial/MyAndroidTutorial.iml
new file mode 100644
index 0000000..2a02201
--- /dev/null
+++ b/examples/0203/MyAndroidTutorial/MyAndroidTutorial.iml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0203/MyAndroidTutorial/app/.gitignore b/examples/0203/MyAndroidTutorial/app/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/examples/0203/MyAndroidTutorial/app/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/examples/0203/MyAndroidTutorial/app/app.iml b/examples/0203/MyAndroidTutorial/app/app.iml
new file mode 100644
index 0000000..c6c55c4
--- /dev/null
+++ b/examples/0203/MyAndroidTutorial/app/app.iml
@@ -0,0 +1,91 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0203/MyAndroidTutorial/app/build.gradle b/examples/0203/MyAndroidTutorial/app/build.gradle
new file mode 100644
index 0000000..b09f064
--- /dev/null
+++ b/examples/0203/MyAndroidTutorial/app/build.gradle
@@ -0,0 +1,25 @@
+apply plugin: 'com.android.application'
+
+android {
+ compileSdkVersion 21
+ buildToolsVersion "21.1.2"
+
+ defaultConfig {
+ applicationId "net.macdidi.myandroidtutorial"
+ minSdkVersion 15
+ targetSdkVersion 21
+ versionCode 1
+ versionName "1.0"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ compile fileTree(dir: 'libs', include: ['*.jar'])
+ compile 'com.android.support:appcompat-v7:21.0.3'
+}
diff --git a/examples/0203/MyAndroidTutorial/app/proguard-rules.pro b/examples/0203/MyAndroidTutorial/app/proguard-rules.pro
new file mode 100644
index 0000000..b5fa7ec
--- /dev/null
+++ b/examples/0203/MyAndroidTutorial/app/proguard-rules.pro
@@ -0,0 +1,17 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /Users/macdidi5/Library/Android/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
diff --git a/examples/0203/MyAndroidTutorial/app/src/androidTest/java/net/macdidi/myandroidtutorial/ApplicationTest.java b/examples/0203/MyAndroidTutorial/app/src/androidTest/java/net/macdidi/myandroidtutorial/ApplicationTest.java
new file mode 100644
index 0000000..2cb214e
--- /dev/null
+++ b/examples/0203/MyAndroidTutorial/app/src/androidTest/java/net/macdidi/myandroidtutorial/ApplicationTest.java
@@ -0,0 +1,13 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Application;
+import android.test.ApplicationTestCase;
+
+/**
+ * Testing Fundamentals
+ */
+public class ApplicationTest extends ApplicationTestCase {
+ public ApplicationTest() {
+ super(Application.class);
+ }
+}
\ No newline at end of file
diff --git a/examples/0203/MyAndroidTutorial/app/src/main/AndroidManifest.xml b/examples/0203/MyAndroidTutorial/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..c325305
--- /dev/null
+++ b/examples/0203/MyAndroidTutorial/app/src/main/AndroidManifest.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0203/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MainActivity.java b/examples/0203/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MainActivity.java
new file mode 100644
index 0000000..9d263f9
--- /dev/null
+++ b/examples/0203/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MainActivity.java
@@ -0,0 +1,148 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.AlertDialog;
+import android.os.Bundle;
+import android.support.v7.app.ActionBarActivity;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+import android.widget.TextView;
+import android.widget.Toast;
+
+public class MainActivity extends ActionBarActivity {
+ private ListView item_list;
+ private TextView show_app_name;
+
+ private static final String[] data = {
+ "關於Android Tutorial的事情",
+ "一隻非常可愛的小狗狗!",
+ "一首非常好聽的音樂!"};
+ private ArrayAdapter adapter;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ processViews();
+ processControllers();
+
+ int layoutId = android.R.layout.simple_list_item_1;
+ adapter = new ArrayAdapter(this, layoutId, data);
+ item_list.setAdapter(adapter);
+ }
+
+ private void processViews() {
+ item_list = (ListView)findViewById(R.id.item_list);
+ show_app_name = (TextView) findViewById(R.id.show_app_name);
+ }
+
+ private void processControllers() {
+ // 建立選單項目點擊監聽物件
+ AdapterView.OnItemClickListener itemListener = new AdapterView.OnItemClickListener() {
+ // 第一個參數是使用者操作的ListView物件
+ // 第二個參數是使用者選擇的項目
+ // 第三個參數是使用者選擇的項目編號,第一個是0
+ // 第四個參數在這裡沒有用途
+ @Override
+ public void onItemClick(AdapterView> parent, View view,
+ int position, long id) {
+ Toast.makeText(MainActivity.this,
+ data[position], Toast.LENGTH_LONG).show();
+ }
+ };
+
+ // 註冊選單項目點擊監聽物件
+ item_list.setOnItemClickListener(itemListener);
+
+ // 建立選單項目長按監聽物件
+ AdapterView.OnItemLongClickListener itemLongListener = new AdapterView.OnItemLongClickListener() {
+ // 第一個參數是使用者操作的ListView物件
+ // 第二個參數是使用者選擇的項目
+ // 第三個參數是使用者選擇的項目編號,第一個是0
+ // 第四個參數在這裡沒有用途
+ @Override
+ public boolean onItemLongClick(AdapterView> parent, View view,
+ int position, long id) {
+ Toast.makeText(MainActivity.this,
+ "Long: " + data[position], Toast.LENGTH_LONG).show();
+ return false;
+ }
+ };
+
+ // 註冊選單項目長按監聽物件
+ item_list.setOnItemLongClickListener(itemLongListener);
+
+ // 建立長按監聽物件
+ View.OnLongClickListener listener = new View.OnLongClickListener() {
+
+ @Override
+ public boolean onLongClick(View view) {
+ AlertDialog.Builder dialog =
+ new AlertDialog.Builder(MainActivity.this);
+ dialog.setTitle(R.string.app_name)
+ .setMessage(R.string.about)
+ .show();
+ return false;
+ }
+
+ };
+
+ // 註冊長按監聽物件
+ show_app_name.setOnLongClickListener(listener);
+ }
+
+ // 載入選單資源
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ MenuInflater menuInflater = getMenuInflater();
+ menuInflater.inflate(R.menu.menu_main, menu);
+ return true;
+ }
+
+ // 使用者選擇所有的選單項目都會呼叫這個方法
+ public void clickMenuItem(MenuItem item) {
+ // 使用參數取得使用者選擇的選單項目元件編號
+ int itemId = item.getItemId();
+
+ // 判斷該執行什麼工作,目前還沒有加入需要執行的工作
+ switch (itemId) {
+ case R.id.search_item:
+ break;
+ case R.id.add_item:
+ break;
+ case R.id.revert_item:
+ break;
+ case R.id.delete_item:
+ break;
+ case R.id.googleplus_item:
+ break;
+ case R.id.facebook_item:
+ break;
+ }
+
+ // 測試用的程式碼,完成測試後記得移除
+ AlertDialog.Builder dialog =
+ new AlertDialog.Builder(MainActivity.this);
+ dialog.setTitle("MenuItem Test")
+ .setMessage(item.getTitle())
+ .setIcon(item.getIcon())
+ .show();
+ }
+
+ // 方法名稱與onClick的設定一樣,參數的型態是android.view.View
+ public void aboutApp(View view) {
+ // 顯示訊息框
+ // Context:通常指定為「this」;如果在巢狀類別中使用,要加上這個Activity元件類別的名稱,例如「元件類別名稱.this」
+ // String或int:設定顯示在訊息框裡面的訊息或文字資源
+ // int:設定訊息框停留在畫面的時間,使用宣告在Toast類別中的變數,可以設定為「LENGTH_LONG」和「LENGTH_SHORT」
+ Toast.makeText(this, R.string.app_name, Toast.LENGTH_LONG).show();
+ }
+
+}
+
+
diff --git a/examples/0203/MyAndroidTutorial/res/drawable-hdpi/ic_launcher.png b/examples/0203/MyAndroidTutorial/app/src/main/res/drawable-hdpi/ic_launcher.png
similarity index 100%
rename from examples/0203/MyAndroidTutorial/res/drawable-hdpi/ic_launcher.png
rename to examples/0203/MyAndroidTutorial/app/src/main/res/drawable-hdpi/ic_launcher.png
diff --git a/examples/0203/MyAndroidTutorial/res/drawable-mdpi/ic_launcher.png b/examples/0203/MyAndroidTutorial/app/src/main/res/drawable-mdpi/ic_launcher.png
similarity index 100%
rename from examples/0203/MyAndroidTutorial/res/drawable-mdpi/ic_launcher.png
rename to examples/0203/MyAndroidTutorial/app/src/main/res/drawable-mdpi/ic_launcher.png
diff --git a/examples/0203/MyAndroidTutorial/res/drawable-xhdpi/ic_launcher.png b/examples/0203/MyAndroidTutorial/app/src/main/res/drawable-xhdpi/ic_launcher.png
similarity index 100%
rename from examples/0203/MyAndroidTutorial/res/drawable-xhdpi/ic_launcher.png
rename to examples/0203/MyAndroidTutorial/app/src/main/res/drawable-xhdpi/ic_launcher.png
diff --git a/examples/0203/MyAndroidTutorial/app/src/main/res/drawable-xxhdpi/ic_launcher.png b/examples/0203/MyAndroidTutorial/app/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..4df1894
Binary files /dev/null and b/examples/0203/MyAndroidTutorial/app/src/main/res/drawable-xxhdpi/ic_launcher.png differ
diff --git a/examples/0203/MyAndroidTutorial/res/drawable/alarm_icon.png b/examples/0203/MyAndroidTutorial/app/src/main/res/drawable/alarm_icon.png
similarity index 100%
rename from examples/0203/MyAndroidTutorial/res/drawable/alarm_icon.png
rename to examples/0203/MyAndroidTutorial/app/src/main/res/drawable/alarm_icon.png
diff --git a/examples/0203/MyAndroidTutorial/res/drawable/location_icon.png b/examples/0203/MyAndroidTutorial/app/src/main/res/drawable/location_icon.png
similarity index 100%
rename from examples/0203/MyAndroidTutorial/res/drawable/location_icon.png
rename to examples/0203/MyAndroidTutorial/app/src/main/res/drawable/location_icon.png
diff --git a/examples/0203/MyAndroidTutorial/res/drawable/record_sound_icon.png b/examples/0203/MyAndroidTutorial/app/src/main/res/drawable/record_sound_icon.png
similarity index 100%
rename from examples/0203/MyAndroidTutorial/res/drawable/record_sound_icon.png
rename to examples/0203/MyAndroidTutorial/app/src/main/res/drawable/record_sound_icon.png
diff --git a/examples/0203/MyAndroidTutorial/app/src/main/res/drawable/retangle_drawable.xml b/examples/0203/MyAndroidTutorial/app/src/main/res/drawable/retangle_drawable.xml
new file mode 100644
index 0000000..51d1e84
--- /dev/null
+++ b/examples/0203/MyAndroidTutorial/app/src/main/res/drawable/retangle_drawable.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0203/MyAndroidTutorial/res/drawable/select_color_icon.png b/examples/0203/MyAndroidTutorial/app/src/main/res/drawable/select_color_icon.png
similarity index 100%
rename from examples/0203/MyAndroidTutorial/res/drawable/select_color_icon.png
rename to examples/0203/MyAndroidTutorial/app/src/main/res/drawable/select_color_icon.png
diff --git a/examples/0203/MyAndroidTutorial/res/drawable/take_picture_icon.png b/examples/0203/MyAndroidTutorial/app/src/main/res/drawable/take_picture_icon.png
similarity index 100%
rename from examples/0203/MyAndroidTutorial/res/drawable/take_picture_icon.png
rename to examples/0203/MyAndroidTutorial/app/src/main/res/drawable/take_picture_icon.png
diff --git a/examples/0203/MyAndroidTutorial/app/src/main/res/layout/activity_main.xml b/examples/0203/MyAndroidTutorial/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..121511b
--- /dev/null
+++ b/examples/0203/MyAndroidTutorial/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
diff --git a/examples/0203/MyAndroidTutorial/app/src/main/res/menu/menu_main.xml b/examples/0203/MyAndroidTutorial/app/src/main/res/menu/menu_main.xml
new file mode 100644
index 0000000..024de57
--- /dev/null
+++ b/examples/0203/MyAndroidTutorial/app/src/main/res/menu/menu_main.xml
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
diff --git a/examples/0203/MyAndroidTutorial/app/src/main/res/values-en/strings.xml b/examples/0203/MyAndroidTutorial/app/src/main/res/values-en/strings.xml
new file mode 100644
index 0000000..c532533
--- /dev/null
+++ b/examples/0203/MyAndroidTutorial/app/src/main/res/values-en/strings.xml
@@ -0,0 +1,12 @@
+
+
+
+ MyAndroidTutorial
+ Hello world!
+ Settings
+
+ Title
+ Enter title
+ Content
+ Enter content
+
diff --git a/examples/0203/MyAndroidTutorial/app/src/main/res/values-w820dp/dimens.xml b/examples/0203/MyAndroidTutorial/app/src/main/res/values-w820dp/dimens.xml
new file mode 100644
index 0000000..63fc816
--- /dev/null
+++ b/examples/0203/MyAndroidTutorial/app/src/main/res/values-w820dp/dimens.xml
@@ -0,0 +1,6 @@
+
+
+ 64dp
+
diff --git a/examples/0203/MyAndroidTutorial/app/src/main/res/values/colors.xml b/examples/0203/MyAndroidTutorial/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..8d8f719
--- /dev/null
+++ b/examples/0203/MyAndroidTutorial/app/src/main/res/values/colors.xml
@@ -0,0 +1,6 @@
+
+
+ #CCCCCC
+ #AAAAAA
+ #DD999999
+
\ No newline at end of file
diff --git a/examples/0203/MyAndroidTutorial/app/src/main/res/values/dimens.xml b/examples/0203/MyAndroidTutorial/app/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..02898ec
--- /dev/null
+++ b/examples/0203/MyAndroidTutorial/app/src/main/res/values/dimens.xml
@@ -0,0 +1,9 @@
+
+
+ 16dp
+ 16dp
+
+ 6dp
+ 24sp
+ 2dp
+
diff --git a/examples/0203/MyAndroidTutorial/app/src/main/res/values/strings.xml b/examples/0203/MyAndroidTutorial/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..31ebfd1
--- /dev/null
+++ b/examples/0203/MyAndroidTutorial/app/src/main/res/values/strings.xml
@@ -0,0 +1,14 @@
+
+
+
+ MyAndroidTutorial
+ Hello world!
+ Settings
+
+ 標題
+ 輸入標題
+ 內容
+ 輸入內容
+
+ 這是Android Tutorial應用程式
+
diff --git a/examples/0203/MyAndroidTutorial/app/src/main/res/values/styles.xml b/examples/0203/MyAndroidTutorial/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..766ab99
--- /dev/null
+++ b/examples/0203/MyAndroidTutorial/app/src/main/res/values/styles.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
diff --git a/examples/0203/MyAndroidTutorial/bin/AndroidManifest.xml b/examples/0203/MyAndroidTutorial/bin/AndroidManifest.xml
deleted file mode 100644
index 470193a..0000000
--- a/examples/0203/MyAndroidTutorial/bin/AndroidManifest.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/examples/0203/MyAndroidTutorial/bin/MyAndroidTutorial.apk b/examples/0203/MyAndroidTutorial/bin/MyAndroidTutorial.apk
deleted file mode 100644
index 550ab92..0000000
Binary files a/examples/0203/MyAndroidTutorial/bin/MyAndroidTutorial.apk and /dev/null differ
diff --git a/examples/0203/MyAndroidTutorial/bin/classes.dex b/examples/0203/MyAndroidTutorial/bin/classes.dex
deleted file mode 100644
index 6cdeba1..0000000
Binary files a/examples/0203/MyAndroidTutorial/bin/classes.dex and /dev/null differ
diff --git a/examples/0203/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/BuildConfig.class b/examples/0203/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/BuildConfig.class
deleted file mode 100644
index 30f5623..0000000
Binary files a/examples/0203/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/BuildConfig.class and /dev/null differ
diff --git a/examples/0203/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$1.class b/examples/0203/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$1.class
deleted file mode 100644
index 1a97015..0000000
Binary files a/examples/0203/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$1.class and /dev/null differ
diff --git a/examples/0203/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$2.class b/examples/0203/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$2.class
deleted file mode 100644
index 50556f9..0000000
Binary files a/examples/0203/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$2.class and /dev/null differ
diff --git a/examples/0203/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$3.class b/examples/0203/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$3.class
deleted file mode 100644
index b24751b..0000000
Binary files a/examples/0203/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$3.class and /dev/null differ
diff --git a/examples/0203/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity.class b/examples/0203/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity.class
deleted file mode 100644
index 813b51e..0000000
Binary files a/examples/0203/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity.class and /dev/null differ
diff --git a/examples/0203/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$attr.class b/examples/0203/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$attr.class
deleted file mode 100644
index 9d83559..0000000
Binary files a/examples/0203/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$attr.class and /dev/null differ
diff --git a/examples/0203/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$color.class b/examples/0203/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$color.class
deleted file mode 100644
index 10fa364..0000000
Binary files a/examples/0203/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$color.class and /dev/null differ
diff --git a/examples/0203/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$dimen.class b/examples/0203/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$dimen.class
deleted file mode 100644
index 9361e88..0000000
Binary files a/examples/0203/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$dimen.class and /dev/null differ
diff --git a/examples/0203/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$drawable.class b/examples/0203/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$drawable.class
deleted file mode 100644
index cef044a..0000000
Binary files a/examples/0203/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$drawable.class and /dev/null differ
diff --git a/examples/0203/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$id.class b/examples/0203/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$id.class
deleted file mode 100644
index cd5b83b..0000000
Binary files a/examples/0203/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$id.class and /dev/null differ
diff --git a/examples/0203/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$layout.class b/examples/0203/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$layout.class
deleted file mode 100644
index a409dec..0000000
Binary files a/examples/0203/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$layout.class and /dev/null differ
diff --git a/examples/0203/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$menu.class b/examples/0203/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$menu.class
deleted file mode 100644
index 365b3fa..0000000
Binary files a/examples/0203/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$menu.class and /dev/null differ
diff --git a/examples/0203/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$string.class b/examples/0203/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$string.class
deleted file mode 100644
index bc3126f..0000000
Binary files a/examples/0203/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$string.class and /dev/null differ
diff --git a/examples/0203/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$style.class b/examples/0203/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$style.class
deleted file mode 100644
index 3b98e1e..0000000
Binary files a/examples/0203/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$style.class and /dev/null differ
diff --git a/examples/0203/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R.class b/examples/0203/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R.class
deleted file mode 100644
index 3be8276..0000000
Binary files a/examples/0203/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R.class and /dev/null differ
diff --git a/examples/0203/MyAndroidTutorial/bin/dexedLibs/android-support-v4-9b1d5d28bf7d59a4e392b3d4f78c1f13.jar b/examples/0203/MyAndroidTutorial/bin/dexedLibs/android-support-v4-9b1d5d28bf7d59a4e392b3d4f78c1f13.jar
deleted file mode 100644
index 80a2884..0000000
Binary files a/examples/0203/MyAndroidTutorial/bin/dexedLibs/android-support-v4-9b1d5d28bf7d59a4e392b3d4f78c1f13.jar and /dev/null differ
diff --git a/examples/0203/MyAndroidTutorial/bin/jarlist.cache b/examples/0203/MyAndroidTutorial/bin/jarlist.cache
deleted file mode 100644
index 0565465..0000000
--- a/examples/0203/MyAndroidTutorial/bin/jarlist.cache
+++ /dev/null
@@ -1,3 +0,0 @@
-# cache for current jar dependency. DO NOT EDIT.
-# format is
-# Encoding is UTF-8
diff --git a/examples/0203/MyAndroidTutorial/bin/res/crunch/drawable-hdpi/ic_launcher.png b/examples/0203/MyAndroidTutorial/bin/res/crunch/drawable-hdpi/ic_launcher.png
deleted file mode 100644
index bcfa058..0000000
Binary files a/examples/0203/MyAndroidTutorial/bin/res/crunch/drawable-hdpi/ic_launcher.png and /dev/null differ
diff --git a/examples/0203/MyAndroidTutorial/bin/res/crunch/drawable-mdpi/ic_launcher.png b/examples/0203/MyAndroidTutorial/bin/res/crunch/drawable-mdpi/ic_launcher.png
deleted file mode 100644
index 85848ff..0000000
Binary files a/examples/0203/MyAndroidTutorial/bin/res/crunch/drawable-mdpi/ic_launcher.png and /dev/null differ
diff --git a/examples/0203/MyAndroidTutorial/bin/res/crunch/drawable-xhdpi/ic_launcher.png b/examples/0203/MyAndroidTutorial/bin/res/crunch/drawable-xhdpi/ic_launcher.png
deleted file mode 100644
index 916901e..0000000
Binary files a/examples/0203/MyAndroidTutorial/bin/res/crunch/drawable-xhdpi/ic_launcher.png and /dev/null differ
diff --git a/examples/0203/MyAndroidTutorial/bin/res/crunch/drawable/alarm_icon.png b/examples/0203/MyAndroidTutorial/bin/res/crunch/drawable/alarm_icon.png
deleted file mode 100644
index ebeae27..0000000
Binary files a/examples/0203/MyAndroidTutorial/bin/res/crunch/drawable/alarm_icon.png and /dev/null differ
diff --git a/examples/0203/MyAndroidTutorial/bin/res/crunch/drawable/location_icon.png b/examples/0203/MyAndroidTutorial/bin/res/crunch/drawable/location_icon.png
deleted file mode 100644
index 6897a97..0000000
Binary files a/examples/0203/MyAndroidTutorial/bin/res/crunch/drawable/location_icon.png and /dev/null differ
diff --git a/examples/0203/MyAndroidTutorial/bin/res/crunch/drawable/record_sound_icon.png b/examples/0203/MyAndroidTutorial/bin/res/crunch/drawable/record_sound_icon.png
deleted file mode 100644
index 6fe2060..0000000
Binary files a/examples/0203/MyAndroidTutorial/bin/res/crunch/drawable/record_sound_icon.png and /dev/null differ
diff --git a/examples/0203/MyAndroidTutorial/bin/res/crunch/drawable/select_color_icon.png b/examples/0203/MyAndroidTutorial/bin/res/crunch/drawable/select_color_icon.png
deleted file mode 100644
index 4270ec5..0000000
Binary files a/examples/0203/MyAndroidTutorial/bin/res/crunch/drawable/select_color_icon.png and /dev/null differ
diff --git a/examples/0203/MyAndroidTutorial/bin/res/crunch/drawable/take_picture_icon.png b/examples/0203/MyAndroidTutorial/bin/res/crunch/drawable/take_picture_icon.png
deleted file mode 100644
index c812e2f..0000000
Binary files a/examples/0203/MyAndroidTutorial/bin/res/crunch/drawable/take_picture_icon.png and /dev/null differ
diff --git a/examples/0203/MyAndroidTutorial/bin/resources.ap_ b/examples/0203/MyAndroidTutorial/bin/resources.ap_
deleted file mode 100644
index a167be3..0000000
Binary files a/examples/0203/MyAndroidTutorial/bin/resources.ap_ and /dev/null differ
diff --git a/examples/0203/MyAndroidTutorial/build.gradle b/examples/0203/MyAndroidTutorial/build.gradle
new file mode 100644
index 0000000..6356aab
--- /dev/null
+++ b/examples/0203/MyAndroidTutorial/build.gradle
@@ -0,0 +1,19 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+ repositories {
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:1.0.0'
+
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+}
+
+allprojects {
+ repositories {
+ jcenter()
+ }
+}
diff --git a/examples/0203/MyAndroidTutorial/gen/net/macdidi/myandroidtutorial/BuildConfig.java b/examples/0203/MyAndroidTutorial/gen/net/macdidi/myandroidtutorial/BuildConfig.java
deleted file mode 100644
index 5d44ea9..0000000
--- a/examples/0203/MyAndroidTutorial/gen/net/macdidi/myandroidtutorial/BuildConfig.java
+++ /dev/null
@@ -1,6 +0,0 @@
-/** Automatically generated file. DO NOT MODIFY */
-package net.macdidi.myandroidtutorial;
-
-public final class BuildConfig {
- public final static boolean DEBUG = true;
-}
\ No newline at end of file
diff --git a/examples/0203/MyAndroidTutorial/gen/net/macdidi/myandroidtutorial/R.java b/examples/0203/MyAndroidTutorial/gen/net/macdidi/myandroidtutorial/R.java
deleted file mode 100644
index d0b06c5..0000000
--- a/examples/0203/MyAndroidTutorial/gen/net/macdidi/myandroidtutorial/R.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/* AUTO-GENERATED FILE. DO NOT MODIFY.
- *
- * This class was automatically generated by the
- * aapt tool from the resource data it found. It
- * should not be modified by hand.
- */
-
-package net.macdidi.myandroidtutorial;
-
-public final class R {
- public static final class attr {
- }
- public static final class color {
- public static final int divider_color=0x7f040002;
- public static final int grey=0x7f040001;
- public static final int light_grey=0x7f040000;
- }
- public static final class dimen {
- public static final int default_margin=0x7f050001;
- public static final int default_padding=0x7f050000;
- public static final int title_txt_size=0x7f050002;
- }
- public static final class drawable {
- public static final int alarm_icon=0x7f020000;
- public static final int ic_launcher=0x7f020001;
- public static final int location_icon=0x7f020002;
- public static final int record_sound_icon=0x7f020003;
- public static final int retangle_drawable=0x7f020004;
- public static final int select_color_icon=0x7f020005;
- public static final int take_picture_icon=0x7f020006;
- }
- public static final class id {
- public static final int add_item=0x7f090003;
- public static final int delete_item=0x7f090005;
- public static final int facebook_item=0x7f090008;
- public static final int googleplus_item=0x7f090007;
- public static final int item_list=0x7f090000;
- public static final int revert_item=0x7f090004;
- public static final int search_item=0x7f090002;
- public static final int share_item=0x7f090006;
- public static final int show_app_name=0x7f090001;
- }
- public static final class layout {
- public static final int activity_main=0x7f030000;
- }
- public static final class menu {
- public static final int main_menu=0x7f080000;
- }
- public static final class string {
- public static final int about=0x7f060006;
- public static final int app_name=0x7f060000;
- public static final int content=0x7f060004;
- public static final int enter_content=0x7f060005;
- public static final int enter_title=0x7f060003;
- public static final int hello_world=0x7f060007;
- public static final int title=0x7f060002;
- public static final int title_activity_main=0x7f060001;
- }
- public static final class style {
- /**
- Base application theme, dependent on API level. This theme is replaced
- by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
-
-
- Theme customizations available in newer API levels can go in
- res/values-vXX/styles.xml, while customizations related to
- backward-compatibility can go here.
-
-
- Base application theme for API 11+. This theme completely replaces
- AppBaseTheme from res/values/styles.xml on API 11+ devices.
-
- API 11 theme customizations can go here.
-
- Base application theme for API 14+. This theme completely replaces
- AppBaseTheme from BOTH res/values/styles.xml and
- res/values-v11/styles.xml on API 14+ devices.
-
- API 14 theme customizations can go here.
- */
- public static final int AppBaseTheme=0x7f070000;
- /** Application theme.
- All customizations that are NOT specific to a particular API-level can go here.
- */
- public static final int AppTheme=0x7f070001;
- }
-}
diff --git a/examples/0203/MyAndroidTutorial/gradle.properties b/examples/0203/MyAndroidTutorial/gradle.properties
new file mode 100644
index 0000000..1d3591c
--- /dev/null
+++ b/examples/0203/MyAndroidTutorial/gradle.properties
@@ -0,0 +1,18 @@
+# Project-wide Gradle settings.
+
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+# Default value: -Xmx10248m -XX:MaxPermSize=256m
+# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
+
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
\ No newline at end of file
diff --git a/examples/0203/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.jar b/examples/0203/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
Binary files /dev/null and b/examples/0203/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/examples/0203/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.properties b/examples/0203/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..0c71e76
--- /dev/null
+++ b/examples/0203/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
diff --git a/examples/0203/MyAndroidTutorial/gradlew b/examples/0203/MyAndroidTutorial/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/examples/0203/MyAndroidTutorial/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/examples/0203/MyAndroidTutorial/gradlew.bat b/examples/0203/MyAndroidTutorial/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/examples/0203/MyAndroidTutorial/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/examples/0203/MyAndroidTutorial/libs/android-support-v4.jar b/examples/0203/MyAndroidTutorial/libs/android-support-v4.jar
deleted file mode 100644
index 187bdf4..0000000
Binary files a/examples/0203/MyAndroidTutorial/libs/android-support-v4.jar and /dev/null differ
diff --git a/examples/0203/MyAndroidTutorial/proguard-project.txt b/examples/0203/MyAndroidTutorial/proguard-project.txt
deleted file mode 100644
index f2fe155..0000000
--- a/examples/0203/MyAndroidTutorial/proguard-project.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-# To enable ProGuard in your project, edit project.properties
-# to define the proguard.config property as described in that file.
-#
-# Add project specific ProGuard rules here.
-# By default, the flags in this file are appended to flags specified
-# in ${sdk.dir}/tools/proguard/proguard-android.txt
-# You can edit the include path and order by changing the ProGuard
-# include property in project.properties.
-#
-# For more details, see
-# http://developer.android.com/guide/developing/tools/proguard.html
-
-# Add any project specific keep options here:
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-# public *;
-#}
diff --git a/examples/0203/MyAndroidTutorial/project.properties b/examples/0203/MyAndroidTutorial/project.properties
deleted file mode 100644
index 4ab1256..0000000
--- a/examples/0203/MyAndroidTutorial/project.properties
+++ /dev/null
@@ -1,14 +0,0 @@
-# This file is automatically generated by Android Tools.
-# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
-#
-# This file must be checked in Version Control Systems.
-#
-# To customize properties used by the Ant build system edit
-# "ant.properties", and override values to adapt the script to your
-# project structure.
-#
-# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
-#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
-
-# Project target.
-target=android-19
diff --git a/examples/0203/MyAndroidTutorial/res/drawable/retangle_drawable.xml b/examples/0203/MyAndroidTutorial/res/drawable/retangle_drawable.xml
deleted file mode 100644
index e195342..0000000
--- a/examples/0203/MyAndroidTutorial/res/drawable/retangle_drawable.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/examples/0203/MyAndroidTutorial/res/layout/activity_main.xml b/examples/0203/MyAndroidTutorial/res/layout/activity_main.xml
deleted file mode 100644
index 418c34b..0000000
--- a/examples/0203/MyAndroidTutorial/res/layout/activity_main.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
diff --git a/examples/0203/MyAndroidTutorial/res/menu/main_menu.xml b/examples/0203/MyAndroidTutorial/res/menu/main_menu.xml
deleted file mode 100644
index 030587f..0000000
--- a/examples/0203/MyAndroidTutorial/res/menu/main_menu.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/examples/0203/MyAndroidTutorial/res/values-en/strings.xml b/examples/0203/MyAndroidTutorial/res/values-en/strings.xml
deleted file mode 100644
index 34f4fed..0000000
--- a/examples/0203/MyAndroidTutorial/res/values-en/strings.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
- MyAndroidTutorial
- MainActivity
- Hello world!
-
- Title
- Enter title
- Content
- Enter content
-
-
diff --git a/examples/0203/MyAndroidTutorial/res/values-v11/styles.xml b/examples/0203/MyAndroidTutorial/res/values-v11/styles.xml
deleted file mode 100644
index 3c02242..0000000
--- a/examples/0203/MyAndroidTutorial/res/values-v11/styles.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
diff --git a/examples/0203/MyAndroidTutorial/res/values-v14/styles.xml b/examples/0203/MyAndroidTutorial/res/values-v14/styles.xml
deleted file mode 100644
index a91fd03..0000000
--- a/examples/0203/MyAndroidTutorial/res/values-v14/styles.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
diff --git a/examples/0203/MyAndroidTutorial/res/values/colors.xml b/examples/0203/MyAndroidTutorial/res/values/colors.xml
deleted file mode 100644
index c7b5d95..0000000
--- a/examples/0203/MyAndroidTutorial/res/values/colors.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
- #CCCCCC
- #AAAAAA
- #DDCCCCCC
-
diff --git a/examples/0203/MyAndroidTutorial/res/values/dimens.xml b/examples/0203/MyAndroidTutorial/res/values/dimens.xml
deleted file mode 100644
index fb03071..0000000
--- a/examples/0203/MyAndroidTutorial/res/values/dimens.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
- 6dp
- 2dp
- 24sp
-
diff --git a/examples/0203/MyAndroidTutorial/res/values/strings.xml b/examples/0203/MyAndroidTutorial/res/values/strings.xml
deleted file mode 100644
index 081492c..0000000
--- a/examples/0203/MyAndroidTutorial/res/values/strings.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
- MyAndroidTutorial
- MainActivity
-
- 標題
- 輸入標題
- 內容
- 輸入內容
-
- 這是Android Tutorial應用程式
-
-
diff --git a/examples/0203/MyAndroidTutorial/res/values/styles.xml b/examples/0203/MyAndroidTutorial/res/values/styles.xml
deleted file mode 100644
index 6ce89c7..0000000
--- a/examples/0203/MyAndroidTutorial/res/values/styles.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
-
-
-
-
-
-
diff --git a/examples/0203/MyAndroidTutorial/settings.gradle b/examples/0203/MyAndroidTutorial/settings.gradle
new file mode 100644
index 0000000..e7b4def
--- /dev/null
+++ b/examples/0203/MyAndroidTutorial/settings.gradle
@@ -0,0 +1 @@
+include ':app'
diff --git a/examples/0203/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/MainActivity.java b/examples/0203/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/MainActivity.java
deleted file mode 100644
index 153d0b9..0000000
--- a/examples/0203/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/MainActivity.java
+++ /dev/null
@@ -1,149 +0,0 @@
-package net.macdidi.myandroidtutorial;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.os.Bundle;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.View.OnLongClickListener;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemClickListener;
-import android.widget.AdapterView.OnItemLongClickListener;
-import android.widget.ArrayAdapter;
-import android.widget.ListView;
-import android.widget.TextView;
-import android.widget.Toast;
-
-public class MainActivity extends Activity {
-
- private ListView item_list;
- private TextView show_app_name;
-
- private static final String[] data = {
- "關於Android Tutorial的事情",
- "一隻非常可愛的小狗狗!",
- "一首非常好聽的音樂!"};
- private ArrayAdapter adapter;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
-
- processViews();
- processControllers();
-
- int layoutId = android.R.layout.simple_list_item_1;
- adapter = new ArrayAdapter(this, layoutId, data);
- item_list.setAdapter(adapter);
- }
-
- private void processViews() {
- item_list = (ListView)findViewById(R.id.item_list);
- show_app_name = (TextView) findViewById(R.id.show_app_name);
- }
-
- private void processControllers() {
- // 建立選單項目點擊監聽物件
- OnItemClickListener itemListener = new OnItemClickListener() {
- // 第一個參數是使用者操作的ListView物件
- // 第二個參數是使用者選擇的項目
- // 第三個參數是使用者選擇的項目編號,第一個是0
- // 第四個參數在這裡沒有用途
- @Override
- public void onItemClick(AdapterView> parent, View view,
- int position, long id) {
- Toast.makeText(MainActivity.this,
- data[position], Toast.LENGTH_LONG).show();
- }
- };
-
- // 註冊選單項目點擊監聽物件
- item_list.setOnItemClickListener(itemListener);
-
- // 建立選單項目長按監聽物件
- OnItemLongClickListener itemLongListener = new OnItemLongClickListener() {
- // 第一個參數是使用者操作的ListView物件
- // 第二個參數是使用者選擇的項目
- // 第三個參數是使用者選擇的項目編號,第一個是0
- // 第四個參數在這裡沒有用途
- @Override
- public boolean onItemLongClick(AdapterView> parent, View view,
- int position, long id) {
- Toast.makeText(MainActivity.this,
- "Long: " + data[position], Toast.LENGTH_LONG).show();
- return false;
- }
- };
-
- // 註冊選單項目長按監聽物件
- item_list.setOnItemLongClickListener(itemLongListener);
-
- // 建立長按監聽物件
- OnLongClickListener listener = new OnLongClickListener() {
-
- @Override
- public boolean onLongClick(View view) {
- AlertDialog.Builder dialog =
- new AlertDialog.Builder(MainActivity.this);
- dialog.setTitle(R.string.app_name)
- .setMessage(R.string.about)
- .show();
- return false;
- }
-
- };
-
- // 註冊長按監聽物件
- show_app_name.setOnLongClickListener(listener);
- }
-
- // 載入選單資源
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- MenuInflater menuInflater = getMenuInflater();
- menuInflater.inflate(R.menu.main_menu, menu);
- return true;
- }
-
- // 使用者選擇所有的選單項目都會呼叫這個方法
- public void clickMenuItem(MenuItem item) {
- // 使用參數取得使用者選擇的選單項目元件編號
- int itemId = item.getItemId();
-
- // 判斷該執行什麼工作,目前還沒有加入需要執行的工作
- switch (itemId) {
- case R.id.search_item:
- break;
- case R.id.add_item:
- break;
- case R.id.revert_item:
- break;
- case R.id.delete_item:
- break;
- case R.id.googleplus_item:
- break;
- case R.id.facebook_item:
- break;
- }
-
- // 測試用的程式碼,完成測試後記得移除
- AlertDialog.Builder dialog =
- new AlertDialog.Builder(MainActivity.this);
- dialog.setTitle("MenuItem Test")
- .setMessage(item.getTitle())
- .setIcon(item.getIcon())
- .show();
- }
-
- // 方法名稱與onClick的設定一樣,參數的型態是android.view.View
- public void aboutApp(View view) {
- // 顯示訊息框
- // Context:通常指定為「this」;如果在巢狀類別中使用,要加上這個Activity元件類別的名稱,例如「元件類別名稱.this」
- // String或int:設定顯示在訊息框裡面的訊息或文字資源
- // int:設定訊息框停留在畫面的時間,使用宣告在Toast類別中的變數,可以設定為「LENGTH_LONG」和「LENGTH_SHORT」
- Toast.makeText(this, R.string.app_name, Toast.LENGTH_LONG).show();
- }
-}
diff --git a/examples/0204/MyAndroidTutorial/.classpath b/examples/0204/MyAndroidTutorial/.classpath
deleted file mode 100644
index 7bc01d9..0000000
--- a/examples/0204/MyAndroidTutorial/.classpath
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
-
-
-
-
diff --git a/examples/0204/MyAndroidTutorial/.gitignore b/examples/0204/MyAndroidTutorial/.gitignore
new file mode 100644
index 0000000..afbdab3
--- /dev/null
+++ b/examples/0204/MyAndroidTutorial/.gitignore
@@ -0,0 +1,6 @@
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
diff --git a/examples/0204/MyAndroidTutorial/.idea/.name b/examples/0204/MyAndroidTutorial/.idea/.name
new file mode 100644
index 0000000..5bb7a85
--- /dev/null
+++ b/examples/0204/MyAndroidTutorial/.idea/.name
@@ -0,0 +1 @@
+MyAndroidTutorial
\ No newline at end of file
diff --git a/examples/0204/MyAndroidTutorial/.idea/compiler.xml b/examples/0204/MyAndroidTutorial/.idea/compiler.xml
new file mode 100644
index 0000000..217af47
--- /dev/null
+++ b/examples/0204/MyAndroidTutorial/.idea/compiler.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0204/MyAndroidTutorial/.idea/copyright/profiles_settings.xml b/examples/0204/MyAndroidTutorial/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..e7bedf3
--- /dev/null
+++ b/examples/0204/MyAndroidTutorial/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/examples/0204/MyAndroidTutorial/.idea/encodings.xml b/examples/0204/MyAndroidTutorial/.idea/encodings.xml
new file mode 100644
index 0000000..e206d70
--- /dev/null
+++ b/examples/0204/MyAndroidTutorial/.idea/encodings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/examples/0204/MyAndroidTutorial/.idea/gradle.xml b/examples/0204/MyAndroidTutorial/.idea/gradle.xml
new file mode 100644
index 0000000..fe865d3
--- /dev/null
+++ b/examples/0204/MyAndroidTutorial/.idea/gradle.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0204/MyAndroidTutorial/.idea/misc.xml b/examples/0204/MyAndroidTutorial/.idea/misc.xml
new file mode 100644
index 0000000..9076de5
--- /dev/null
+++ b/examples/0204/MyAndroidTutorial/.idea/misc.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0204/MyAndroidTutorial/.idea/modules.xml b/examples/0204/MyAndroidTutorial/.idea/modules.xml
new file mode 100644
index 0000000..327df67
--- /dev/null
+++ b/examples/0204/MyAndroidTutorial/.idea/modules.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0204/MyAndroidTutorial/.idea/scopes/scope_settings.xml b/examples/0204/MyAndroidTutorial/.idea/scopes/scope_settings.xml
new file mode 100644
index 0000000..922003b
--- /dev/null
+++ b/examples/0204/MyAndroidTutorial/.idea/scopes/scope_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0204/MyAndroidTutorial/.idea/vcs.xml b/examples/0204/MyAndroidTutorial/.idea/vcs.xml
new file mode 100644
index 0000000..def6a6a
--- /dev/null
+++ b/examples/0204/MyAndroidTutorial/.idea/vcs.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/examples/0204/MyAndroidTutorial/.project b/examples/0204/MyAndroidTutorial/.project
deleted file mode 100644
index b1de407..0000000
--- a/examples/0204/MyAndroidTutorial/.project
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
- MyAndroidTutorial
-
-
-
-
-
- com.android.ide.eclipse.adt.ResourceManagerBuilder
-
-
-
-
- com.android.ide.eclipse.adt.PreCompilerBuilder
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- com.android.ide.eclipse.adt.ApkBuilder
-
-
-
-
-
- com.android.ide.eclipse.adt.AndroidNature
- org.eclipse.jdt.core.javanature
-
-
diff --git a/examples/0204/MyAndroidTutorial/AndroidManifest.xml b/examples/0204/MyAndroidTutorial/AndroidManifest.xml
deleted file mode 100644
index ebb0127..0000000
--- a/examples/0204/MyAndroidTutorial/AndroidManifest.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/examples/0204/MyAndroidTutorial/MyAndroidTutorial.iml b/examples/0204/MyAndroidTutorial/MyAndroidTutorial.iml
new file mode 100644
index 0000000..2a02201
--- /dev/null
+++ b/examples/0204/MyAndroidTutorial/MyAndroidTutorial.iml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0204/MyAndroidTutorial/app/.gitignore b/examples/0204/MyAndroidTutorial/app/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/examples/0204/MyAndroidTutorial/app/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/examples/0204/MyAndroidTutorial/app/app.iml b/examples/0204/MyAndroidTutorial/app/app.iml
new file mode 100644
index 0000000..c6c55c4
--- /dev/null
+++ b/examples/0204/MyAndroidTutorial/app/app.iml
@@ -0,0 +1,91 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0204/MyAndroidTutorial/app/build.gradle b/examples/0204/MyAndroidTutorial/app/build.gradle
new file mode 100644
index 0000000..b09f064
--- /dev/null
+++ b/examples/0204/MyAndroidTutorial/app/build.gradle
@@ -0,0 +1,25 @@
+apply plugin: 'com.android.application'
+
+android {
+ compileSdkVersion 21
+ buildToolsVersion "21.1.2"
+
+ defaultConfig {
+ applicationId "net.macdidi.myandroidtutorial"
+ minSdkVersion 15
+ targetSdkVersion 21
+ versionCode 1
+ versionName "1.0"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ compile fileTree(dir: 'libs', include: ['*.jar'])
+ compile 'com.android.support:appcompat-v7:21.0.3'
+}
diff --git a/examples/0204/MyAndroidTutorial/app/proguard-rules.pro b/examples/0204/MyAndroidTutorial/app/proguard-rules.pro
new file mode 100644
index 0000000..b5fa7ec
--- /dev/null
+++ b/examples/0204/MyAndroidTutorial/app/proguard-rules.pro
@@ -0,0 +1,17 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /Users/macdidi5/Library/Android/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
diff --git a/examples/0204/MyAndroidTutorial/app/src/androidTest/java/net/macdidi/myandroidtutorial/ApplicationTest.java b/examples/0204/MyAndroidTutorial/app/src/androidTest/java/net/macdidi/myandroidtutorial/ApplicationTest.java
new file mode 100644
index 0000000..2cb214e
--- /dev/null
+++ b/examples/0204/MyAndroidTutorial/app/src/androidTest/java/net/macdidi/myandroidtutorial/ApplicationTest.java
@@ -0,0 +1,13 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Application;
+import android.test.ApplicationTestCase;
+
+/**
+ * Testing Fundamentals
+ */
+public class ApplicationTest extends ApplicationTestCase {
+ public ApplicationTest() {
+ super(Application.class);
+ }
+}
\ No newline at end of file
diff --git a/examples/0204/MyAndroidTutorial/app/src/main/AndroidManifest.xml b/examples/0204/MyAndroidTutorial/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..47e0605
--- /dev/null
+++ b/examples/0204/MyAndroidTutorial/app/src/main/AndroidManifest.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0204/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/AboutActivity.java b/examples/0204/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/AboutActivity.java
new file mode 100644
index 0000000..42dddeb
--- /dev/null
+++ b/examples/0204/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/AboutActivity.java
@@ -0,0 +1,24 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.view.Window;
+
+public class AboutActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ // 取消元件的應用程式標題
+ requestWindowFeature(Window.FEATURE_NO_TITLE);
+ setContentView(R.layout.activity_about);
+ }
+
+ // 結束按鈕
+ public void clickOk(View view) {
+ // 呼叫這個方法結束Activity元件
+ finish();
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0204/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemActivity.java b/examples/0204/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemActivity.java
new file mode 100644
index 0000000..7e6c457
--- /dev/null
+++ b/examples/0204/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemActivity.java
@@ -0,0 +1,79 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.EditText;
+
+public class ItemActivity extends Activity {
+
+ private EditText title_text, content_text;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_item);
+
+ processViews();
+
+ // 取得Intent物件
+ Intent intent = getIntent();
+ // 讀取Action名稱
+ String action = intent.getAction();
+
+ // 如果是修改記事
+ if (action.equals("net.macdidi.myandroidtutorial.EDIT_ITEM")) {
+ // 接收與設定記事標題
+ String titleText = intent.getStringExtra("titleText");
+ title_text.setText(titleText);
+ }
+ }
+
+ private void processViews() {
+ title_text = (EditText) findViewById(R.id.title_text);
+ content_text = (EditText) findViewById(R.id.content_text);
+ }
+
+ // 點擊確定與取消按鈕都會呼叫這個方法
+ public void onSubmit(View view) {
+ // 確定按鈕
+ if (view.getId() == R.id.ok_teim) {
+ // 讀取使用者輸入的標題與內容
+ String titleText = title_text.getText().toString();
+ String contentText = content_text.getText().toString();
+
+ // 取得回傳資料用的Intent物件
+ Intent result = getIntent();
+ // 設定標題與內容
+ result.putExtra("titleText", titleText);
+ result.putExtra("contentText", contentText);
+
+ // 設定回應結果為確定
+ setResult(Activity.RESULT_OK, result);
+ }
+
+ // 結束
+ finish();
+ }
+
+ // 以後需要擴充的功能
+ public void clickFunction(View view) {
+ int id = view.getId();
+
+ switch (id) {
+ case R.id.take_picture:
+ break;
+ case R.id.record_sound:
+ break;
+ case R.id.set_location:
+ break;
+ case R.id.set_alarm:
+ break;
+ case R.id.select_color:
+ break;
+ }
+
+ }
+
+}
diff --git a/examples/0204/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MainActivity.java b/examples/0204/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MainActivity.java
new file mode 100644
index 0000000..7ad657c
--- /dev/null
+++ b/examples/0204/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MainActivity.java
@@ -0,0 +1,185 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.v7.app.ActionBarActivity;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import java.util.ArrayList;
+
+public class MainActivity extends ActionBarActivity {
+ private ListView item_list;
+ private TextView show_app_name;
+
+ // 換掉原來的字串陣列
+ private ArrayList data = new ArrayList<>();
+ private ArrayAdapter adapter;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ processViews();
+ processControllers();
+
+ // 加入範例資料
+ data.add("關於Android Tutorial的事情");
+ data.add("一隻非常可愛的小狗狗!");
+ data.add("一首非常好聽的音樂!");
+
+ int layoutId = android.R.layout.simple_list_item_1;
+ adapter = new ArrayAdapter(this, layoutId, data);
+ item_list.setAdapter(adapter);
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ // 如果被啟動的Activity元件傳回確定的結果
+ if (resultCode == Activity.RESULT_OK) {
+ String titleText = data.getStringExtra("titleText");
+
+ // 如果是新增記事
+ if (requestCode == 0) {
+ // 加入標題項目
+ this.data.add(titleText);
+ // 通知資料已經改變,ListView元件才會重新顯示
+ adapter.notifyDataSetChanged();
+ }
+ // 如果是修改記事
+ else if (requestCode == 1) {
+ // 讀取記事編號
+ int position = data.getIntExtra("position", -1);
+
+ if (position != -1) {
+ // 設定標題項目
+ this.data.set(position, titleText);
+ // 通知資料已經改變,ListView元件才會重新顯示
+ adapter.notifyDataSetChanged();
+ }
+ }
+ }
+ }
+
+ private void processViews() {
+ item_list = (ListView)findViewById(R.id.item_list);
+ show_app_name = (TextView) findViewById(R.id.show_app_name);
+ }
+
+ private void processControllers() {
+ // 建立選單項目點擊監聽物件
+ AdapterView.OnItemClickListener itemListener = new AdapterView.OnItemClickListener() {
+
+ @Override
+ public void onItemClick(AdapterView> parent, View view,
+ int position, long id) {
+ // 使用Action名稱建立啟動另一個Activity元件需要的Intent物件
+ Intent intent = new Intent("net.macdidi.myandroidtutorial.EDIT_ITEM");
+
+ // 設定記事編號與標題
+ intent.putExtra("position", position);
+ intent.putExtra("titleText", data.get(position));
+
+ // 呼叫「startActivityForResult」,第二個參數「1」表示執行修改
+ startActivityForResult(intent, 1);
+ }
+ };
+
+ // 註冊選單項目點擊監聽物件
+ item_list.setOnItemClickListener(itemListener);
+
+ // 建立選單項目長按監聽物件
+ AdapterView.OnItemLongClickListener itemLongListener = new AdapterView.OnItemLongClickListener() {
+
+ @Override
+ public boolean onItemLongClick(AdapterView> parent, View view,
+ int position, long id) {
+ // 換掉「data[position]」
+ Toast.makeText(MainActivity.this,
+ "Long: " + data.get(position), Toast.LENGTH_LONG).show();
+ return false;
+ }
+ };
+
+ // 註冊選單項目長按監聽物件
+ item_list.setOnItemLongClickListener(itemLongListener);
+
+ // 建立長按監聽物件
+ View.OnLongClickListener listener = new View.OnLongClickListener() {
+
+ @Override
+ public boolean onLongClick(View view) {
+ AlertDialog.Builder dialog =
+ new AlertDialog.Builder(MainActivity.this);
+ dialog.setTitle(R.string.app_name)
+ .setMessage(R.string.about)
+ .show();
+ return false;
+ }
+
+ };
+
+ // 註冊長按監聽物件
+ show_app_name.setOnLongClickListener(listener);
+ }
+
+ // 載入選單資源
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ MenuInflater menuInflater = getMenuInflater();
+ menuInflater.inflate(R.menu.menu_main, menu);
+ return true;
+ }
+
+ // 使用者選擇所有的選單項目都會呼叫這個方法
+ public void clickMenuItem(MenuItem item) {
+ // 使用參數取得使用者選擇的選單項目元件編號
+ int itemId = item.getItemId();
+
+ // 判斷該執行什麼工作,目前還沒有加入需要執行的工作
+ switch (itemId) {
+ case R.id.search_item:
+ break;
+ // 使用者選擇新增選單項目
+ case R.id.add_item:
+ // 使用Action名稱建立啟動另一個Activity元件需要的Intent物件
+ Intent intent = new Intent("net.macdidi.myandroidtutorial.ADD_ITEM");
+ // 呼叫「startActivityForResult」,,第二個參數「0」表示執行新增
+ startActivityForResult(intent, 0);
+ break;
+ case R.id.revert_item:
+ break;
+ case R.id.delete_item:
+ break;
+ case R.id.googleplus_item:
+ break;
+ case R.id.facebook_item:
+ break;
+ }
+
+ }
+
+ // 方法名稱與onClick的設定一樣,參數的型態是android.view.View
+ public void aboutApp(View view) {
+ // 建立啟動另一個Activity元件需要的Intent物件
+ // 建構式的第一個參數:「this」
+ // 建構式的第二個參數:「Activity元件類別名稱.class」
+ Intent intent = new Intent(this, AboutActivity.class);
+ // 呼叫「startActivity」,參數為一個建立好的Intent物件
+ // 這行敘述執行以後,如果沒有任何錯誤,就會啟動指定的元件
+ startActivity(intent);
+ }
+
+}
+
+
diff --git a/examples/0204/MyAndroidTutorial/res/drawable-hdpi/ic_launcher.png b/examples/0204/MyAndroidTutorial/app/src/main/res/drawable-hdpi/ic_launcher.png
similarity index 100%
rename from examples/0204/MyAndroidTutorial/res/drawable-hdpi/ic_launcher.png
rename to examples/0204/MyAndroidTutorial/app/src/main/res/drawable-hdpi/ic_launcher.png
diff --git a/examples/0204/MyAndroidTutorial/res/drawable-mdpi/ic_launcher.png b/examples/0204/MyAndroidTutorial/app/src/main/res/drawable-mdpi/ic_launcher.png
similarity index 100%
rename from examples/0204/MyAndroidTutorial/res/drawable-mdpi/ic_launcher.png
rename to examples/0204/MyAndroidTutorial/app/src/main/res/drawable-mdpi/ic_launcher.png
diff --git a/examples/0204/MyAndroidTutorial/res/drawable-xhdpi/ic_launcher.png b/examples/0204/MyAndroidTutorial/app/src/main/res/drawable-xhdpi/ic_launcher.png
similarity index 100%
rename from examples/0204/MyAndroidTutorial/res/drawable-xhdpi/ic_launcher.png
rename to examples/0204/MyAndroidTutorial/app/src/main/res/drawable-xhdpi/ic_launcher.png
diff --git a/examples/0204/MyAndroidTutorial/app/src/main/res/drawable-xxhdpi/ic_launcher.png b/examples/0204/MyAndroidTutorial/app/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..4df1894
Binary files /dev/null and b/examples/0204/MyAndroidTutorial/app/src/main/res/drawable-xxhdpi/ic_launcher.png differ
diff --git a/examples/0204/MyAndroidTutorial/res/drawable/alarm_icon.png b/examples/0204/MyAndroidTutorial/app/src/main/res/drawable/alarm_icon.png
similarity index 100%
rename from examples/0204/MyAndroidTutorial/res/drawable/alarm_icon.png
rename to examples/0204/MyAndroidTutorial/app/src/main/res/drawable/alarm_icon.png
diff --git a/examples/0204/MyAndroidTutorial/res/drawable/location_icon.png b/examples/0204/MyAndroidTutorial/app/src/main/res/drawable/location_icon.png
similarity index 100%
rename from examples/0204/MyAndroidTutorial/res/drawable/location_icon.png
rename to examples/0204/MyAndroidTutorial/app/src/main/res/drawable/location_icon.png
diff --git a/examples/0204/MyAndroidTutorial/res/drawable/record_sound_icon.png b/examples/0204/MyAndroidTutorial/app/src/main/res/drawable/record_sound_icon.png
similarity index 100%
rename from examples/0204/MyAndroidTutorial/res/drawable/record_sound_icon.png
rename to examples/0204/MyAndroidTutorial/app/src/main/res/drawable/record_sound_icon.png
diff --git a/examples/0204/MyAndroidTutorial/app/src/main/res/drawable/retangle_drawable.xml b/examples/0204/MyAndroidTutorial/app/src/main/res/drawable/retangle_drawable.xml
new file mode 100644
index 0000000..51d1e84
--- /dev/null
+++ b/examples/0204/MyAndroidTutorial/app/src/main/res/drawable/retangle_drawable.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0204/MyAndroidTutorial/res/drawable/select_color_icon.png b/examples/0204/MyAndroidTutorial/app/src/main/res/drawable/select_color_icon.png
similarity index 100%
rename from examples/0204/MyAndroidTutorial/res/drawable/select_color_icon.png
rename to examples/0204/MyAndroidTutorial/app/src/main/res/drawable/select_color_icon.png
diff --git a/examples/0204/MyAndroidTutorial/res/drawable/take_picture_icon.png b/examples/0204/MyAndroidTutorial/app/src/main/res/drawable/take_picture_icon.png
similarity index 100%
rename from examples/0204/MyAndroidTutorial/res/drawable/take_picture_icon.png
rename to examples/0204/MyAndroidTutorial/app/src/main/res/drawable/take_picture_icon.png
diff --git a/examples/0204/MyAndroidTutorial/app/src/main/res/layout/activity_about.xml b/examples/0204/MyAndroidTutorial/app/src/main/res/layout/activity_about.xml
new file mode 100644
index 0000000..8e78611
--- /dev/null
+++ b/examples/0204/MyAndroidTutorial/app/src/main/res/layout/activity_about.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0204/MyAndroidTutorial/app/src/main/res/layout/activity_item.xml b/examples/0204/MyAndroidTutorial/app/src/main/res/layout/activity_item.xml
new file mode 100644
index 0000000..cb0c3bd
--- /dev/null
+++ b/examples/0204/MyAndroidTutorial/app/src/main/res/layout/activity_item.xml
@@ -0,0 +1,108 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0204/MyAndroidTutorial/app/src/main/res/layout/activity_main.xml b/examples/0204/MyAndroidTutorial/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..121511b
--- /dev/null
+++ b/examples/0204/MyAndroidTutorial/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
diff --git a/examples/0204/MyAndroidTutorial/app/src/main/res/menu/menu_about.xml b/examples/0204/MyAndroidTutorial/app/src/main/res/menu/menu_about.xml
new file mode 100644
index 0000000..d481100
--- /dev/null
+++ b/examples/0204/MyAndroidTutorial/app/src/main/res/menu/menu_about.xml
@@ -0,0 +1,7 @@
+
+
+
diff --git a/examples/0204/MyAndroidTutorial/app/src/main/res/menu/menu_item.xml b/examples/0204/MyAndroidTutorial/app/src/main/res/menu/menu_item.xml
new file mode 100644
index 0000000..cd2c9e4
--- /dev/null
+++ b/examples/0204/MyAndroidTutorial/app/src/main/res/menu/menu_item.xml
@@ -0,0 +1,7 @@
+
+
+
diff --git a/examples/0204/MyAndroidTutorial/app/src/main/res/menu/menu_main.xml b/examples/0204/MyAndroidTutorial/app/src/main/res/menu/menu_main.xml
new file mode 100644
index 0000000..024de57
--- /dev/null
+++ b/examples/0204/MyAndroidTutorial/app/src/main/res/menu/menu_main.xml
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
diff --git a/examples/0204/MyAndroidTutorial/app/src/main/res/values-en/strings.xml b/examples/0204/MyAndroidTutorial/app/src/main/res/values-en/strings.xml
new file mode 100644
index 0000000..c532533
--- /dev/null
+++ b/examples/0204/MyAndroidTutorial/app/src/main/res/values-en/strings.xml
@@ -0,0 +1,12 @@
+
+
+
+ MyAndroidTutorial
+ Hello world!
+ Settings
+
+ Title
+ Enter title
+ Content
+ Enter content
+
diff --git a/examples/0204/MyAndroidTutorial/app/src/main/res/values-w820dp/dimens.xml b/examples/0204/MyAndroidTutorial/app/src/main/res/values-w820dp/dimens.xml
new file mode 100644
index 0000000..63fc816
--- /dev/null
+++ b/examples/0204/MyAndroidTutorial/app/src/main/res/values-w820dp/dimens.xml
@@ -0,0 +1,6 @@
+
+
+ 64dp
+
diff --git a/examples/0204/MyAndroidTutorial/app/src/main/res/values/colors.xml b/examples/0204/MyAndroidTutorial/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..6b13c1d
--- /dev/null
+++ b/examples/0204/MyAndroidTutorial/app/src/main/res/values/colors.xml
@@ -0,0 +1,7 @@
+
+
+ #CCCCCC
+ #AAAAAA
+ #DD999999
+ #111111
+
\ No newline at end of file
diff --git a/examples/0204/MyAndroidTutorial/app/src/main/res/values/dimens.xml b/examples/0204/MyAndroidTutorial/app/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..02898ec
--- /dev/null
+++ b/examples/0204/MyAndroidTutorial/app/src/main/res/values/dimens.xml
@@ -0,0 +1,9 @@
+
+
+ 16dp
+ 16dp
+
+ 6dp
+ 24sp
+ 2dp
+
diff --git a/examples/0204/MyAndroidTutorial/app/src/main/res/values/strings.xml b/examples/0204/MyAndroidTutorial/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..4ae5508
--- /dev/null
+++ b/examples/0204/MyAndroidTutorial/app/src/main/res/values/strings.xml
@@ -0,0 +1,16 @@
+
+
+
+ MyAndroidTutorial
+ Hello world!
+ Settings
+ 標題
+ 輸入標題
+ 內容
+ 輸入內容
+ 這是Android Tutorial應用程式
+ AboutActivity
+ 版本:AndroidTutorial_0.2.4
+ ItemActivity
+
+
diff --git a/examples/0204/MyAndroidTutorial/app/src/main/res/values/styles.xml b/examples/0204/MyAndroidTutorial/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..766ab99
--- /dev/null
+++ b/examples/0204/MyAndroidTutorial/app/src/main/res/values/styles.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
diff --git a/examples/0204/MyAndroidTutorial/bin/AndroidManifest.xml b/examples/0204/MyAndroidTutorial/bin/AndroidManifest.xml
deleted file mode 100644
index ebb0127..0000000
--- a/examples/0204/MyAndroidTutorial/bin/AndroidManifest.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/examples/0204/MyAndroidTutorial/bin/MyAndroidTutorial.apk b/examples/0204/MyAndroidTutorial/bin/MyAndroidTutorial.apk
deleted file mode 100644
index 7355fdb..0000000
Binary files a/examples/0204/MyAndroidTutorial/bin/MyAndroidTutorial.apk and /dev/null differ
diff --git a/examples/0204/MyAndroidTutorial/bin/classes.dex b/examples/0204/MyAndroidTutorial/bin/classes.dex
deleted file mode 100644
index 9f6fc9b..0000000
Binary files a/examples/0204/MyAndroidTutorial/bin/classes.dex and /dev/null differ
diff --git a/examples/0204/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/AboutActivity.class b/examples/0204/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/AboutActivity.class
deleted file mode 100644
index abbf876..0000000
Binary files a/examples/0204/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/AboutActivity.class and /dev/null differ
diff --git a/examples/0204/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/BuildConfig.class b/examples/0204/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/BuildConfig.class
deleted file mode 100644
index 30f5623..0000000
Binary files a/examples/0204/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/BuildConfig.class and /dev/null differ
diff --git a/examples/0204/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ItemActivity.class b/examples/0204/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ItemActivity.class
deleted file mode 100644
index 789204b..0000000
Binary files a/examples/0204/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ItemActivity.class and /dev/null differ
diff --git a/examples/0204/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$1.class b/examples/0204/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$1.class
deleted file mode 100644
index 4dc8daa..0000000
Binary files a/examples/0204/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$1.class and /dev/null differ
diff --git a/examples/0204/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$2.class b/examples/0204/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$2.class
deleted file mode 100644
index 0d12e77..0000000
Binary files a/examples/0204/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$2.class and /dev/null differ
diff --git a/examples/0204/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$3.class b/examples/0204/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$3.class
deleted file mode 100644
index 309ed31..0000000
Binary files a/examples/0204/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$3.class and /dev/null differ
diff --git a/examples/0204/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity.class b/examples/0204/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity.class
deleted file mode 100644
index ff94f24..0000000
Binary files a/examples/0204/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity.class and /dev/null differ
diff --git a/examples/0204/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$attr.class b/examples/0204/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$attr.class
deleted file mode 100644
index 9d83559..0000000
Binary files a/examples/0204/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$attr.class and /dev/null differ
diff --git a/examples/0204/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$color.class b/examples/0204/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$color.class
deleted file mode 100644
index 8646729..0000000
Binary files a/examples/0204/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$color.class and /dev/null differ
diff --git a/examples/0204/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$dimen.class b/examples/0204/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$dimen.class
deleted file mode 100644
index ab21b39..0000000
Binary files a/examples/0204/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$dimen.class and /dev/null differ
diff --git a/examples/0204/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$drawable.class b/examples/0204/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$drawable.class
deleted file mode 100644
index 4ab86cf..0000000
Binary files a/examples/0204/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$drawable.class and /dev/null differ
diff --git a/examples/0204/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$id.class b/examples/0204/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$id.class
deleted file mode 100644
index 31b2d33..0000000
Binary files a/examples/0204/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$id.class and /dev/null differ
diff --git a/examples/0204/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$layout.class b/examples/0204/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$layout.class
deleted file mode 100644
index f7464ff..0000000
Binary files a/examples/0204/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$layout.class and /dev/null differ
diff --git a/examples/0204/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$menu.class b/examples/0204/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$menu.class
deleted file mode 100644
index 15e6fe5..0000000
Binary files a/examples/0204/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$menu.class and /dev/null differ
diff --git a/examples/0204/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$string.class b/examples/0204/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$string.class
deleted file mode 100644
index b44fbc2..0000000
Binary files a/examples/0204/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$string.class and /dev/null differ
diff --git a/examples/0204/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$style.class b/examples/0204/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$style.class
deleted file mode 100644
index 703d6e3..0000000
Binary files a/examples/0204/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$style.class and /dev/null differ
diff --git a/examples/0204/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R.class b/examples/0204/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R.class
deleted file mode 100644
index 3be8276..0000000
Binary files a/examples/0204/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R.class and /dev/null differ
diff --git a/examples/0204/MyAndroidTutorial/bin/dexedLibs/android-support-v4-9b1d5d28bf7d59a4e392b3d4f78c1f13.jar b/examples/0204/MyAndroidTutorial/bin/dexedLibs/android-support-v4-9b1d5d28bf7d59a4e392b3d4f78c1f13.jar
deleted file mode 100644
index 80a2884..0000000
Binary files a/examples/0204/MyAndroidTutorial/bin/dexedLibs/android-support-v4-9b1d5d28bf7d59a4e392b3d4f78c1f13.jar and /dev/null differ
diff --git a/examples/0204/MyAndroidTutorial/bin/jarlist.cache b/examples/0204/MyAndroidTutorial/bin/jarlist.cache
deleted file mode 100644
index 0565465..0000000
--- a/examples/0204/MyAndroidTutorial/bin/jarlist.cache
+++ /dev/null
@@ -1,3 +0,0 @@
-# cache for current jar dependency. DO NOT EDIT.
-# format is
-# Encoding is UTF-8
diff --git a/examples/0204/MyAndroidTutorial/bin/res/crunch/drawable-hdpi/ic_launcher.png b/examples/0204/MyAndroidTutorial/bin/res/crunch/drawable-hdpi/ic_launcher.png
deleted file mode 100644
index bcfa058..0000000
Binary files a/examples/0204/MyAndroidTutorial/bin/res/crunch/drawable-hdpi/ic_launcher.png and /dev/null differ
diff --git a/examples/0204/MyAndroidTutorial/bin/res/crunch/drawable-mdpi/ic_launcher.png b/examples/0204/MyAndroidTutorial/bin/res/crunch/drawable-mdpi/ic_launcher.png
deleted file mode 100644
index 85848ff..0000000
Binary files a/examples/0204/MyAndroidTutorial/bin/res/crunch/drawable-mdpi/ic_launcher.png and /dev/null differ
diff --git a/examples/0204/MyAndroidTutorial/bin/res/crunch/drawable-xhdpi/ic_launcher.png b/examples/0204/MyAndroidTutorial/bin/res/crunch/drawable-xhdpi/ic_launcher.png
deleted file mode 100644
index 916901e..0000000
Binary files a/examples/0204/MyAndroidTutorial/bin/res/crunch/drawable-xhdpi/ic_launcher.png and /dev/null differ
diff --git a/examples/0204/MyAndroidTutorial/bin/res/crunch/drawable/alarm_icon.png b/examples/0204/MyAndroidTutorial/bin/res/crunch/drawable/alarm_icon.png
deleted file mode 100644
index ebeae27..0000000
Binary files a/examples/0204/MyAndroidTutorial/bin/res/crunch/drawable/alarm_icon.png and /dev/null differ
diff --git a/examples/0204/MyAndroidTutorial/bin/res/crunch/drawable/location_icon.png b/examples/0204/MyAndroidTutorial/bin/res/crunch/drawable/location_icon.png
deleted file mode 100644
index 6897a97..0000000
Binary files a/examples/0204/MyAndroidTutorial/bin/res/crunch/drawable/location_icon.png and /dev/null differ
diff --git a/examples/0204/MyAndroidTutorial/bin/res/crunch/drawable/record_sound_icon.png b/examples/0204/MyAndroidTutorial/bin/res/crunch/drawable/record_sound_icon.png
deleted file mode 100644
index 6fe2060..0000000
Binary files a/examples/0204/MyAndroidTutorial/bin/res/crunch/drawable/record_sound_icon.png and /dev/null differ
diff --git a/examples/0204/MyAndroidTutorial/bin/res/crunch/drawable/select_color_icon.png b/examples/0204/MyAndroidTutorial/bin/res/crunch/drawable/select_color_icon.png
deleted file mode 100644
index 4270ec5..0000000
Binary files a/examples/0204/MyAndroidTutorial/bin/res/crunch/drawable/select_color_icon.png and /dev/null differ
diff --git a/examples/0204/MyAndroidTutorial/bin/res/crunch/drawable/take_picture_icon.png b/examples/0204/MyAndroidTutorial/bin/res/crunch/drawable/take_picture_icon.png
deleted file mode 100644
index c812e2f..0000000
Binary files a/examples/0204/MyAndroidTutorial/bin/res/crunch/drawable/take_picture_icon.png and /dev/null differ
diff --git a/examples/0204/MyAndroidTutorial/bin/resources.ap_ b/examples/0204/MyAndroidTutorial/bin/resources.ap_
deleted file mode 100644
index 3d34c0f..0000000
Binary files a/examples/0204/MyAndroidTutorial/bin/resources.ap_ and /dev/null differ
diff --git a/examples/0204/MyAndroidTutorial/build.gradle b/examples/0204/MyAndroidTutorial/build.gradle
new file mode 100644
index 0000000..6356aab
--- /dev/null
+++ b/examples/0204/MyAndroidTutorial/build.gradle
@@ -0,0 +1,19 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+ repositories {
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:1.0.0'
+
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+}
+
+allprojects {
+ repositories {
+ jcenter()
+ }
+}
diff --git a/examples/0204/MyAndroidTutorial/gen/net/macdidi/myandroidtutorial/BuildConfig.java b/examples/0204/MyAndroidTutorial/gen/net/macdidi/myandroidtutorial/BuildConfig.java
deleted file mode 100644
index 5d44ea9..0000000
--- a/examples/0204/MyAndroidTutorial/gen/net/macdidi/myandroidtutorial/BuildConfig.java
+++ /dev/null
@@ -1,6 +0,0 @@
-/** Automatically generated file. DO NOT MODIFY */
-package net.macdidi.myandroidtutorial;
-
-public final class BuildConfig {
- public final static boolean DEBUG = true;
-}
\ No newline at end of file
diff --git a/examples/0204/MyAndroidTutorial/gen/net/macdidi/myandroidtutorial/R.java b/examples/0204/MyAndroidTutorial/gen/net/macdidi/myandroidtutorial/R.java
deleted file mode 100644
index e28e906..0000000
--- a/examples/0204/MyAndroidTutorial/gen/net/macdidi/myandroidtutorial/R.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/* AUTO-GENERATED FILE. DO NOT MODIFY.
- *
- * This class was automatically generated by the
- * aapt tool from the resource data it found. It
- * should not be modified by hand.
- */
-
-package net.macdidi.myandroidtutorial;
-
-public final class R {
- public static final class attr {
- }
- public static final class color {
- public static final int dark_text=0x7f040003;
- public static final int divider_color=0x7f040002;
- public static final int grey=0x7f040001;
- public static final int light_grey=0x7f040000;
- }
- public static final class dimen {
- public static final int default_margin=0x7f050001;
- public static final int default_padding=0x7f050000;
- public static final int title_txt_size=0x7f050002;
- }
- public static final class drawable {
- public static final int alarm_icon=0x7f020000;
- public static final int ic_launcher=0x7f020001;
- public static final int location_icon=0x7f020002;
- public static final int record_sound_icon=0x7f020003;
- public static final int retangle_drawable=0x7f020004;
- public static final int select_color_icon=0x7f020005;
- public static final int take_picture_icon=0x7f020006;
- }
- public static final class id {
- public static final int add_item=0x7f09000c;
- public static final int cancel_item=0x7f090007;
- public static final int content_text=0x7f090001;
- public static final int delete_item=0x7f09000e;
- public static final int facebook_item=0x7f090011;
- public static final int googleplus_item=0x7f090010;
- public static final int item_list=0x7f090009;
- public static final int ok_teim=0x7f090008;
- public static final int record_sound=0x7f090003;
- public static final int revert_item=0x7f09000d;
- public static final int search_item=0x7f09000b;
- public static final int select_color=0x7f090006;
- public static final int set_alarm=0x7f090005;
- public static final int set_location=0x7f090004;
- public static final int share_item=0x7f09000f;
- public static final int show_app_name=0x7f09000a;
- public static final int take_picture=0x7f090002;
- public static final int title_text=0x7f090000;
- }
- public static final class layout {
- public static final int activity_about=0x7f030000;
- public static final int activity_item=0x7f030001;
- public static final int activity_main=0x7f030002;
- }
- public static final class menu {
- public static final int main_menu=0x7f080000;
- }
- public static final class string {
- public static final int about=0x7f060006;
- public static final int app_name=0x7f060000;
- public static final int content=0x7f060004;
- public static final int enter_content=0x7f060005;
- public static final int enter_title=0x7f060003;
- public static final int hello_world=0x7f060009;
- public static final int title=0x7f060002;
- public static final int title_activity_hello=0x7f060008;
- public static final int title_activity_main=0x7f060001;
- public static final int version=0x7f060007;
- }
- public static final class style {
- /**
- Base application theme, dependent on API level. This theme is replaced
- by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
-
-
- Theme customizations available in newer API levels can go in
- res/values-vXX/styles.xml, while customizations related to
- backward-compatibility can go here.
-
-
- Base application theme for API 11+. This theme completely replaces
- AppBaseTheme from res/values/styles.xml on API 11+ devices.
-
- API 11 theme customizations can go here.
-
- Base application theme for API 14+. This theme completely replaces
- AppBaseTheme from BOTH res/values/styles.xml and
- res/values-v11/styles.xml on API 14+ devices.
-
- API 14 theme customizations can go here.
- */
- public static final int AppBaseTheme=0x7f070000;
- /** Application theme.
- All customizations that are NOT specific to a particular API-level can go here.
- */
- public static final int AppTheme=0x7f070001;
- }
-}
diff --git a/examples/0204/MyAndroidTutorial/gradle.properties b/examples/0204/MyAndroidTutorial/gradle.properties
new file mode 100644
index 0000000..1d3591c
--- /dev/null
+++ b/examples/0204/MyAndroidTutorial/gradle.properties
@@ -0,0 +1,18 @@
+# Project-wide Gradle settings.
+
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+# Default value: -Xmx10248m -XX:MaxPermSize=256m
+# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
+
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
\ No newline at end of file
diff --git a/examples/0204/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.jar b/examples/0204/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
Binary files /dev/null and b/examples/0204/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/examples/0204/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.properties b/examples/0204/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..0c71e76
--- /dev/null
+++ b/examples/0204/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
diff --git a/examples/0204/MyAndroidTutorial/gradlew b/examples/0204/MyAndroidTutorial/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/examples/0204/MyAndroidTutorial/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/examples/0204/MyAndroidTutorial/gradlew.bat b/examples/0204/MyAndroidTutorial/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/examples/0204/MyAndroidTutorial/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/examples/0204/MyAndroidTutorial/libs/android-support-v4.jar b/examples/0204/MyAndroidTutorial/libs/android-support-v4.jar
deleted file mode 100644
index 187bdf4..0000000
Binary files a/examples/0204/MyAndroidTutorial/libs/android-support-v4.jar and /dev/null differ
diff --git a/examples/0204/MyAndroidTutorial/proguard-project.txt b/examples/0204/MyAndroidTutorial/proguard-project.txt
deleted file mode 100644
index f2fe155..0000000
--- a/examples/0204/MyAndroidTutorial/proguard-project.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-# To enable ProGuard in your project, edit project.properties
-# to define the proguard.config property as described in that file.
-#
-# Add project specific ProGuard rules here.
-# By default, the flags in this file are appended to flags specified
-# in ${sdk.dir}/tools/proguard/proguard-android.txt
-# You can edit the include path and order by changing the ProGuard
-# include property in project.properties.
-#
-# For more details, see
-# http://developer.android.com/guide/developing/tools/proguard.html
-
-# Add any project specific keep options here:
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-# public *;
-#}
diff --git a/examples/0204/MyAndroidTutorial/project.properties b/examples/0204/MyAndroidTutorial/project.properties
deleted file mode 100644
index 4ab1256..0000000
--- a/examples/0204/MyAndroidTutorial/project.properties
+++ /dev/null
@@ -1,14 +0,0 @@
-# This file is automatically generated by Android Tools.
-# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
-#
-# This file must be checked in Version Control Systems.
-#
-# To customize properties used by the Ant build system edit
-# "ant.properties", and override values to adapt the script to your
-# project structure.
-#
-# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
-#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
-
-# Project target.
-target=android-19
diff --git a/examples/0204/MyAndroidTutorial/res/drawable/retangle_drawable.xml b/examples/0204/MyAndroidTutorial/res/drawable/retangle_drawable.xml
deleted file mode 100644
index e195342..0000000
--- a/examples/0204/MyAndroidTutorial/res/drawable/retangle_drawable.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/examples/0204/MyAndroidTutorial/res/layout/activity_about.xml b/examples/0204/MyAndroidTutorial/res/layout/activity_about.xml
deleted file mode 100644
index 738fe98..0000000
--- a/examples/0204/MyAndroidTutorial/res/layout/activity_about.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/examples/0204/MyAndroidTutorial/res/layout/activity_item.xml b/examples/0204/MyAndroidTutorial/res/layout/activity_item.xml
deleted file mode 100755
index 87fd821..0000000
--- a/examples/0204/MyAndroidTutorial/res/layout/activity_item.xml
+++ /dev/null
@@ -1,92 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/examples/0204/MyAndroidTutorial/res/layout/activity_main.xml b/examples/0204/MyAndroidTutorial/res/layout/activity_main.xml
deleted file mode 100644
index 418c34b..0000000
--- a/examples/0204/MyAndroidTutorial/res/layout/activity_main.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
diff --git a/examples/0204/MyAndroidTutorial/res/menu/main_menu.xml b/examples/0204/MyAndroidTutorial/res/menu/main_menu.xml
deleted file mode 100644
index 030587f..0000000
--- a/examples/0204/MyAndroidTutorial/res/menu/main_menu.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/examples/0204/MyAndroidTutorial/res/values-en/strings.xml b/examples/0204/MyAndroidTutorial/res/values-en/strings.xml
deleted file mode 100644
index 34f4fed..0000000
--- a/examples/0204/MyAndroidTutorial/res/values-en/strings.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
- MyAndroidTutorial
- MainActivity
- Hello world!
-
- Title
- Enter title
- Content
- Enter content
-
-
diff --git a/examples/0204/MyAndroidTutorial/res/values-v11/styles.xml b/examples/0204/MyAndroidTutorial/res/values-v11/styles.xml
deleted file mode 100644
index 3c02242..0000000
--- a/examples/0204/MyAndroidTutorial/res/values-v11/styles.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
diff --git a/examples/0204/MyAndroidTutorial/res/values-v14/styles.xml b/examples/0204/MyAndroidTutorial/res/values-v14/styles.xml
deleted file mode 100644
index a91fd03..0000000
--- a/examples/0204/MyAndroidTutorial/res/values-v14/styles.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
diff --git a/examples/0204/MyAndroidTutorial/res/values/colors.xml b/examples/0204/MyAndroidTutorial/res/values/colors.xml
deleted file mode 100644
index c63ec2d..0000000
--- a/examples/0204/MyAndroidTutorial/res/values/colors.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
- #CCCCCC
- #AAAAAA
- #DDCCCCCC
- #111111
-
diff --git a/examples/0204/MyAndroidTutorial/res/values/dimens.xml b/examples/0204/MyAndroidTutorial/res/values/dimens.xml
deleted file mode 100644
index fb03071..0000000
--- a/examples/0204/MyAndroidTutorial/res/values/dimens.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
- 6dp
- 2dp
- 24sp
-
diff --git a/examples/0204/MyAndroidTutorial/res/values/strings.xml b/examples/0204/MyAndroidTutorial/res/values/strings.xml
deleted file mode 100644
index c83608f..0000000
--- a/examples/0204/MyAndroidTutorial/res/values/strings.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
- MyAndroidTutorial
- MyAndroidTutorial
- 標題
- 輸入標題
- 內容
- 輸入內容
- 這是Android Tutorial應用程式
- 版本:AndroidTutorial_0.2.4
- HelloActivity
- Hello world!
-
-
diff --git a/examples/0204/MyAndroidTutorial/res/values/styles.xml b/examples/0204/MyAndroidTutorial/res/values/styles.xml
deleted file mode 100644
index 6ce89c7..0000000
--- a/examples/0204/MyAndroidTutorial/res/values/styles.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
-
-
-
-
-
-
diff --git a/examples/0204/MyAndroidTutorial/settings.gradle b/examples/0204/MyAndroidTutorial/settings.gradle
new file mode 100644
index 0000000..e7b4def
--- /dev/null
+++ b/examples/0204/MyAndroidTutorial/settings.gradle
@@ -0,0 +1 @@
+include ':app'
diff --git a/examples/0204/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/AboutActivity.java b/examples/0204/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/AboutActivity.java
deleted file mode 100644
index 111efc5..0000000
--- a/examples/0204/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/AboutActivity.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package net.macdidi.myandroidtutorial;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.view.View;
-import android.view.Window;
-
-public class AboutActivity extends Activity {
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- // 取消元件的應用程式標題
- requestWindowFeature(Window.FEATURE_NO_TITLE);
- setContentView(R.layout.activity_about);
- }
-
- // 結束按鈕
- public void clickOk(View view) {
- // 呼叫這個方法結束Activity元件
- finish();
- }
-
-}
diff --git a/examples/0204/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/ItemActivity.java b/examples/0204/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/ItemActivity.java
deleted file mode 100755
index 7caff18..0000000
--- a/examples/0204/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/ItemActivity.java
+++ /dev/null
@@ -1,79 +0,0 @@
-package net.macdidi.myandroidtutorial;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.os.Bundle;
-import android.view.View;
-import android.widget.EditText;
-
-public class ItemActivity extends Activity {
-
- private EditText title_text, content_text;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_item);
-
- processViews();
-
- // 取得Intent物件
- Intent intent = getIntent();
- // 讀取Action名稱
- String action = intent.getAction();
-
- // 如果是修改記事
- if (action.equals("net.macdidi.myandroidtutorial.EDIT_ITEM")) {
- // 接收與設定記事標題
- String titleText = intent.getStringExtra("titleText");
- title_text.setText(titleText);
- }
- }
-
- private void processViews() {
- title_text = (EditText) findViewById(R.id.title_text);
- content_text = (EditText) findViewById(R.id.content_text);
- }
-
- // 點擊確定與取消按鈕都會呼叫這個方法
- public void onSubmit(View view) {
- // 確定按鈕
- if (view.getId() == R.id.ok_teim) {
- // 讀取使用者輸入的標題與內容
- String titleText = title_text.getText().toString();
- String contentText = content_text.getText().toString();
-
- // 取得回傳資料用的Intent物件
- Intent result = getIntent();
- // 設定標題與內容
- result.putExtra("titleText", titleText);
- result.putExtra("contentText", contentText);
-
- // 設定回應結果為確定
- setResult(Activity.RESULT_OK, result);
- }
-
- // 結束
- finish();
- }
-
- // 以後需要擴充的功能
- public void clickFunction(View view) {
- int id = view.getId();
-
- switch (id) {
- case R.id.take_picture:
- break;
- case R.id.record_sound:
- break;
- case R.id.set_location:
- break;
- case R.id.set_alarm:
- break;
- case R.id.select_color:
- break;
- }
-
- }
-
-}
diff --git a/examples/0204/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/MainActivity.java b/examples/0204/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/MainActivity.java
deleted file mode 100644
index 2bd7ca3..0000000
--- a/examples/0204/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/MainActivity.java
+++ /dev/null
@@ -1,191 +0,0 @@
-package net.macdidi.myandroidtutorial;
-
-import java.util.ArrayList;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.content.Intent;
-import android.os.Bundle;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.View.OnLongClickListener;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemClickListener;
-import android.widget.AdapterView.OnItemLongClickListener;
-import android.widget.ArrayAdapter;
-import android.widget.ListView;
-import android.widget.TextView;
-import android.widget.Toast;
-
-public class MainActivity extends Activity {
-
- private ListView item_list;
- private TextView show_app_name;
-
- // 換掉原來的字串陣列
- private ArrayList data = new ArrayList<>();
- private ArrayAdapter adapter;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
-
- processViews();
- processControllers();
-
- // 加入範例資料
- data.add("關於Android Tutorial的事情");
- data.add("一隻非常可愛的小狗狗!");
- data.add("一首非常好聽的音樂!");
-
- int layoutId = android.R.layout.simple_list_item_1;
- adapter = new ArrayAdapter(this, layoutId, data);
- item_list.setAdapter(adapter);
- }
-
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- // 如果被啟動的Activity元件傳回確定的結果
- if (resultCode == Activity.RESULT_OK) {
- // 讀取標題
- String titleText = data.getStringExtra("titleText");
-
- // 如果是新增記事
- if (requestCode == 0) {
- // 加入標題項目
- this.data.add(titleText);
- // 通知資料已經改變,ListView元件才會重新顯示
- adapter.notifyDataSetChanged();
- }
- // 如果是修改記事
- else if (requestCode == 1) {
- // 讀取記事編號
- int position = data.getIntExtra("position", -1);
-
- if (position != -1) {
- // 設定標題項目
- this.data.set(position, titleText);
- // 通知資料已經改變,ListView元件才會重新顯示
- adapter.notifyDataSetChanged();
- }
- }
- }
- }
-
- private void processViews() {
- item_list = (ListView)findViewById(R.id.item_list);
- show_app_name = (TextView) findViewById(R.id.show_app_name);
- }
-
- private void processControllers() {
- // 建立選單項目點擊監聽物件
- OnItemClickListener itemListener = new OnItemClickListener() {
- // 第一個參數是使用者操作的ListView物件
- // 第二個參數是使用者選擇的項目
- // 第三個參數是使用者選擇的項目編號,第一個是0
- // 第四個參數在這裡沒有用途
- @Override
- public void onItemClick(AdapterView> parent, View view,
- int position, long id) {
- // 使用Action名稱建立啟動另一個Activity元件需要的Intent物件
- Intent intent = new Intent("net.macdidi.myandroidtutorial.EDIT_ITEM");
-
- // 設定記事編號與標題
- intent.putExtra("position", position);
- intent.putExtra("titleText", data.get(position));
-
- // 呼叫「startActivityForResult」,第二個參數「1」表示執行修改
- startActivityForResult(intent, 1);
- }
- };
-
- // 註冊選單項目點擊監聽物件
- item_list.setOnItemClickListener(itemListener);
-
- // 建立選單項目長按監聽物件
- OnItemLongClickListener itemLongListener = new OnItemLongClickListener() {
- // 第一個參數是使用者操作的ListView物件
- // 第二個參數是使用者選擇的項目
- // 第三個參數是使用者選擇的項目編號,第一個是0
- // 第四個參數在這裡沒有用途
- @Override
- public boolean onItemLongClick(AdapterView> parent, View view,
- int position, long id) {
- // 換掉「data[position]」
- Toast.makeText(MainActivity.this,
- "Long: " + data.get(position), Toast.LENGTH_LONG).show();
- return false;
- }
- };
-
- // 註冊選單項目長按監聽物件
- item_list.setOnItemLongClickListener(itemLongListener);
-
- // 建立長按監聽物件
- OnLongClickListener listener = new OnLongClickListener() {
-
- @Override
- public boolean onLongClick(View view) {
- AlertDialog.Builder dialog =
- new AlertDialog.Builder(MainActivity.this);
- dialog.setTitle(R.string.app_name)
- .setMessage(R.string.about)
- .show();
- return false;
- }
-
- };
-
- // 註冊長按監聽物件
- show_app_name.setOnLongClickListener(listener);
- }
-
- // 載入選單資源
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- MenuInflater menuInflater = getMenuInflater();
- menuInflater.inflate(R.menu.main_menu, menu);
- return true;
- }
-
- // 使用者選擇所有的選單項目都會呼叫這個方法
- public void clickMenuItem(MenuItem item) {
- // 使用參數取得使用者選擇的選單項目元件編號
- int itemId = item.getItemId();
-
- // 判斷該執行什麼工作,目前還沒有加入需要執行的工作
- switch (itemId) {
- case R.id.search_item:
- break;
- case R.id.add_item:
- // 使用Action名稱建立啟動另一個Activity元件需要的Intent物件
- Intent intent = new Intent("net.macdidi.myandroidtutorial.ADD_ITEM");
- // 呼叫「startActivityForResult」,,第二個參數「0」表示執行新增
- startActivityForResult(intent, 0);
- break;
- case R.id.revert_item:
- break;
- case R.id.delete_item:
- break;
- case R.id.googleplus_item:
- break;
- case R.id.facebook_item:
- break;
- }
-
- }
-
- // 點擊應用程式名稱元件後呼叫的方法
- public void aboutApp(View view) {
- // 建立啟動另一個Activity元件需要的Intent物件
- // 建構式的第一個參數:「this」
- // 建構式的第二個參數:「Activity元件類別名稱.class」
- Intent intent = new Intent(this, AboutActivity.class);
- // 呼叫「startActivity」,參數為一個建立好的Intent物件
- // 這行敘述執行以後,如果沒有任何錯誤,就會啟動指定的元件
- startActivity(intent);
- }
-}
diff --git a/examples/0301/MyAndroidTutorial/.classpath b/examples/0301/MyAndroidTutorial/.classpath
deleted file mode 100755
index 7bc01d9..0000000
--- a/examples/0301/MyAndroidTutorial/.classpath
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
-
-
-
-
diff --git a/examples/0301/MyAndroidTutorial/.gitignore b/examples/0301/MyAndroidTutorial/.gitignore
new file mode 100644
index 0000000..afbdab3
--- /dev/null
+++ b/examples/0301/MyAndroidTutorial/.gitignore
@@ -0,0 +1,6 @@
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
diff --git a/examples/0301/MyAndroidTutorial/.idea/.name b/examples/0301/MyAndroidTutorial/.idea/.name
new file mode 100644
index 0000000..5bb7a85
--- /dev/null
+++ b/examples/0301/MyAndroidTutorial/.idea/.name
@@ -0,0 +1 @@
+MyAndroidTutorial
\ No newline at end of file
diff --git a/examples/0301/MyAndroidTutorial/.idea/compiler.xml b/examples/0301/MyAndroidTutorial/.idea/compiler.xml
new file mode 100644
index 0000000..217af47
--- /dev/null
+++ b/examples/0301/MyAndroidTutorial/.idea/compiler.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0301/MyAndroidTutorial/.idea/copyright/profiles_settings.xml b/examples/0301/MyAndroidTutorial/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..e7bedf3
--- /dev/null
+++ b/examples/0301/MyAndroidTutorial/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/examples/0301/MyAndroidTutorial/.idea/encodings.xml b/examples/0301/MyAndroidTutorial/.idea/encodings.xml
new file mode 100644
index 0000000..e206d70
--- /dev/null
+++ b/examples/0301/MyAndroidTutorial/.idea/encodings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/examples/0301/MyAndroidTutorial/.idea/gradle.xml b/examples/0301/MyAndroidTutorial/.idea/gradle.xml
new file mode 100644
index 0000000..fe865d3
--- /dev/null
+++ b/examples/0301/MyAndroidTutorial/.idea/gradle.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0301/MyAndroidTutorial/.idea/misc.xml b/examples/0301/MyAndroidTutorial/.idea/misc.xml
new file mode 100644
index 0000000..9076de5
--- /dev/null
+++ b/examples/0301/MyAndroidTutorial/.idea/misc.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0301/MyAndroidTutorial/.idea/modules.xml b/examples/0301/MyAndroidTutorial/.idea/modules.xml
new file mode 100644
index 0000000..327df67
--- /dev/null
+++ b/examples/0301/MyAndroidTutorial/.idea/modules.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0301/MyAndroidTutorial/.idea/scopes/scope_settings.xml b/examples/0301/MyAndroidTutorial/.idea/scopes/scope_settings.xml
new file mode 100644
index 0000000..922003b
--- /dev/null
+++ b/examples/0301/MyAndroidTutorial/.idea/scopes/scope_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0301/MyAndroidTutorial/.idea/vcs.xml b/examples/0301/MyAndroidTutorial/.idea/vcs.xml
new file mode 100644
index 0000000..def6a6a
--- /dev/null
+++ b/examples/0301/MyAndroidTutorial/.idea/vcs.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/examples/0301/MyAndroidTutorial/.project b/examples/0301/MyAndroidTutorial/.project
deleted file mode 100755
index b1de407..0000000
--- a/examples/0301/MyAndroidTutorial/.project
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
- MyAndroidTutorial
-
-
-
-
-
- com.android.ide.eclipse.adt.ResourceManagerBuilder
-
-
-
-
- com.android.ide.eclipse.adt.PreCompilerBuilder
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- com.android.ide.eclipse.adt.ApkBuilder
-
-
-
-
-
- com.android.ide.eclipse.adt.AndroidNature
- org.eclipse.jdt.core.javanature
-
-
diff --git a/examples/0301/MyAndroidTutorial/.settings/org.eclipse.core.resources.prefs b/examples/0301/MyAndroidTutorial/.settings/org.eclipse.core.resources.prefs
deleted file mode 100644
index 99f26c0..0000000
--- a/examples/0301/MyAndroidTutorial/.settings/org.eclipse.core.resources.prefs
+++ /dev/null
@@ -1,2 +0,0 @@
-eclipse.preferences.version=1
-encoding/=UTF-8
diff --git a/examples/0301/MyAndroidTutorial/AndroidManifest.xml b/examples/0301/MyAndroidTutorial/AndroidManifest.xml
deleted file mode 100755
index 5cf0934..0000000
--- a/examples/0301/MyAndroidTutorial/AndroidManifest.xml
+++ /dev/null
@@ -1,52 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/examples/0301/MyAndroidTutorial/MyAndroidTutorial.iml b/examples/0301/MyAndroidTutorial/MyAndroidTutorial.iml
new file mode 100644
index 0000000..2a02201
--- /dev/null
+++ b/examples/0301/MyAndroidTutorial/MyAndroidTutorial.iml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0301/MyAndroidTutorial/app/.gitignore b/examples/0301/MyAndroidTutorial/app/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/examples/0301/MyAndroidTutorial/app/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/examples/0301/MyAndroidTutorial/app/app.iml b/examples/0301/MyAndroidTutorial/app/app.iml
new file mode 100644
index 0000000..c6c55c4
--- /dev/null
+++ b/examples/0301/MyAndroidTutorial/app/app.iml
@@ -0,0 +1,91 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0301/MyAndroidTutorial/app/build.gradle b/examples/0301/MyAndroidTutorial/app/build.gradle
new file mode 100644
index 0000000..b09f064
--- /dev/null
+++ b/examples/0301/MyAndroidTutorial/app/build.gradle
@@ -0,0 +1,25 @@
+apply plugin: 'com.android.application'
+
+android {
+ compileSdkVersion 21
+ buildToolsVersion "21.1.2"
+
+ defaultConfig {
+ applicationId "net.macdidi.myandroidtutorial"
+ minSdkVersion 15
+ targetSdkVersion 21
+ versionCode 1
+ versionName "1.0"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ compile fileTree(dir: 'libs', include: ['*.jar'])
+ compile 'com.android.support:appcompat-v7:21.0.3'
+}
diff --git a/examples/0301/MyAndroidTutorial/app/proguard-rules.pro b/examples/0301/MyAndroidTutorial/app/proguard-rules.pro
new file mode 100644
index 0000000..b5fa7ec
--- /dev/null
+++ b/examples/0301/MyAndroidTutorial/app/proguard-rules.pro
@@ -0,0 +1,17 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /Users/macdidi5/Library/Android/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
diff --git a/examples/0301/MyAndroidTutorial/app/src/androidTest/java/net/macdidi/myandroidtutorial/ApplicationTest.java b/examples/0301/MyAndroidTutorial/app/src/androidTest/java/net/macdidi/myandroidtutorial/ApplicationTest.java
new file mode 100644
index 0000000..2cb214e
--- /dev/null
+++ b/examples/0301/MyAndroidTutorial/app/src/androidTest/java/net/macdidi/myandroidtutorial/ApplicationTest.java
@@ -0,0 +1,13 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Application;
+import android.test.ApplicationTestCase;
+
+/**
+ * Testing Fundamentals
+ */
+public class ApplicationTest extends ApplicationTestCase {
+ public ApplicationTest() {
+ super(Application.class);
+ }
+}
\ No newline at end of file
diff --git a/examples/0301/MyAndroidTutorial/app/src/main/AndroidManifest.xml b/examples/0301/MyAndroidTutorial/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..8e54cd3
--- /dev/null
+++ b/examples/0301/MyAndroidTutorial/app/src/main/AndroidManifest.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0301/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/AboutActivity.java b/examples/0301/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/AboutActivity.java
new file mode 100644
index 0000000..42dddeb
--- /dev/null
+++ b/examples/0301/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/AboutActivity.java
@@ -0,0 +1,24 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.view.Window;
+
+public class AboutActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ // 取消元件的應用程式標題
+ requestWindowFeature(Window.FEATURE_NO_TITLE);
+ setContentView(R.layout.activity_about);
+ }
+
+ // 結束按鈕
+ public void clickOk(View view) {
+ // 呼叫這個方法結束Activity元件
+ finish();
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0301/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ColorActivity.java b/examples/0301/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ColorActivity.java
new file mode 100644
index 0000000..2d5412d
--- /dev/null
+++ b/examples/0301/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ColorActivity.java
@@ -0,0 +1,55 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.LinearLayout;
+
+public class ColorActivity extends Activity {
+
+ private LinearLayout color_gallery;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_color);
+
+ processViews();
+
+ ColorListener listener = new ColorListener();
+
+ for (Colors c : Colors.values()) {
+ Button button = new Button(this);
+ button.setId(c.parseColor());
+ LinearLayout.LayoutParams layout =
+ new LinearLayout.LayoutParams(128, 128);
+ layout.setMargins(6, 6, 6, 6);
+ button.setLayoutParams(layout);
+ button.setBackgroundColor(c.parseColor());
+
+ button.setOnClickListener(listener);
+
+ color_gallery.addView(button);
+ }
+ }
+
+ private void processViews() {
+ color_gallery = (LinearLayout) findViewById(R.id.color_gallery);
+ }
+
+ private class ColorListener implements OnClickListener {
+
+ @Override
+ public void onClick(View view) {
+ Intent result = getIntent();
+ result.putExtra("colorId", view.getId());
+ setResult(Activity.RESULT_OK, result);
+ finish();
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0301/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Colors.java b/examples/0301/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Colors.java
new file mode 100644
index 0000000..1462149
--- /dev/null
+++ b/examples/0301/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Colors.java
@@ -0,0 +1,24 @@
+package net.macdidi.myandroidtutorial;
+
+import android.graphics.Color;
+
+public enum Colors {
+
+ LIGHTGREY("#D3D3D3"), BLUE("#33B5E5"), PURPLE("#AA66CC"),
+ GREEN("#99CC00"), ORANGE("#FFBB33"), RED("#FF4444");
+
+ private String code;
+
+ private Colors(String code) {
+ this.code = code;
+ }
+
+ public String getCode() {
+ return code;
+ }
+
+ public int parseColor() {
+ return Color.parseColor(code);
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0301/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Item.java b/examples/0301/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Item.java
new file mode 100644
index 0000000..b015021
--- /dev/null
+++ b/examples/0301/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Item.java
@@ -0,0 +1,135 @@
+package net.macdidi.myandroidtutorial;
+
+import java.util.Date;
+import java.util.Locale;
+
+public class Item implements java.io.Serializable {
+
+ // 編號、日期時間、顏色、標題、內容、檔案名稱、經緯度、修改、已選擇
+ private long id;
+ private long datetime;
+ private Colors color;
+ private String title;
+ private String content;
+ private String fileName;
+ private double latitude;
+ private double longitude;
+ private long lastModify;
+ private boolean selected;
+
+ public Item() {
+ title = "";
+ content = "";
+ color = Colors.LIGHTGREY;
+ }
+
+ public Item(long id, long datetime, Colors color, String title,
+ String content, String fileName, double latitude, double longitude,
+ long lastModify) {
+ this.id = id;
+ this.datetime = datetime;
+ this.color = color;
+ this.title = title;
+ this.content = content;
+ this.fileName = fileName;
+ this.latitude = latitude;
+ this.longitude = longitude;
+ this.lastModify = lastModify;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public long getDatetime() {
+ return datetime;
+ }
+
+ // 裝置區域的日期時間
+ public String getLocaleDatetime() {
+ return String.format(Locale.getDefault(), "%tF % {
+
+ // 畫面資源編號
+ private int resource;
+ // 包裝的記事資料
+ private List- items;
+
+ public ItemAdapter(Context context, int resource, List
- items) {
+ super(context, resource, items);
+ this.resource = resource;
+ this.items = items;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ LinearLayout itemView;
+ // 讀取目前位置的記事物件
+ final Item item = getItem(position);
+
+ if (convertView == null) {
+ // 建立項目畫面元件
+ itemView = new LinearLayout(getContext());
+ String inflater = Context.LAYOUT_INFLATER_SERVICE;
+ LayoutInflater li = (LayoutInflater)
+ getContext().getSystemService(inflater);
+ li.inflate(resource, itemView, true);
+ }
+ else {
+ itemView = (LinearLayout) convertView;
+ }
+
+ // 讀取記事顏色、已選擇、標題與日期時間元件
+ RelativeLayout typeColor = (RelativeLayout) itemView.findViewById(R.id.type_color);
+ ImageView selectedItem = (ImageView) itemView.findViewById(R.id.selected_item);
+ TextView titleView = (TextView) itemView.findViewById(R.id.title_text);
+ TextView dateView = (TextView) itemView.findViewById(R.id.date_text);
+
+ // 設定記事顏色
+ GradientDrawable background = (GradientDrawable)typeColor.getBackground();
+ background.setColor(item.getColor().parseColor());
+
+ // 設定標題與日期時間
+ titleView.setText(item.getTitle());
+ dateView.setText(item.getLocaleDatetime());
+
+ // 設定是否已選擇
+ selectedItem.setVisibility(item.isSelected() ? View.VISIBLE : View.INVISIBLE);
+
+ return itemView;
+ }
+
+ // 設定指定編號的記事資料
+ public void set(int index, Item item) {
+ if (index >= 0 && index < items.size()) {
+ items.set(index, item);
+ notifyDataSetChanged();
+ }
+ }
+
+ // 讀取指定編號的記事資料
+ public Item get(int index) {
+ return items.get(index);
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0301/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MainActivity.java b/examples/0301/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MainActivity.java
new file mode 100644
index 0000000..3b59d6e
--- /dev/null
+++ b/examples/0301/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MainActivity.java
@@ -0,0 +1,299 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.v7.app.ActionBarActivity;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+public class MainActivity extends ActionBarActivity {
+ private ListView item_list;
+ private TextView show_app_name;
+
+ // ListView使用的自定Adapter物件
+ private ItemAdapter itemAdapter;
+ // 儲存所有記事本的List物件
+ private List
- items;
+
+ // 選單項目物件
+ private MenuItem add_item, search_item, revert_item, share_item, delete_item;
+
+ // 已選擇項目數量
+ private int selectedCount = 0;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ processViews();
+ processControllers();
+
+ // 加入範例資料
+ items = new ArrayList
- ();
+
+ items.add(new Item(1, new Date().getTime(), Colors.RED, "關於Android Tutorial的事情.", "Hello content", "", 0, 0, 0));
+ items.add(new Item(2, new Date().getTime(), Colors.BLUE, "一隻非常可愛的小狗狗!", "她的名字叫「大熱狗」,又叫\n作「奶嘴」,是一隻非常可愛\n的小狗。", "", 0, 0, 0));
+ items.add(new Item(3, new Date().getTime(), Colors.GREEN, "一首非常好聽的音樂!", "Hello content", "", 0, 0, 0));
+
+ // 建立自定Adapter物件
+ itemAdapter = new ItemAdapter(this, R.layout.single_item, items);
+ item_list.setAdapter(itemAdapter);
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ // 如果被啟動的Activity元件傳回確定的結果
+ if (resultCode == Activity.RESULT_OK) {
+ // 讀取記事物件
+ Item item = (Item) data.getExtras().getSerializable(
+ "net.macdidi.myandroidtutorial.Item");
+
+ // 如果是新增記事
+ if (requestCode == 0) {
+ // 設定記事物件的編號與日期時間
+ item.setId(items.size() + 1);
+ item.setDatetime(new Date().getTime());
+
+ // 加入新增的記事物件
+ items.add(item);
+
+ // 通知資料改變
+ itemAdapter.notifyDataSetChanged();
+ }
+ // 如果是修改記事
+ else if (requestCode == 1) {
+ // 讀取記事編號
+ int position = data.getIntExtra("position", -1);
+
+ if (position != -1) {
+ // 設定修改的記事物件
+ items.set(position, item);
+ itemAdapter.notifyDataSetChanged();
+ }
+ }
+ }
+ }
+
+ private void processViews() {
+ item_list = (ListView)findViewById(R.id.item_list);
+ show_app_name = (TextView) findViewById(R.id.show_app_name);
+ }
+
+ private void processControllers() {
+
+ // 建立選單項目點擊監聽物件
+ AdapterView.OnItemClickListener itemListener = new AdapterView.OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView> parent, View view,
+ int position, long id) {
+ // 讀取選擇的記事物件
+ Item item = itemAdapter.getItem(position);
+
+ // 如果已經有勾選的項目
+ if (selectedCount > 0) {
+ // 處理是否顯示已選擇項目
+ processMenu(item);
+ // 重新設定記事項目
+ itemAdapter.set(position, item);
+ }
+ else {
+ Intent intent = new Intent(
+ "net.macdidi.myandroidtutorial.EDIT_ITEM");
+
+ // 設定記事編號與記事物件
+ intent.putExtra("position", position);
+ intent.putExtra("net.macdidi.myandroidtutorial.Item", item);
+
+ startActivityForResult(intent, 1);
+ }
+ }
+ };
+
+ // 註冊選單項目點擊監聽物件
+ item_list.setOnItemClickListener(itemListener);
+
+ // 建立記事項目長按監聽物件
+ AdapterView.OnItemLongClickListener itemLongListener = new AdapterView.OnItemLongClickListener() {
+ @Override
+ public boolean onItemLongClick(AdapterView> parent, View view,
+ int position, long id) {
+ // 讀取選擇的記事物件
+ Item item = itemAdapter.getItem(position);
+ // 處理是否顯示已選擇項目
+ processMenu(item);
+ // 重新設定記事項目
+ itemAdapter.set(position, item);
+ return true;
+ }
+ };
+
+ // 註冊記事項目長按監聽物件
+ item_list.setOnItemLongClickListener(itemLongListener);
+
+ // 建立長按監聽物件
+ View.OnLongClickListener listener = new View.OnLongClickListener() {
+
+ @Override
+ public boolean onLongClick(View view) {
+ AlertDialog.Builder dialog =
+ new AlertDialog.Builder(MainActivity.this);
+ dialog.setTitle(R.string.app_name)
+ .setMessage(R.string.about)
+ .show();
+ return false;
+ }
+
+ };
+
+ // 註冊長按監聽物件
+ show_app_name.setOnLongClickListener(listener);
+ }
+
+ // 處理是否顯示已選擇項目
+ private void processMenu(Item item) {
+ // 如果需要設定記事項目
+ if (item != null) {
+ // 設定已勾選的狀態
+ item.setSelected(!item.isSelected());
+
+ // 計算已勾選數量
+ if (item.isSelected()) {
+ selectedCount++;
+ }
+ else {
+ selectedCount--;
+ }
+ }
+
+ // 根據選擇的狀況,設定是否顯示選單項目
+ add_item.setVisible(selectedCount == 0);
+ search_item.setVisible(selectedCount == 0);
+ revert_item.setVisible(selectedCount > 0);
+ share_item.setVisible(selectedCount > 0);
+ delete_item.setVisible(selectedCount > 0);
+ }
+
+ // 載入選單資源
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ MenuInflater menuInflater = getMenuInflater();
+ menuInflater.inflate(R.menu.menu_main, menu);
+
+ // 取得選單項目物件
+ add_item = menu.findItem(R.id.add_item);
+ search_item = menu.findItem(R.id.search_item);
+ revert_item = menu.findItem(R.id.revert_item);
+ share_item = menu.findItem(R.id.share_item);
+ delete_item = menu.findItem(R.id.delete_item);
+
+ // 設定選單項目
+ processMenu(null);
+
+ return true;
+ }
+
+ // 使用者選擇所有的選單項目都會呼叫這個方法
+ public void clickMenuItem(MenuItem item) {
+ // 使用參數取得使用者選擇的選單項目元件編號
+ int itemId = item.getItemId();
+
+ // 判斷該執行什麼工作,目前還沒有加入需要執行的工作
+ switch (itemId) {
+ case R.id.search_item:
+ break;
+ // 使用者選擇新增選單項目
+ case R.id.add_item:
+ // 使用Action名稱建立啟動另一個Activity元件需要的Intent物件
+ Intent intent = new Intent("net.macdidi.myandroidtutorial.ADD_ITEM");
+ // 呼叫「startActivityForResult」,,第二個參數「0」表示執行新增
+ startActivityForResult(intent, 0);
+ break;
+ // 取消所有已勾選的項目
+ case R.id.revert_item:
+ for (int i = 0; i < itemAdapter.getCount(); i++) {
+ Item ri = itemAdapter.getItem(i);
+
+ if (ri.isSelected()) {
+ ri.setSelected(false);
+ itemAdapter.set(i, ri);
+ }
+ }
+
+ selectedCount = 0;
+ processMenu(null);
+
+ break;
+ // 刪除
+ case R.id.delete_item:
+ // 沒有選擇
+ if (selectedCount == 0) {
+ break;
+ }
+
+ // 建立與顯示詢問是否刪除的對話框
+ AlertDialog.Builder d = new AlertDialog.Builder(this);
+ String message = getString(R.string.delete_item);
+ d.setTitle(R.string.delete)
+ .setMessage(String.format(message, selectedCount));
+ d.setPositiveButton(android.R.string.yes,
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ // 刪除所有已勾選的項目
+ int index = itemAdapter.getCount() - 1;
+
+ while (index > -1) {
+ Item item = itemAdapter.get(index);
+
+ if (item.isSelected()) {
+ itemAdapter.remove(item);
+ }
+
+ index--;
+ }
+
+ // 通知資料改變
+ itemAdapter.notifyDataSetChanged();
+ selectedCount = 0;
+ processMenu(null);
+ }
+ });
+ d.setNegativeButton(android.R.string.no, null);
+ d.show();
+
+ break;
+ case R.id.googleplus_item:
+ break;
+ case R.id.facebook_item:
+ break;
+ }
+
+ }
+
+ // 方法名稱與onClick的設定一樣,參數的型態是android.view.View
+ public void aboutApp(View view) {
+ // 建立啟動另一個Activity元件需要的Intent物件
+ // 建構式的第一個參數:「this」
+ // 建構式的第二個參數:「Activity元件類別名稱.class」
+ Intent intent = new Intent(this, AboutActivity.class);
+ // 呼叫「startActivity」,參數為一個建立好的Intent物件
+ // 這行敘述執行以後,如果沒有任何錯誤,就會啟動指定的元件
+ startActivity(intent);
+ }
+
+}
+
+
diff --git a/examples/0301/MyAndroidTutorial/res/drawable-hdpi/ic_launcher.png b/examples/0301/MyAndroidTutorial/app/src/main/res/drawable-hdpi/ic_launcher.png
old mode 100755
new mode 100644
similarity index 100%
rename from examples/0301/MyAndroidTutorial/res/drawable-hdpi/ic_launcher.png
rename to examples/0301/MyAndroidTutorial/app/src/main/res/drawable-hdpi/ic_launcher.png
diff --git a/examples/0301/MyAndroidTutorial/res/drawable-mdpi/ic_launcher.png b/examples/0301/MyAndroidTutorial/app/src/main/res/drawable-mdpi/ic_launcher.png
old mode 100755
new mode 100644
similarity index 100%
rename from examples/0301/MyAndroidTutorial/res/drawable-mdpi/ic_launcher.png
rename to examples/0301/MyAndroidTutorial/app/src/main/res/drawable-mdpi/ic_launcher.png
diff --git a/examples/0301/MyAndroidTutorial/res/drawable-xhdpi/ic_launcher.png b/examples/0301/MyAndroidTutorial/app/src/main/res/drawable-xhdpi/ic_launcher.png
old mode 100755
new mode 100644
similarity index 100%
rename from examples/0301/MyAndroidTutorial/res/drawable-xhdpi/ic_launcher.png
rename to examples/0301/MyAndroidTutorial/app/src/main/res/drawable-xhdpi/ic_launcher.png
diff --git a/examples/0301/MyAndroidTutorial/app/src/main/res/drawable-xxhdpi/ic_launcher.png b/examples/0301/MyAndroidTutorial/app/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..4df1894
Binary files /dev/null and b/examples/0301/MyAndroidTutorial/app/src/main/res/drawable-xxhdpi/ic_launcher.png differ
diff --git a/examples/0301/MyAndroidTutorial/res/drawable/alarm_icon.png b/examples/0301/MyAndroidTutorial/app/src/main/res/drawable/alarm_icon.png
old mode 100755
new mode 100644
similarity index 100%
rename from examples/0301/MyAndroidTutorial/res/drawable/alarm_icon.png
rename to examples/0301/MyAndroidTutorial/app/src/main/res/drawable/alarm_icon.png
diff --git a/examples/0301/MyAndroidTutorial/app/src/main/res/drawable/item_drawable.xml b/examples/0301/MyAndroidTutorial/app/src/main/res/drawable/item_drawable.xml
new file mode 100644
index 0000000..37607e2
--- /dev/null
+++ b/examples/0301/MyAndroidTutorial/app/src/main/res/drawable/item_drawable.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0301/MyAndroidTutorial/res/drawable/location_icon.png b/examples/0301/MyAndroidTutorial/app/src/main/res/drawable/location_icon.png
old mode 100755
new mode 100644
similarity index 100%
rename from examples/0301/MyAndroidTutorial/res/drawable/location_icon.png
rename to examples/0301/MyAndroidTutorial/app/src/main/res/drawable/location_icon.png
diff --git a/examples/0301/MyAndroidTutorial/res/drawable/record_sound_icon.png b/examples/0301/MyAndroidTutorial/app/src/main/res/drawable/record_sound_icon.png
old mode 100755
new mode 100644
similarity index 100%
rename from examples/0301/MyAndroidTutorial/res/drawable/record_sound_icon.png
rename to examples/0301/MyAndroidTutorial/app/src/main/res/drawable/record_sound_icon.png
diff --git a/examples/0301/MyAndroidTutorial/app/src/main/res/drawable/retangle_drawable.xml b/examples/0301/MyAndroidTutorial/app/src/main/res/drawable/retangle_drawable.xml
new file mode 100644
index 0000000..51d1e84
--- /dev/null
+++ b/examples/0301/MyAndroidTutorial/app/src/main/res/drawable/retangle_drawable.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0301/MyAndroidTutorial/res/drawable/select_color_icon.png b/examples/0301/MyAndroidTutorial/app/src/main/res/drawable/select_color_icon.png
old mode 100755
new mode 100644
similarity index 100%
rename from examples/0301/MyAndroidTutorial/res/drawable/select_color_icon.png
rename to examples/0301/MyAndroidTutorial/app/src/main/res/drawable/select_color_icon.png
diff --git a/examples/0301/MyAndroidTutorial/res/drawable/selected_icon.png b/examples/0301/MyAndroidTutorial/app/src/main/res/drawable/selected_icon.png
similarity index 100%
rename from examples/0301/MyAndroidTutorial/res/drawable/selected_icon.png
rename to examples/0301/MyAndroidTutorial/app/src/main/res/drawable/selected_icon.png
diff --git a/examples/0301/MyAndroidTutorial/res/drawable/take_picture_icon.png b/examples/0301/MyAndroidTutorial/app/src/main/res/drawable/take_picture_icon.png
old mode 100755
new mode 100644
similarity index 100%
rename from examples/0301/MyAndroidTutorial/res/drawable/take_picture_icon.png
rename to examples/0301/MyAndroidTutorial/app/src/main/res/drawable/take_picture_icon.png
diff --git a/examples/0301/MyAndroidTutorial/app/src/main/res/layout/activity_about.xml b/examples/0301/MyAndroidTutorial/app/src/main/res/layout/activity_about.xml
new file mode 100644
index 0000000..8e78611
--- /dev/null
+++ b/examples/0301/MyAndroidTutorial/app/src/main/res/layout/activity_about.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0301/MyAndroidTutorial/app/src/main/res/layout/activity_color.xml b/examples/0301/MyAndroidTutorial/app/src/main/res/layout/activity_color.xml
new file mode 100644
index 0000000..d25bbc5
--- /dev/null
+++ b/examples/0301/MyAndroidTutorial/app/src/main/res/layout/activity_color.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
diff --git a/examples/0301/MyAndroidTutorial/app/src/main/res/layout/activity_item.xml b/examples/0301/MyAndroidTutorial/app/src/main/res/layout/activity_item.xml
new file mode 100644
index 0000000..cb0c3bd
--- /dev/null
+++ b/examples/0301/MyAndroidTutorial/app/src/main/res/layout/activity_item.xml
@@ -0,0 +1,108 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0301/MyAndroidTutorial/app/src/main/res/layout/activity_main.xml b/examples/0301/MyAndroidTutorial/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..121511b
--- /dev/null
+++ b/examples/0301/MyAndroidTutorial/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
diff --git a/examples/0301/MyAndroidTutorial/app/src/main/res/layout/single_item.xml b/examples/0301/MyAndroidTutorial/app/src/main/res/layout/single_item.xml
new file mode 100644
index 0000000..40ddbc9
--- /dev/null
+++ b/examples/0301/MyAndroidTutorial/app/src/main/res/layout/single_item.xml
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0301/MyAndroidTutorial/app/src/main/res/menu/menu_about.xml b/examples/0301/MyAndroidTutorial/app/src/main/res/menu/menu_about.xml
new file mode 100644
index 0000000..d481100
--- /dev/null
+++ b/examples/0301/MyAndroidTutorial/app/src/main/res/menu/menu_about.xml
@@ -0,0 +1,7 @@
+
+
+
diff --git a/examples/0301/MyAndroidTutorial/app/src/main/res/menu/menu_color.xml b/examples/0301/MyAndroidTutorial/app/src/main/res/menu/menu_color.xml
new file mode 100644
index 0000000..8ff243b
--- /dev/null
+++ b/examples/0301/MyAndroidTutorial/app/src/main/res/menu/menu_color.xml
@@ -0,0 +1,7 @@
+
+
+
diff --git a/examples/0301/MyAndroidTutorial/app/src/main/res/menu/menu_item.xml b/examples/0301/MyAndroidTutorial/app/src/main/res/menu/menu_item.xml
new file mode 100644
index 0000000..cd2c9e4
--- /dev/null
+++ b/examples/0301/MyAndroidTutorial/app/src/main/res/menu/menu_item.xml
@@ -0,0 +1,7 @@
+
+
+
diff --git a/examples/0301/MyAndroidTutorial/app/src/main/res/menu/menu_main.xml b/examples/0301/MyAndroidTutorial/app/src/main/res/menu/menu_main.xml
new file mode 100644
index 0000000..024de57
--- /dev/null
+++ b/examples/0301/MyAndroidTutorial/app/src/main/res/menu/menu_main.xml
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
diff --git a/examples/0301/MyAndroidTutorial/app/src/main/res/values-en/strings.xml b/examples/0301/MyAndroidTutorial/app/src/main/res/values-en/strings.xml
new file mode 100644
index 0000000..c532533
--- /dev/null
+++ b/examples/0301/MyAndroidTutorial/app/src/main/res/values-en/strings.xml
@@ -0,0 +1,12 @@
+
+
+
+ MyAndroidTutorial
+ Hello world!
+ Settings
+
+ Title
+ Enter title
+ Content
+ Enter content
+
diff --git a/examples/0301/MyAndroidTutorial/app/src/main/res/values-w820dp/dimens.xml b/examples/0301/MyAndroidTutorial/app/src/main/res/values-w820dp/dimens.xml
new file mode 100644
index 0000000..63fc816
--- /dev/null
+++ b/examples/0301/MyAndroidTutorial/app/src/main/res/values-w820dp/dimens.xml
@@ -0,0 +1,6 @@
+
+
+ 64dp
+
diff --git a/examples/0301/MyAndroidTutorial/app/src/main/res/values/colors.xml b/examples/0301/MyAndroidTutorial/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..6b13c1d
--- /dev/null
+++ b/examples/0301/MyAndroidTutorial/app/src/main/res/values/colors.xml
@@ -0,0 +1,7 @@
+
+
+ #CCCCCC
+ #AAAAAA
+ #DD999999
+ #111111
+
\ No newline at end of file
diff --git a/examples/0301/MyAndroidTutorial/app/src/main/res/values/dimens.xml b/examples/0301/MyAndroidTutorial/app/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..02898ec
--- /dev/null
+++ b/examples/0301/MyAndroidTutorial/app/src/main/res/values/dimens.xml
@@ -0,0 +1,9 @@
+
+
+ 16dp
+ 16dp
+
+ 6dp
+ 24sp
+ 2dp
+
diff --git a/examples/0301/MyAndroidTutorial/app/src/main/res/values/strings.xml b/examples/0301/MyAndroidTutorial/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..630e062
--- /dev/null
+++ b/examples/0301/MyAndroidTutorial/app/src/main/res/values/strings.xml
@@ -0,0 +1,19 @@
+
+
+
+ MyAndroidTutorial
+ Hello world!
+ Settings
+ 標題
+ 輸入標題
+ 內容
+ 輸入內容
+ 這是Android Tutorial應用程式
+ AboutActivity
+ 版本:AndroidTutorial_0.2.4
+ ItemActivity
+ ColorActivity
+ 刪除
+ 確定要刪除 %1$d 個項目?
+
+
diff --git a/examples/0301/MyAndroidTutorial/app/src/main/res/values/styles.xml b/examples/0301/MyAndroidTutorial/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..766ab99
--- /dev/null
+++ b/examples/0301/MyAndroidTutorial/app/src/main/res/values/styles.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
diff --git a/examples/0301/MyAndroidTutorial/bin/AndroidManifest.xml b/examples/0301/MyAndroidTutorial/bin/AndroidManifest.xml
deleted file mode 100755
index 5cf0934..0000000
--- a/examples/0301/MyAndroidTutorial/bin/AndroidManifest.xml
+++ /dev/null
@@ -1,52 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/examples/0301/MyAndroidTutorial/bin/MyAndroidTutorial.apk b/examples/0301/MyAndroidTutorial/bin/MyAndroidTutorial.apk
deleted file mode 100644
index ca5282e..0000000
Binary files a/examples/0301/MyAndroidTutorial/bin/MyAndroidTutorial.apk and /dev/null differ
diff --git a/examples/0301/MyAndroidTutorial/bin/classes.dex b/examples/0301/MyAndroidTutorial/bin/classes.dex
deleted file mode 100755
index 10a8b2f..0000000
Binary files a/examples/0301/MyAndroidTutorial/bin/classes.dex and /dev/null differ
diff --git a/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/AboutActivity.class b/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/AboutActivity.class
deleted file mode 100644
index abbf876..0000000
Binary files a/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/AboutActivity.class and /dev/null differ
diff --git a/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/BuildConfig.class b/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/BuildConfig.class
deleted file mode 100644
index 30f5623..0000000
Binary files a/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/BuildConfig.class and /dev/null differ
diff --git a/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ColorActivity$ColorListener.class b/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ColorActivity$ColorListener.class
deleted file mode 100644
index 6a65175..0000000
Binary files a/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ColorActivity$ColorListener.class and /dev/null differ
diff --git a/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ColorActivity.class b/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ColorActivity.class
deleted file mode 100644
index 36dd667..0000000
Binary files a/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ColorActivity.class and /dev/null differ
diff --git a/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/Colors.class b/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/Colors.class
deleted file mode 100644
index 4dda566..0000000
Binary files a/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/Colors.class and /dev/null differ
diff --git a/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/Item.class b/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/Item.class
deleted file mode 100644
index f5449a6..0000000
Binary files a/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/Item.class and /dev/null differ
diff --git a/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ItemActivity.class b/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ItemActivity.class
deleted file mode 100644
index 0d32bc9..0000000
Binary files a/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ItemActivity.class and /dev/null differ
diff --git a/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ItemAdapter.class b/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ItemAdapter.class
deleted file mode 100644
index 3eae412..0000000
Binary files a/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ItemAdapter.class and /dev/null differ
diff --git a/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$1.class b/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$1.class
deleted file mode 100644
index e7d0223..0000000
Binary files a/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$1.class and /dev/null differ
diff --git a/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$2.class b/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$2.class
deleted file mode 100644
index 97be84f..0000000
Binary files a/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$2.class and /dev/null differ
diff --git a/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$3.class b/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$3.class
deleted file mode 100644
index fd51b0e..0000000
Binary files a/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$3.class and /dev/null differ
diff --git a/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$4.class b/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$4.class
deleted file mode 100644
index 6145ab2..0000000
Binary files a/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$4.class and /dev/null differ
diff --git a/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity.class b/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity.class
deleted file mode 100644
index c76f32a..0000000
Binary files a/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity.class and /dev/null differ
diff --git a/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$attr.class b/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$attr.class
deleted file mode 100644
index 9d83559..0000000
Binary files a/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$attr.class and /dev/null differ
diff --git a/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$color.class b/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$color.class
deleted file mode 100644
index 8646729..0000000
Binary files a/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$color.class and /dev/null differ
diff --git a/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$dimen.class b/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$dimen.class
deleted file mode 100644
index ab21b39..0000000
Binary files a/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$dimen.class and /dev/null differ
diff --git a/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$drawable.class b/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$drawable.class
deleted file mode 100644
index ef1ea1f..0000000
Binary files a/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$drawable.class and /dev/null differ
diff --git a/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$id.class b/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$id.class
deleted file mode 100644
index 1f93dd5..0000000
Binary files a/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$id.class and /dev/null differ
diff --git a/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$layout.class b/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$layout.class
deleted file mode 100644
index 5ae8d8f..0000000
Binary files a/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$layout.class and /dev/null differ
diff --git a/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$menu.class b/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$menu.class
deleted file mode 100644
index 8e3b342..0000000
Binary files a/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$menu.class and /dev/null differ
diff --git a/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$string.class b/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$string.class
deleted file mode 100644
index eba16b1..0000000
Binary files a/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$string.class and /dev/null differ
diff --git a/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$style.class b/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$style.class
deleted file mode 100644
index 90d6181..0000000
Binary files a/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$style.class and /dev/null differ
diff --git a/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R.class b/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R.class
deleted file mode 100644
index 3be8276..0000000
Binary files a/examples/0301/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R.class and /dev/null differ
diff --git a/examples/0301/MyAndroidTutorial/bin/dexedLibs/android-support-v4-9b1d5d28bf7d59a4e392b3d4f78c1f13.jar b/examples/0301/MyAndroidTutorial/bin/dexedLibs/android-support-v4-9b1d5d28bf7d59a4e392b3d4f78c1f13.jar
deleted file mode 100755
index 2f330c0..0000000
Binary files a/examples/0301/MyAndroidTutorial/bin/dexedLibs/android-support-v4-9b1d5d28bf7d59a4e392b3d4f78c1f13.jar and /dev/null differ
diff --git a/examples/0301/MyAndroidTutorial/bin/jarlist.cache b/examples/0301/MyAndroidTutorial/bin/jarlist.cache
deleted file mode 100755
index 0565465..0000000
--- a/examples/0301/MyAndroidTutorial/bin/jarlist.cache
+++ /dev/null
@@ -1,3 +0,0 @@
-# cache for current jar dependency. DO NOT EDIT.
-# format is
-# Encoding is UTF-8
diff --git a/examples/0301/MyAndroidTutorial/bin/res/crunch/drawable-hdpi/ic_launcher.png b/examples/0301/MyAndroidTutorial/bin/res/crunch/drawable-hdpi/ic_launcher.png
deleted file mode 100755
index bcfa058..0000000
Binary files a/examples/0301/MyAndroidTutorial/bin/res/crunch/drawable-hdpi/ic_launcher.png and /dev/null differ
diff --git a/examples/0301/MyAndroidTutorial/bin/res/crunch/drawable-mdpi/ic_launcher.png b/examples/0301/MyAndroidTutorial/bin/res/crunch/drawable-mdpi/ic_launcher.png
deleted file mode 100755
index 85848ff..0000000
Binary files a/examples/0301/MyAndroidTutorial/bin/res/crunch/drawable-mdpi/ic_launcher.png and /dev/null differ
diff --git a/examples/0301/MyAndroidTutorial/bin/res/crunch/drawable-xhdpi/ic_launcher.png b/examples/0301/MyAndroidTutorial/bin/res/crunch/drawable-xhdpi/ic_launcher.png
deleted file mode 100755
index 916901e..0000000
Binary files a/examples/0301/MyAndroidTutorial/bin/res/crunch/drawable-xhdpi/ic_launcher.png and /dev/null differ
diff --git a/examples/0301/MyAndroidTutorial/bin/res/crunch/drawable/alarm_icon.png b/examples/0301/MyAndroidTutorial/bin/res/crunch/drawable/alarm_icon.png
deleted file mode 100755
index ebeae27..0000000
Binary files a/examples/0301/MyAndroidTutorial/bin/res/crunch/drawable/alarm_icon.png and /dev/null differ
diff --git a/examples/0301/MyAndroidTutorial/bin/res/crunch/drawable/location_icon.png b/examples/0301/MyAndroidTutorial/bin/res/crunch/drawable/location_icon.png
deleted file mode 100755
index 6897a97..0000000
Binary files a/examples/0301/MyAndroidTutorial/bin/res/crunch/drawable/location_icon.png and /dev/null differ
diff --git a/examples/0301/MyAndroidTutorial/bin/res/crunch/drawable/record_sound_icon.png b/examples/0301/MyAndroidTutorial/bin/res/crunch/drawable/record_sound_icon.png
deleted file mode 100755
index 6fe2060..0000000
Binary files a/examples/0301/MyAndroidTutorial/bin/res/crunch/drawable/record_sound_icon.png and /dev/null differ
diff --git a/examples/0301/MyAndroidTutorial/bin/res/crunch/drawable/select_color_icon.png b/examples/0301/MyAndroidTutorial/bin/res/crunch/drawable/select_color_icon.png
deleted file mode 100755
index 4270ec5..0000000
Binary files a/examples/0301/MyAndroidTutorial/bin/res/crunch/drawable/select_color_icon.png and /dev/null differ
diff --git a/examples/0301/MyAndroidTutorial/bin/res/crunch/drawable/selected_icon.png b/examples/0301/MyAndroidTutorial/bin/res/crunch/drawable/selected_icon.png
deleted file mode 100755
index 982ddee..0000000
Binary files a/examples/0301/MyAndroidTutorial/bin/res/crunch/drawable/selected_icon.png and /dev/null differ
diff --git a/examples/0301/MyAndroidTutorial/bin/res/crunch/drawable/take_picture_icon.png b/examples/0301/MyAndroidTutorial/bin/res/crunch/drawable/take_picture_icon.png
deleted file mode 100755
index c812e2f..0000000
Binary files a/examples/0301/MyAndroidTutorial/bin/res/crunch/drawable/take_picture_icon.png and /dev/null differ
diff --git a/examples/0301/MyAndroidTutorial/bin/resources.ap_ b/examples/0301/MyAndroidTutorial/bin/resources.ap_
deleted file mode 100644
index 7cc2da9..0000000
Binary files a/examples/0301/MyAndroidTutorial/bin/resources.ap_ and /dev/null differ
diff --git a/examples/0301/MyAndroidTutorial/build.gradle b/examples/0301/MyAndroidTutorial/build.gradle
new file mode 100644
index 0000000..6356aab
--- /dev/null
+++ b/examples/0301/MyAndroidTutorial/build.gradle
@@ -0,0 +1,19 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+ repositories {
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:1.0.0'
+
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+}
+
+allprojects {
+ repositories {
+ jcenter()
+ }
+}
diff --git a/examples/0301/MyAndroidTutorial/gen/net/macdidi/myandroidtutorial/BuildConfig.java b/examples/0301/MyAndroidTutorial/gen/net/macdidi/myandroidtutorial/BuildConfig.java
deleted file mode 100755
index 5d44ea9..0000000
--- a/examples/0301/MyAndroidTutorial/gen/net/macdidi/myandroidtutorial/BuildConfig.java
+++ /dev/null
@@ -1,6 +0,0 @@
-/** Automatically generated file. DO NOT MODIFY */
-package net.macdidi.myandroidtutorial;
-
-public final class BuildConfig {
- public final static boolean DEBUG = true;
-}
\ No newline at end of file
diff --git a/examples/0301/MyAndroidTutorial/gen/net/macdidi/myandroidtutorial/R.java b/examples/0301/MyAndroidTutorial/gen/net/macdidi/myandroidtutorial/R.java
deleted file mode 100755
index 1f01c47..0000000
--- a/examples/0301/MyAndroidTutorial/gen/net/macdidi/myandroidtutorial/R.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/* AUTO-GENERATED FILE. DO NOT MODIFY.
- *
- * This class was automatically generated by the
- * aapt tool from the resource data it found. It
- * should not be modified by hand.
- */
-
-package net.macdidi.myandroidtutorial;
-
-public final class R {
- public static final class attr {
- }
- public static final class color {
- public static final int dark_text=0x7f040003;
- public static final int divider_color=0x7f040002;
- public static final int grey=0x7f040001;
- public static final int light_grey=0x7f040000;
- }
- public static final class dimen {
- public static final int default_margin=0x7f050001;
- public static final int default_padding=0x7f050000;
- public static final int title_txt_size=0x7f050002;
- }
- public static final class drawable {
- public static final int alarm_icon=0x7f020000;
- public static final int ic_launcher=0x7f020001;
- public static final int item_drawable=0x7f020002;
- public static final int location_icon=0x7f020003;
- public static final int record_sound_icon=0x7f020004;
- public static final int retangle_drawable=0x7f020005;
- public static final int select_color_icon=0x7f020006;
- public static final int selected_icon=0x7f020007;
- public static final int take_picture_icon=0x7f020008;
- }
- public static final class id {
- public static final int add_item=0x7f090010;
- public static final int cancel_item=0x7f090008;
- public static final int color_gallery=0x7f090000;
- public static final int content_text=0x7f090002;
- public static final int date_text=0x7f09000e;
- public static final int delete_item=0x7f090012;
- public static final int facebook_item=0x7f090015;
- public static final int googleplus_item=0x7f090014;
- public static final int item_list=0x7f09000a;
- public static final int ok_teim=0x7f090009;
- public static final int record_sound=0x7f090004;
- public static final int revert_item=0x7f090011;
- public static final int search_item=0x7f09000f;
- public static final int select_color=0x7f090007;
- public static final int selected_item=0x7f09000d;
- public static final int set_alarm=0x7f090006;
- public static final int set_location=0x7f090005;
- public static final int share_item=0x7f090013;
- public static final int show_app_name=0x7f09000b;
- public static final int take_picture=0x7f090003;
- public static final int title_text=0x7f090001;
- public static final int type_color=0x7f09000c;
- }
- public static final class layout {
- public static final int activity_about=0x7f030000;
- public static final int activity_color=0x7f030001;
- public static final int activity_item=0x7f030002;
- public static final int activity_main=0x7f030003;
- public static final int single_item=0x7f030004;
- }
- public static final class menu {
- public static final int main_menu=0x7f080000;
- }
- public static final class string {
- public static final int about=0x7f060007;
- public static final int app_name=0x7f060000;
- public static final int content=0x7f060005;
- public static final int delete=0x7f060009;
- public static final int delete_item=0x7f06000a;
- public static final int enter_content=0x7f060006;
- public static final int enter_title=0x7f060004;
- public static final int hello_world=0x7f06000b;
- public static final int title=0x7f060003;
- public static final int title_activity_color=0x7f060002;
- public static final int title_activity_main=0x7f060001;
- public static final int version=0x7f060008;
- }
- public static final class style {
- /**
- Base application theme, dependent on API level. This theme is replaced
- by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
-
-
- Theme customizations available in newer API levels can go in
- res/values-vXX/styles.xml, while customizations related to
- backward-compatibility can go here.
-
-
- Base application theme for API 11+. This theme completely replaces
- AppBaseTheme from res/values/styles.xml on API 11+ devices.
-
- API 11 theme customizations can go here.
-
- Base application theme for API 14+. This theme completely replaces
- AppBaseTheme from BOTH res/values/styles.xml and
- res/values-v11/styles.xml on API 14+ devices.
-
- API 14 theme customizations can go here.
- */
- public static final int AppBaseTheme=0x7f070000;
- /** Application theme.
- All customizations that are NOT specific to a particular API-level can go here.
- */
- public static final int AppTheme=0x7f070001;
- }
-}
diff --git a/examples/0301/MyAndroidTutorial/gradle.properties b/examples/0301/MyAndroidTutorial/gradle.properties
new file mode 100644
index 0000000..1d3591c
--- /dev/null
+++ b/examples/0301/MyAndroidTutorial/gradle.properties
@@ -0,0 +1,18 @@
+# Project-wide Gradle settings.
+
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+# Default value: -Xmx10248m -XX:MaxPermSize=256m
+# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
+
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
\ No newline at end of file
diff --git a/examples/0301/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.jar b/examples/0301/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
Binary files /dev/null and b/examples/0301/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/examples/0301/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.properties b/examples/0301/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..0c71e76
--- /dev/null
+++ b/examples/0301/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
diff --git a/examples/0301/MyAndroidTutorial/gradlew b/examples/0301/MyAndroidTutorial/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/examples/0301/MyAndroidTutorial/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/examples/0301/MyAndroidTutorial/gradlew.bat b/examples/0301/MyAndroidTutorial/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/examples/0301/MyAndroidTutorial/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/examples/0301/MyAndroidTutorial/libs/android-support-v4.jar b/examples/0301/MyAndroidTutorial/libs/android-support-v4.jar
deleted file mode 100755
index 187bdf4..0000000
Binary files a/examples/0301/MyAndroidTutorial/libs/android-support-v4.jar and /dev/null differ
diff --git a/examples/0301/MyAndroidTutorial/proguard-project.txt b/examples/0301/MyAndroidTutorial/proguard-project.txt
deleted file mode 100755
index f2fe155..0000000
--- a/examples/0301/MyAndroidTutorial/proguard-project.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-# To enable ProGuard in your project, edit project.properties
-# to define the proguard.config property as described in that file.
-#
-# Add project specific ProGuard rules here.
-# By default, the flags in this file are appended to flags specified
-# in ${sdk.dir}/tools/proguard/proguard-android.txt
-# You can edit the include path and order by changing the ProGuard
-# include property in project.properties.
-#
-# For more details, see
-# http://developer.android.com/guide/developing/tools/proguard.html
-
-# Add any project specific keep options here:
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-# public *;
-#}
diff --git a/examples/0301/MyAndroidTutorial/project.properties b/examples/0301/MyAndroidTutorial/project.properties
deleted file mode 100755
index 4ab1256..0000000
--- a/examples/0301/MyAndroidTutorial/project.properties
+++ /dev/null
@@ -1,14 +0,0 @@
-# This file is automatically generated by Android Tools.
-# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
-#
-# This file must be checked in Version Control Systems.
-#
-# To customize properties used by the Ant build system edit
-# "ant.properties", and override values to adapt the script to your
-# project structure.
-#
-# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
-#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
-
-# Project target.
-target=android-19
diff --git a/examples/0301/MyAndroidTutorial/res/drawable/item_drawable.xml b/examples/0301/MyAndroidTutorial/res/drawable/item_drawable.xml
deleted file mode 100755
index ecc4011..0000000
--- a/examples/0301/MyAndroidTutorial/res/drawable/item_drawable.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/examples/0301/MyAndroidTutorial/res/drawable/retangle_drawable.xml b/examples/0301/MyAndroidTutorial/res/drawable/retangle_drawable.xml
deleted file mode 100755
index e195342..0000000
--- a/examples/0301/MyAndroidTutorial/res/drawable/retangle_drawable.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/examples/0301/MyAndroidTutorial/res/layout/activity_about.xml b/examples/0301/MyAndroidTutorial/res/layout/activity_about.xml
deleted file mode 100755
index 738fe98..0000000
--- a/examples/0301/MyAndroidTutorial/res/layout/activity_about.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/examples/0301/MyAndroidTutorial/res/layout/activity_color.xml b/examples/0301/MyAndroidTutorial/res/layout/activity_color.xml
deleted file mode 100755
index 693a9d4..0000000
--- a/examples/0301/MyAndroidTutorial/res/layout/activity_color.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
-
-
diff --git a/examples/0301/MyAndroidTutorial/res/layout/activity_item.xml b/examples/0301/MyAndroidTutorial/res/layout/activity_item.xml
deleted file mode 100755
index a12c44c..0000000
--- a/examples/0301/MyAndroidTutorial/res/layout/activity_item.xml
+++ /dev/null
@@ -1,94 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/examples/0301/MyAndroidTutorial/res/layout/activity_main.xml b/examples/0301/MyAndroidTutorial/res/layout/activity_main.xml
deleted file mode 100755
index 418c34b..0000000
--- a/examples/0301/MyAndroidTutorial/res/layout/activity_main.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
diff --git a/examples/0301/MyAndroidTutorial/res/layout/single_item.xml b/examples/0301/MyAndroidTutorial/res/layout/single_item.xml
deleted file mode 100755
index c3b579c..0000000
--- a/examples/0301/MyAndroidTutorial/res/layout/single_item.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/examples/0301/MyAndroidTutorial/res/menu/main_menu.xml b/examples/0301/MyAndroidTutorial/res/menu/main_menu.xml
deleted file mode 100755
index 030587f..0000000
--- a/examples/0301/MyAndroidTutorial/res/menu/main_menu.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/examples/0301/MyAndroidTutorial/res/values-en/strings.xml b/examples/0301/MyAndroidTutorial/res/values-en/strings.xml
deleted file mode 100755
index 34f4fed..0000000
--- a/examples/0301/MyAndroidTutorial/res/values-en/strings.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
- MyAndroidTutorial
- MainActivity
- Hello world!
-
- Title
- Enter title
- Content
- Enter content
-
-
diff --git a/examples/0301/MyAndroidTutorial/res/values-v11/styles.xml b/examples/0301/MyAndroidTutorial/res/values-v11/styles.xml
deleted file mode 100755
index 3c02242..0000000
--- a/examples/0301/MyAndroidTutorial/res/values-v11/styles.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
diff --git a/examples/0301/MyAndroidTutorial/res/values-v14/styles.xml b/examples/0301/MyAndroidTutorial/res/values-v14/styles.xml
deleted file mode 100755
index a91fd03..0000000
--- a/examples/0301/MyAndroidTutorial/res/values-v14/styles.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
diff --git a/examples/0301/MyAndroidTutorial/res/values/colors.xml b/examples/0301/MyAndroidTutorial/res/values/colors.xml
deleted file mode 100755
index c63ec2d..0000000
--- a/examples/0301/MyAndroidTutorial/res/values/colors.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
- #CCCCCC
- #AAAAAA
- #DDCCCCCC
- #111111
-
diff --git a/examples/0301/MyAndroidTutorial/res/values/dimens.xml b/examples/0301/MyAndroidTutorial/res/values/dimens.xml
deleted file mode 100755
index fb03071..0000000
--- a/examples/0301/MyAndroidTutorial/res/values/dimens.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
- 6dp
- 2dp
- 24sp
-
diff --git a/examples/0301/MyAndroidTutorial/res/values/strings.xml b/examples/0301/MyAndroidTutorial/res/values/strings.xml
deleted file mode 100755
index 9bce28c..0000000
--- a/examples/0301/MyAndroidTutorial/res/values/strings.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
- MyAndroidTutorial
- MyAndroidTutorial
- 設定顏色
- 標題
- 輸入標題
- 內容
- 輸入內容
- 這是Android Tutorial應用程式
- 版本:AndroidTutorial_0.2.4
-
- 刪除
- 確定要刪除 %1$d 個項目?
-
-
diff --git a/examples/0301/MyAndroidTutorial/res/values/styles.xml b/examples/0301/MyAndroidTutorial/res/values/styles.xml
deleted file mode 100755
index 6ce89c7..0000000
--- a/examples/0301/MyAndroidTutorial/res/values/styles.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
-
-
-
-
-
-
diff --git a/examples/0301/MyAndroidTutorial/settings.gradle b/examples/0301/MyAndroidTutorial/settings.gradle
new file mode 100644
index 0000000..e7b4def
--- /dev/null
+++ b/examples/0301/MyAndroidTutorial/settings.gradle
@@ -0,0 +1 @@
+include ':app'
diff --git a/examples/0301/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/AboutActivity.java b/examples/0301/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/AboutActivity.java
deleted file mode 100755
index 111efc5..0000000
--- a/examples/0301/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/AboutActivity.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package net.macdidi.myandroidtutorial;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.view.View;
-import android.view.Window;
-
-public class AboutActivity extends Activity {
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- // 取消元件的應用程式標題
- requestWindowFeature(Window.FEATURE_NO_TITLE);
- setContentView(R.layout.activity_about);
- }
-
- // 結束按鈕
- public void clickOk(View view) {
- // 呼叫這個方法結束Activity元件
- finish();
- }
-
-}
diff --git a/examples/0301/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/ColorActivity.java b/examples/0301/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/ColorActivity.java
deleted file mode 100755
index 56b112a..0000000
--- a/examples/0301/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/ColorActivity.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package net.macdidi.myandroidtutorial;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.os.Bundle;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.widget.Button;
-import android.widget.LinearLayout;
-
-public class ColorActivity extends Activity {
-
- private LinearLayout color_gallery;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_color);
-
- processViews();
-
- ColorListener listener = new ColorListener();
-
- for (Colors c : Colors.values()) {
- Button button = new Button(this);
- button.setId(c.parseColor());
- LinearLayout.LayoutParams layout =
- new LinearLayout.LayoutParams(128, 128);
- layout.setMargins(6, 6, 6, 6);
- button.setLayoutParams(layout);
- button.setBackgroundColor(c.parseColor());
-
- button.setOnClickListener(listener);
-
- color_gallery.addView(button);
- }
- }
-
- private void processViews() {
- color_gallery = (LinearLayout) findViewById(R.id.color_gallery);
- }
-
- private class ColorListener implements OnClickListener {
-
- @Override
- public void onClick(View view) {
- Intent result = getIntent();
- result.putExtra("colorId", view.getId());
- setResult(Activity.RESULT_OK, result);
- finish();
- }
-
- }
-
-}
diff --git a/examples/0301/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/Colors.java b/examples/0301/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/Colors.java
deleted file mode 100755
index a3eb9d4..0000000
--- a/examples/0301/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/Colors.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package net.macdidi.myandroidtutorial;
-
-import android.graphics.Color;
-
-public enum Colors {
-
- LIGHTGREY("#D3D3D3"), BLUE("#33B5E5"), PURPLE("#AA66CC"),
- GREEN("#99CC00"), ORANGE("#FFBB33"), RED("#FF4444");
-
- private String code;
-
- private Colors(String code) {
- this.code = code;
- }
-
- public String getCode() {
- return code;
- }
-
- public int parseColor() {
- return Color.parseColor(code);
- }
-
-}
diff --git a/examples/0301/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/Item.java b/examples/0301/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/Item.java
deleted file mode 100755
index d2df2a9..0000000
--- a/examples/0301/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/Item.java
+++ /dev/null
@@ -1,135 +0,0 @@
-package net.macdidi.myandroidtutorial;
-
-import java.util.Date;
-import java.util.Locale;
-
-public class Item implements java.io.Serializable {
-
- // 編號、日期時間、顏色、標題、內容、檔案名稱、經緯度、修改、已選擇
- private long id;
- private long datetime;
- private Colors color;
- private String title;
- private String content;
- private String fileName;
- private double latitude;
- private double longitude;
- private long lastModify;
- private boolean selected;
-
- public Item() {
- title = "";
- content = "";
- color = Colors.LIGHTGREY;
- }
-
- public Item(long id, long datetime, Colors color, String title,
- String content, String fileName, double latitude, double longitude,
- long lastModify) {
- this.id = id;
- this.datetime = datetime;
- this.color = color;
- this.title = title;
- this.content = content;
- this.fileName = fileName;
- this.latitude = latitude;
- this.longitude = longitude;
- this.lastModify = lastModify;
- }
-
- public long getId() {
- return id;
- }
-
- public void setId(long id) {
- this.id = id;
- }
-
- public long getDatetime() {
- return datetime;
- }
-
- // 裝置區域的日期時間
- public String getLocaleDatetime() {
- return String.format(Locale.getDefault(), "%tF % {
-
- // 畫面資源編號
- private int resource;
- // 包裝的記事資料
- private List- items;
-
- public ItemAdapter(Context context, int resource, List
- items) {
- super(context, resource, items);
- this.resource = resource;
- this.items = items;
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- LinearLayout itemView;
- // 讀取目前位置的記事物件
- final Item item = getItem(position);
-
- if (convertView == null) {
- // 建立項目畫面元件
- itemView = new LinearLayout(getContext());
- String inflater = Context.LAYOUT_INFLATER_SERVICE;
- LayoutInflater li = (LayoutInflater)
- getContext().getSystemService(inflater);
- li.inflate(resource, itemView, true);
- }
- else {
- itemView = (LinearLayout) convertView;
- }
-
- // 讀取記事顏色、已選擇、標題與日期時間元件
- RelativeLayout typeColor = (RelativeLayout) itemView.findViewById(R.id.type_color);
- ImageView selectedItem = (ImageView) itemView.findViewById(R.id.selected_item);
- TextView titleView = (TextView) itemView.findViewById(R.id.title_text);
- TextView dateView = (TextView) itemView.findViewById(R.id.date_text);
-
- // 設定記事顏色
- GradientDrawable background = (GradientDrawable)typeColor.getBackground();
- background.setColor(item.getColor().parseColor());
-
- // 設定標題與日期時間
- titleView.setText(item.getTitle());
- dateView.setText(item.getLocaleDatetime());
-
- // 設定是否已選擇
- selectedItem.setVisibility(item.isSelected() ? View.VISIBLE : View.INVISIBLE);
-
- return itemView;
- }
-
- // 設定指定編號的記事資料
- public void set(int index, Item item) {
- if (index >= 0 && index < items.size()) {
- items.set(index, item);
- notifyDataSetChanged();
- }
- }
-
- // 讀取指定編號的記事資料
- public Item get(int index) {
- return items.get(index);
- }
-
-}
diff --git a/examples/0301/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/MainActivity.java b/examples/0301/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/MainActivity.java
deleted file mode 100755
index 8779e36..0000000
--- a/examples/0301/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/MainActivity.java
+++ /dev/null
@@ -1,283 +0,0 @@
-package net.macdidi.myandroidtutorial;
-
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.os.Bundle;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.View.OnLongClickListener;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemClickListener;
-import android.widget.AdapterView.OnItemLongClickListener;
-import android.widget.ListView;
-import android.widget.TextView;
-
-public class MainActivity extends Activity {
-
- private ListView item_list;
- private TextView show_app_name;
-
- // ListView使用的自定Adapter物件
- private ItemAdapter itemAdapter;
- // 儲存所有記事本的List物件
- private List
- items;
-
- // 選單項目物件
- private MenuItem add_item, search_item, revert_item, share_item, delete_item;
-
- // 已選擇項目數量
- private int selectedCount = 0;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
-
- processViews();
- processControllers();
-
- // 加入範例資料
- items = new ArrayList
- ();
-
- items.add(new Item(1, new Date().getTime(), Colors.RED, "關於Android Tutorial的事情.", "Hello content", "", 0, 0, 0));
- items.add(new Item(2, new Date().getTime(), Colors.BLUE, "一隻非常可愛的小狗狗!", "她的名字叫「大熱狗」,又叫\n作「奶嘴」,是一隻非常可愛\n的小狗。", "", 0, 0, 0));
- items.add(new Item(3, new Date().getTime(), Colors.GREEN, "一首非常好聽的音樂!", "Hello content", "", 0, 0, 0));
-
- // 建立自定Adapter物件
- itemAdapter = new ItemAdapter(this, R.layout.single_item, items);
- item_list.setAdapter(itemAdapter);
- }
-
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- // 如果被啟動的Activity元件傳回確定的結果
- if (resultCode == Activity.RESULT_OK) {
- // 讀取記事物件
- Item item = (Item) data.getExtras().getSerializable(
- "net.macdidi.myandroidtutorial.Item");
-
- // 如果是新增記事
- if (requestCode == 0) {
- // 設定記事物件的編號與日期時間
- item.setId(items.size() + 1);
-
- // 加入新增的記事物件
- items.add(item);
-
- // 通知資料改變
- itemAdapter.notifyDataSetChanged();
- }
- // 如果是修改記事
- else if (requestCode == 1) {
- // 讀取記事編號
- int position = data.getIntExtra("position", -1);
-
- if (position != -1) {
- // 設定修改的記事物件
- items.set(position, item);
- itemAdapter.notifyDataSetChanged();
- }
- }
- }
- }
-
- private void processViews() {
- item_list = (ListView)findViewById(R.id.item_list);
- show_app_name = (TextView) findViewById(R.id.show_app_name);
- }
-
- private void processControllers() {
-
- // 建立選單項目點擊監聽物件
- OnItemClickListener itemListener = new OnItemClickListener() {
- @Override
- public void onItemClick(AdapterView> parent, View view,
- int position, long id) {
- // 讀取選擇的記事物件
- Item item = itemAdapter.getItem(position);
-
- // 如果已經有勾選的項目
- if (selectedCount > 0) {
- // 處理是否顯示已選擇項目
- processMenu(item);
- // 重新設定記事項目
- itemAdapter.set(position, item);
- }
- else {
- Intent intent = new Intent(
- "net.macdidi.myandroidtutorial.EDIT_ITEM");
-
- // 設定記事編號與記事物件
- intent.putExtra("position", position);
- intent.putExtra("net.macdidi.myandroidtutorial.Item", item);
-
- startActivityForResult(intent, 1);
- }
- }
- };
-
- // 註冊選單項目點擊監聽物件
- item_list.setOnItemClickListener(itemListener);
-
- // 建立記事項目長按監聽物件
- OnItemLongClickListener itemLongListener = new OnItemLongClickListener() {
- @Override
- public boolean onItemLongClick(AdapterView> parent, View view,
- int position, long id) {
- // 讀取選擇的記事物件
- Item item = itemAdapter.getItem(position);
- // 處理是否顯示已選擇項目
- processMenu(item);
- // 重新設定記事項目
- itemAdapter.set(position, item);
- return true;
- }
- };
-
- // 註冊選單項目長按監聽物件
- item_list.setOnItemLongClickListener(itemLongListener);
-
- // 建立長按監聽物件
- OnLongClickListener listener = new OnLongClickListener() {
-
- @Override
- public boolean onLongClick(View view) {
- AlertDialog.Builder dialog =
- new AlertDialog.Builder(MainActivity.this);
- dialog.setTitle(R.string.app_name)
- .setMessage(R.string.about)
- .show();
- return false;
- }
-
- };
-
- // 註冊長按監聽物件
- show_app_name.setOnLongClickListener(listener);
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- MenuInflater menuInflater = getMenuInflater();
- menuInflater.inflate(R.menu.main_menu, menu);
-
- // 取得選單項目物件
- add_item = menu.findItem(R.id.add_item);
- search_item = menu.findItem(R.id.search_item);
- revert_item = menu.findItem(R.id.revert_item);
- share_item = menu.findItem(R.id.share_item);
- delete_item = menu.findItem(R.id.delete_item);
-
- // 設定選單項目
- processMenu(null);
-
- return true;
- }
-
- public void clickMenuItem(MenuItem item) {
- // 使用參數取得使用者選擇的選單項目元件編號
- int itemId = item.getItemId();
-
- switch (itemId) {
- case R.id.search_item:
- break;
- case R.id.add_item:
- Intent intent = new Intent("net.macdidi.myandroidtutorial.ADD_ITEM");
- startActivityForResult(intent, 0);
- break;
- // 取消所有已勾選的項目
- case R.id.revert_item:
- for (int i = 0; i < itemAdapter.getCount(); i++) {
- Item ri = itemAdapter.getItem(i);
-
- if (ri.isSelected()) {
- ri.setSelected(false);
- itemAdapter.set(i, ri);
- }
- }
-
- selectedCount = 0;
- processMenu(null);
-
- break;
- // 刪除
- case R.id.delete_item:
- // 沒有選擇
- if (selectedCount == 0) {
- break;
- }
-
- // 建立與顯示詢問是否刪除的對話框
- AlertDialog.Builder d = new AlertDialog.Builder(this);
- String message = getString(R.string.delete_item);
- d.setTitle(R.string.delete)
- .setMessage(String.format(message, selectedCount));
- d.setPositiveButton(android.R.string.yes,
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- // 刪除所有已勾選的項目
- int index = itemAdapter.getCount() - 1;
-
- while (index > -1) {
- Item item = itemAdapter.get(index);
-
- if (item.isSelected()) {
- itemAdapter.remove(item);
- }
-
- index--;
- }
-
- // 通知資料改變
- itemAdapter.notifyDataSetChanged();
- }
- });
- d.setNegativeButton(android.R.string.no, null);
- d.show();
-
- break;
- case R.id.googleplus_item:
- break;
- case R.id.facebook_item:
- break;
- }
- }
-
- // 處理是否顯示已選擇項目
- private void processMenu(Item item) {
- // 如果需要設定記事項目
- if (item != null) {
- // 設定已勾選的狀態
- item.setSelected(!item.isSelected());
-
- // 計算已勾選數量
- if (item.isSelected()) {
- selectedCount++;
- }
- else {
- selectedCount--;
- }
- }
-
- // 根據選擇的狀況,設定是否顯示選單項目
- add_item.setVisible(selectedCount == 0);
- search_item.setVisible(selectedCount == 0);
- revert_item.setVisible(selectedCount > 0);
- share_item.setVisible(selectedCount > 0);
- delete_item.setVisible(selectedCount > 0);
- }
-
- public void aboutApp(View view) {
- Intent intent = new Intent(this, AboutActivity.class);
- startActivity(intent);
- }
-}
diff --git a/examples/0302/MyAndroidTutorial/.classpath b/examples/0302/MyAndroidTutorial/.classpath
deleted file mode 100755
index 7bc01d9..0000000
--- a/examples/0302/MyAndroidTutorial/.classpath
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
-
-
-
-
diff --git a/examples/0302/MyAndroidTutorial/.gitignore b/examples/0302/MyAndroidTutorial/.gitignore
new file mode 100644
index 0000000..afbdab3
--- /dev/null
+++ b/examples/0302/MyAndroidTutorial/.gitignore
@@ -0,0 +1,6 @@
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
diff --git a/examples/0302/MyAndroidTutorial/.idea/.name b/examples/0302/MyAndroidTutorial/.idea/.name
new file mode 100644
index 0000000..5bb7a85
--- /dev/null
+++ b/examples/0302/MyAndroidTutorial/.idea/.name
@@ -0,0 +1 @@
+MyAndroidTutorial
\ No newline at end of file
diff --git a/examples/0302/MyAndroidTutorial/.idea/compiler.xml b/examples/0302/MyAndroidTutorial/.idea/compiler.xml
new file mode 100644
index 0000000..217af47
--- /dev/null
+++ b/examples/0302/MyAndroidTutorial/.idea/compiler.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0302/MyAndroidTutorial/.idea/copyright/profiles_settings.xml b/examples/0302/MyAndroidTutorial/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..e7bedf3
--- /dev/null
+++ b/examples/0302/MyAndroidTutorial/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/examples/0302/MyAndroidTutorial/.idea/encodings.xml b/examples/0302/MyAndroidTutorial/.idea/encodings.xml
new file mode 100644
index 0000000..e206d70
--- /dev/null
+++ b/examples/0302/MyAndroidTutorial/.idea/encodings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/examples/0302/MyAndroidTutorial/.idea/gradle.xml b/examples/0302/MyAndroidTutorial/.idea/gradle.xml
new file mode 100644
index 0000000..fe865d3
--- /dev/null
+++ b/examples/0302/MyAndroidTutorial/.idea/gradle.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0302/MyAndroidTutorial/.idea/misc.xml b/examples/0302/MyAndroidTutorial/.idea/misc.xml
new file mode 100644
index 0000000..9076de5
--- /dev/null
+++ b/examples/0302/MyAndroidTutorial/.idea/misc.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0302/MyAndroidTutorial/.idea/modules.xml b/examples/0302/MyAndroidTutorial/.idea/modules.xml
new file mode 100644
index 0000000..327df67
--- /dev/null
+++ b/examples/0302/MyAndroidTutorial/.idea/modules.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0302/MyAndroidTutorial/.idea/scopes/scope_settings.xml b/examples/0302/MyAndroidTutorial/.idea/scopes/scope_settings.xml
new file mode 100644
index 0000000..922003b
--- /dev/null
+++ b/examples/0302/MyAndroidTutorial/.idea/scopes/scope_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0302/MyAndroidTutorial/.idea/vcs.xml b/examples/0302/MyAndroidTutorial/.idea/vcs.xml
new file mode 100644
index 0000000..def6a6a
--- /dev/null
+++ b/examples/0302/MyAndroidTutorial/.idea/vcs.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/examples/0302/MyAndroidTutorial/.project b/examples/0302/MyAndroidTutorial/.project
deleted file mode 100755
index b1de407..0000000
--- a/examples/0302/MyAndroidTutorial/.project
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
- MyAndroidTutorial
-
-
-
-
-
- com.android.ide.eclipse.adt.ResourceManagerBuilder
-
-
-
-
- com.android.ide.eclipse.adt.PreCompilerBuilder
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- com.android.ide.eclipse.adt.ApkBuilder
-
-
-
-
-
- com.android.ide.eclipse.adt.AndroidNature
- org.eclipse.jdt.core.javanature
-
-
diff --git a/examples/0302/MyAndroidTutorial/.settings/org.eclipse.core.resources.prefs b/examples/0302/MyAndroidTutorial/.settings/org.eclipse.core.resources.prefs
deleted file mode 100644
index 99f26c0..0000000
--- a/examples/0302/MyAndroidTutorial/.settings/org.eclipse.core.resources.prefs
+++ /dev/null
@@ -1,2 +0,0 @@
-eclipse.preferences.version=1
-encoding/=UTF-8
diff --git a/examples/0302/MyAndroidTutorial/AndroidManifest.xml b/examples/0302/MyAndroidTutorial/AndroidManifest.xml
deleted file mode 100755
index a31ecc2..0000000
--- a/examples/0302/MyAndroidTutorial/AndroidManifest.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/examples/0302/MyAndroidTutorial/MyAndroidTutorial.iml b/examples/0302/MyAndroidTutorial/MyAndroidTutorial.iml
new file mode 100644
index 0000000..2a02201
--- /dev/null
+++ b/examples/0302/MyAndroidTutorial/MyAndroidTutorial.iml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0302/MyAndroidTutorial/app/.gitignore b/examples/0302/MyAndroidTutorial/app/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/examples/0302/MyAndroidTutorial/app/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/examples/0302/MyAndroidTutorial/app/app.iml b/examples/0302/MyAndroidTutorial/app/app.iml
new file mode 100644
index 0000000..c6c55c4
--- /dev/null
+++ b/examples/0302/MyAndroidTutorial/app/app.iml
@@ -0,0 +1,91 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0302/MyAndroidTutorial/app/build.gradle b/examples/0302/MyAndroidTutorial/app/build.gradle
new file mode 100644
index 0000000..b09f064
--- /dev/null
+++ b/examples/0302/MyAndroidTutorial/app/build.gradle
@@ -0,0 +1,25 @@
+apply plugin: 'com.android.application'
+
+android {
+ compileSdkVersion 21
+ buildToolsVersion "21.1.2"
+
+ defaultConfig {
+ applicationId "net.macdidi.myandroidtutorial"
+ minSdkVersion 15
+ targetSdkVersion 21
+ versionCode 1
+ versionName "1.0"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ compile fileTree(dir: 'libs', include: ['*.jar'])
+ compile 'com.android.support:appcompat-v7:21.0.3'
+}
diff --git a/examples/0302/MyAndroidTutorial/app/proguard-rules.pro b/examples/0302/MyAndroidTutorial/app/proguard-rules.pro
new file mode 100644
index 0000000..b5fa7ec
--- /dev/null
+++ b/examples/0302/MyAndroidTutorial/app/proguard-rules.pro
@@ -0,0 +1,17 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /Users/macdidi5/Library/Android/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
diff --git a/examples/0302/MyAndroidTutorial/app/src/androidTest/java/net/macdidi/myandroidtutorial/ApplicationTest.java b/examples/0302/MyAndroidTutorial/app/src/androidTest/java/net/macdidi/myandroidtutorial/ApplicationTest.java
new file mode 100644
index 0000000..2cb214e
--- /dev/null
+++ b/examples/0302/MyAndroidTutorial/app/src/androidTest/java/net/macdidi/myandroidtutorial/ApplicationTest.java
@@ -0,0 +1,13 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Application;
+import android.test.ApplicationTestCase;
+
+/**
+ * Testing Fundamentals
+ */
+public class ApplicationTest extends ApplicationTestCase {
+ public ApplicationTest() {
+ super(Application.class);
+ }
+}
\ No newline at end of file
diff --git a/examples/0302/MyAndroidTutorial/app/src/main/AndroidManifest.xml b/examples/0302/MyAndroidTutorial/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..3181c4f
--- /dev/null
+++ b/examples/0302/MyAndroidTutorial/app/src/main/AndroidManifest.xml
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0302/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/AboutActivity.java b/examples/0302/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/AboutActivity.java
new file mode 100644
index 0000000..42dddeb
--- /dev/null
+++ b/examples/0302/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/AboutActivity.java
@@ -0,0 +1,24 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.view.Window;
+
+public class AboutActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ // 取消元件的應用程式標題
+ requestWindowFeature(Window.FEATURE_NO_TITLE);
+ setContentView(R.layout.activity_about);
+ }
+
+ // 結束按鈕
+ public void clickOk(View view) {
+ // 呼叫這個方法結束Activity元件
+ finish();
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0302/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ColorActivity.java b/examples/0302/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ColorActivity.java
new file mode 100644
index 0000000..182cd55
--- /dev/null
+++ b/examples/0302/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ColorActivity.java
@@ -0,0 +1,75 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.LinearLayout;
+
+public class ColorActivity extends Activity {
+
+ private LinearLayout color_gallery;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_color);
+
+ processViews();
+
+ ColorListener listener = new ColorListener();
+
+ for (Colors c : Colors.values()) {
+ Button button = new Button(this);
+ button.setId(c.parseColor());
+ LinearLayout.LayoutParams layout =
+ new LinearLayout.LayoutParams(128, 128);
+ layout.setMargins(6, 6, 6, 6);
+ button.setLayoutParams(layout);
+ button.setBackgroundColor(c.parseColor());
+
+ button.setOnClickListener(listener);
+
+ color_gallery.addView(button);
+ }
+ }
+
+ private void processViews() {
+ color_gallery = (LinearLayout) findViewById(R.id.color_gallery);
+ }
+
+ private class ColorListener implements OnClickListener {
+
+ @Override
+ public void onClick(View view) {
+ String action = ColorActivity.this.getIntent().getAction();
+
+ // 經由設定元件啟動
+ if (action != null &&
+ action.equals("net.macdidi.myandroidtutorial.CHOOSE_COLOR")) {
+ // 建立SharedPreferences物件
+ SharedPreferences.Editor editor =
+ PreferenceManager.getDefaultSharedPreferences(
+ ColorActivity.this).edit();
+ // 儲存預設顏色
+ editor.putInt("DEFAULT_COLOR", view.getId());
+ // 寫入設定值
+ editor.commit();
+ finish();
+ }
+ // 經由新增或修改記事的元件啟動
+ else {
+ Intent result = getIntent();
+ result.putExtra("colorId", view.getId());
+ setResult(Activity.RESULT_OK, result);
+ finish();
+ }
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0302/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Colors.java b/examples/0302/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Colors.java
new file mode 100644
index 0000000..1462149
--- /dev/null
+++ b/examples/0302/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Colors.java
@@ -0,0 +1,24 @@
+package net.macdidi.myandroidtutorial;
+
+import android.graphics.Color;
+
+public enum Colors {
+
+ LIGHTGREY("#D3D3D3"), BLUE("#33B5E5"), PURPLE("#AA66CC"),
+ GREEN("#99CC00"), ORANGE("#FFBB33"), RED("#FF4444");
+
+ private String code;
+
+ private Colors(String code) {
+ this.code = code;
+ }
+
+ public String getCode() {
+ return code;
+ }
+
+ public int parseColor() {
+ return Color.parseColor(code);
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0302/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Item.java b/examples/0302/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Item.java
new file mode 100644
index 0000000..b015021
--- /dev/null
+++ b/examples/0302/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Item.java
@@ -0,0 +1,135 @@
+package net.macdidi.myandroidtutorial;
+
+import java.util.Date;
+import java.util.Locale;
+
+public class Item implements java.io.Serializable {
+
+ // 編號、日期時間、顏色、標題、內容、檔案名稱、經緯度、修改、已選擇
+ private long id;
+ private long datetime;
+ private Colors color;
+ private String title;
+ private String content;
+ private String fileName;
+ private double latitude;
+ private double longitude;
+ private long lastModify;
+ private boolean selected;
+
+ public Item() {
+ title = "";
+ content = "";
+ color = Colors.LIGHTGREY;
+ }
+
+ public Item(long id, long datetime, Colors color, String title,
+ String content, String fileName, double latitude, double longitude,
+ long lastModify) {
+ this.id = id;
+ this.datetime = datetime;
+ this.color = color;
+ this.title = title;
+ this.content = content;
+ this.fileName = fileName;
+ this.latitude = latitude;
+ this.longitude = longitude;
+ this.lastModify = lastModify;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public long getDatetime() {
+ return datetime;
+ }
+
+ // 裝置區域的日期時間
+ public String getLocaleDatetime() {
+ return String.format(Locale.getDefault(), "%tF % {
+
+ // 畫面資源編號
+ private int resource;
+ // 包裝的記事資料
+ private List- items;
+
+ public ItemAdapter(Context context, int resource, List
- items) {
+ super(context, resource, items);
+ this.resource = resource;
+ this.items = items;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ LinearLayout itemView;
+ // 讀取目前位置的記事物件
+ final Item item = getItem(position);
+
+ if (convertView == null) {
+ // 建立項目畫面元件
+ itemView = new LinearLayout(getContext());
+ String inflater = Context.LAYOUT_INFLATER_SERVICE;
+ LayoutInflater li = (LayoutInflater)
+ getContext().getSystemService(inflater);
+ li.inflate(resource, itemView, true);
+ }
+ else {
+ itemView = (LinearLayout) convertView;
+ }
+
+ // 讀取記事顏色、已選擇、標題與日期時間元件
+ RelativeLayout typeColor = (RelativeLayout) itemView.findViewById(R.id.type_color);
+ ImageView selectedItem = (ImageView) itemView.findViewById(R.id.selected_item);
+ TextView titleView = (TextView) itemView.findViewById(R.id.title_text);
+ TextView dateView = (TextView) itemView.findViewById(R.id.date_text);
+
+ // 設定記事顏色
+ GradientDrawable background = (GradientDrawable)typeColor.getBackground();
+ background.setColor(item.getColor().parseColor());
+
+ // 設定標題與日期時間
+ titleView.setText(item.getTitle());
+ dateView.setText(item.getLocaleDatetime());
+
+ // 設定是否已選擇
+ selectedItem.setVisibility(item.isSelected() ? View.VISIBLE : View.INVISIBLE);
+
+ return itemView;
+ }
+
+ // 設定指定編號的記事資料
+ public void set(int index, Item item) {
+ if (index >= 0 && index < items.size()) {
+ items.set(index, item);
+ notifyDataSetChanged();
+ }
+ }
+
+ // 讀取指定編號的記事資料
+ public Item get(int index) {
+ return items.get(index);
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0302/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MainActivity.java b/examples/0302/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MainActivity.java
new file mode 100644
index 0000000..64125f0
--- /dev/null
+++ b/examples/0302/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MainActivity.java
@@ -0,0 +1,305 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.v7.app.ActionBarActivity;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+public class MainActivity extends ActionBarActivity {
+ private ListView item_list;
+ private TextView show_app_name;
+
+ // ListView使用的自定Adapter物件
+ private ItemAdapter itemAdapter;
+ // 儲存所有記事本的List物件
+ private List
- items;
+
+ // 選單項目物件
+ private MenuItem add_item, search_item, revert_item, share_item, delete_item;
+
+ // 已選擇項目數量
+ private int selectedCount = 0;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ processViews();
+ processControllers();
+
+ // 加入範例資料
+ items = new ArrayList
- ();
+
+ items.add(new Item(1, new Date().getTime(), Colors.RED, "關於Android Tutorial的事情.", "Hello content", "", 0, 0, 0));
+ items.add(new Item(2, new Date().getTime(), Colors.BLUE, "一隻非常可愛的小狗狗!", "她的名字叫「大熱狗」,又叫\n作「奶嘴」,是一隻非常可愛\n的小狗。", "", 0, 0, 0));
+ items.add(new Item(3, new Date().getTime(), Colors.GREEN, "一首非常好聽的音樂!", "Hello content", "", 0, 0, 0));
+
+ // 建立自定Adapter物件
+ itemAdapter = new ItemAdapter(this, R.layout.single_item, items);
+ item_list.setAdapter(itemAdapter);
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ // 如果被啟動的Activity元件傳回確定的結果
+ if (resultCode == Activity.RESULT_OK) {
+ // 讀取記事物件
+ Item item = (Item) data.getExtras().getSerializable(
+ "net.macdidi.myandroidtutorial.Item");
+
+ // 如果是新增記事
+ if (requestCode == 0) {
+ // 設定記事物件的編號與日期時間
+ item.setId(items.size() + 1);
+ item.setDatetime(new Date().getTime());
+
+ // 加入新增的記事物件
+ items.add(item);
+
+ // 通知資料改變
+ itemAdapter.notifyDataSetChanged();
+ }
+ // 如果是修改記事
+ else if (requestCode == 1) {
+ // 讀取記事編號
+ int position = data.getIntExtra("position", -1);
+
+ if (position != -1) {
+ // 設定修改的記事物件
+ items.set(position, item);
+ itemAdapter.notifyDataSetChanged();
+ }
+ }
+ }
+ }
+
+ private void processViews() {
+ item_list = (ListView)findViewById(R.id.item_list);
+ show_app_name = (TextView) findViewById(R.id.show_app_name);
+ }
+
+ private void processControllers() {
+
+ // 建立選單項目點擊監聽物件
+ AdapterView.OnItemClickListener itemListener = new AdapterView.OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView> parent, View view,
+ int position, long id) {
+ // 讀取選擇的記事物件
+ Item item = itemAdapter.getItem(position);
+
+ // 如果已經有勾選的項目
+ if (selectedCount > 0) {
+ // 處理是否顯示已選擇項目
+ processMenu(item);
+ // 重新設定記事項目
+ itemAdapter.set(position, item);
+ }
+ else {
+ Intent intent = new Intent(
+ "net.macdidi.myandroidtutorial.EDIT_ITEM");
+
+ // 設定記事編號與記事物件
+ intent.putExtra("position", position);
+ intent.putExtra("net.macdidi.myandroidtutorial.Item", item);
+
+ startActivityForResult(intent, 1);
+ }
+ }
+ };
+
+ // 註冊選單項目點擊監聽物件
+ item_list.setOnItemClickListener(itemListener);
+
+ // 建立記事項目長按監聽物件
+ AdapterView.OnItemLongClickListener itemLongListener = new AdapterView.OnItemLongClickListener() {
+ @Override
+ public boolean onItemLongClick(AdapterView> parent, View view,
+ int position, long id) {
+ // 讀取選擇的記事物件
+ Item item = itemAdapter.getItem(position);
+ // 處理是否顯示已選擇項目
+ processMenu(item);
+ // 重新設定記事項目
+ itemAdapter.set(position, item);
+ return true;
+ }
+ };
+
+ // 註冊記事項目長按監聽物件
+ item_list.setOnItemLongClickListener(itemLongListener);
+
+ // 建立長按監聽物件
+ View.OnLongClickListener listener = new View.OnLongClickListener() {
+
+ @Override
+ public boolean onLongClick(View view) {
+ AlertDialog.Builder dialog =
+ new AlertDialog.Builder(MainActivity.this);
+ dialog.setTitle(R.string.app_name)
+ .setMessage(R.string.about)
+ .show();
+ return false;
+ }
+
+ };
+
+ // 註冊長按監聽物件
+ show_app_name.setOnLongClickListener(listener);
+ }
+
+ // 處理是否顯示已選擇項目
+ private void processMenu(Item item) {
+ // 如果需要設定記事項目
+ if (item != null) {
+ // 設定已勾選的狀態
+ item.setSelected(!item.isSelected());
+
+ // 計算已勾選數量
+ if (item.isSelected()) {
+ selectedCount++;
+ }
+ else {
+ selectedCount--;
+ }
+ }
+
+ // 根據選擇的狀況,設定是否顯示選單項目
+ add_item.setVisible(selectedCount == 0);
+ search_item.setVisible(selectedCount == 0);
+ revert_item.setVisible(selectedCount > 0);
+ share_item.setVisible(selectedCount > 0);
+ delete_item.setVisible(selectedCount > 0);
+ }
+
+ // 載入選單資源
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ MenuInflater menuInflater = getMenuInflater();
+ menuInflater.inflate(R.menu.menu_main, menu);
+
+ // 取得選單項目物件
+ add_item = menu.findItem(R.id.add_item);
+ search_item = menu.findItem(R.id.search_item);
+ revert_item = menu.findItem(R.id.revert_item);
+ share_item = menu.findItem(R.id.share_item);
+ delete_item = menu.findItem(R.id.delete_item);
+
+ // 設定選單項目
+ processMenu(null);
+
+ return true;
+ }
+
+ // 使用者選擇所有的選單項目都會呼叫這個方法
+ public void clickMenuItem(MenuItem item) {
+ // 使用參數取得使用者選擇的選單項目元件編號
+ int itemId = item.getItemId();
+
+ // 判斷該執行什麼工作,目前還沒有加入需要執行的工作
+ switch (itemId) {
+ case R.id.search_item:
+ break;
+ // 使用者選擇新增選單項目
+ case R.id.add_item:
+ // 使用Action名稱建立啟動另一個Activity元件需要的Intent物件
+ Intent intent = new Intent("net.macdidi.myandroidtutorial.ADD_ITEM");
+ // 呼叫「startActivityForResult」,,第二個參數「0」表示執行新增
+ startActivityForResult(intent, 0);
+ break;
+ // 取消所有已勾選的項目
+ case R.id.revert_item:
+ for (int i = 0; i < itemAdapter.getCount(); i++) {
+ Item ri = itemAdapter.getItem(i);
+
+ if (ri.isSelected()) {
+ ri.setSelected(false);
+ itemAdapter.set(i, ri);
+ }
+ }
+
+ selectedCount = 0;
+ processMenu(null);
+
+ break;
+ // 刪除
+ case R.id.delete_item:
+ // 沒有選擇
+ if (selectedCount == 0) {
+ break;
+ }
+
+ // 建立與顯示詢問是否刪除的對話框
+ AlertDialog.Builder d = new AlertDialog.Builder(this);
+ String message = getString(R.string.delete_item);
+ d.setTitle(R.string.delete)
+ .setMessage(String.format(message, selectedCount));
+ d.setPositiveButton(android.R.string.yes,
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ // 刪除所有已勾選的項目
+ int index = itemAdapter.getCount() - 1;
+
+ while (index > -1) {
+ Item item = itemAdapter.get(index);
+
+ if (item.isSelected()) {
+ itemAdapter.remove(item);
+ }
+
+ index--;
+ }
+
+ // 通知資料改變
+ itemAdapter.notifyDataSetChanged();
+ selectedCount = 0;
+ processMenu(null);
+ }
+ });
+ d.setNegativeButton(android.R.string.no, null);
+ d.show();
+
+ break;
+ case R.id.googleplus_item:
+ break;
+ case R.id.facebook_item:
+ break;
+ }
+
+ }
+
+ // 方法名稱與onClick的設定一樣,參數的型態是android.view.View
+ public void aboutApp(View view) {
+ // 建立啟動另一個Activity元件需要的Intent物件
+ // 建構式的第一個參數:「this」
+ // 建構式的第二個參數:「Activity元件類別名稱.class」
+ Intent intent = new Intent(this, AboutActivity.class);
+ // 呼叫「startActivity」,參數為一個建立好的Intent物件
+ // 這行敘述執行以後,如果沒有任何錯誤,就會啟動指定的元件
+ startActivity(intent);
+ }
+
+ // 設定
+ public void clickPreferences(MenuItem item) {
+ // 啟動設定元件
+ startActivity(new Intent(this, PrefActivity.class));
+ }
+
+}
+
+
diff --git a/examples/0302/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PrefActivity.java b/examples/0302/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PrefActivity.java
new file mode 100644
index 0000000..b2dcc4a
--- /dev/null
+++ b/examples/0302/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PrefActivity.java
@@ -0,0 +1,38 @@
+package net.macdidi.myandroidtutorial;
+
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceManager;
+
+public class PrefActivity extends PreferenceActivity {
+
+ private SharedPreferences sharedPreferences;
+ private Preference defaultColor;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ // 指定使用的設定畫面配置資源
+ addPreferencesFromResource(R.xml.mypreference);
+ defaultColor = (Preference)findPreference("DEFAULT_COLOR");
+ // 建立SharedPreferences物件
+ sharedPreferences =
+ PreferenceManager.getDefaultSharedPreferences(this);
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ // 讀取設定的預設顏色
+ int color = sharedPreferences.getInt("DEFAULT_COLOR", -1);
+
+ if (color != -1) {
+ // 設定顏色說明
+ defaultColor.setSummary(getString(R.string.default_color_summary) +
+ ": " + ItemActivity.getColors(color));
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0302/MyAndroidTutorial/res/drawable-hdpi/ic_launcher.png b/examples/0302/MyAndroidTutorial/app/src/main/res/drawable-hdpi/ic_launcher.png
old mode 100755
new mode 100644
similarity index 100%
rename from examples/0302/MyAndroidTutorial/res/drawable-hdpi/ic_launcher.png
rename to examples/0302/MyAndroidTutorial/app/src/main/res/drawable-hdpi/ic_launcher.png
diff --git a/examples/0302/MyAndroidTutorial/res/drawable-mdpi/ic_launcher.png b/examples/0302/MyAndroidTutorial/app/src/main/res/drawable-mdpi/ic_launcher.png
old mode 100755
new mode 100644
similarity index 100%
rename from examples/0302/MyAndroidTutorial/res/drawable-mdpi/ic_launcher.png
rename to examples/0302/MyAndroidTutorial/app/src/main/res/drawable-mdpi/ic_launcher.png
diff --git a/examples/0302/MyAndroidTutorial/res/drawable-xhdpi/ic_launcher.png b/examples/0302/MyAndroidTutorial/app/src/main/res/drawable-xhdpi/ic_launcher.png
old mode 100755
new mode 100644
similarity index 100%
rename from examples/0302/MyAndroidTutorial/res/drawable-xhdpi/ic_launcher.png
rename to examples/0302/MyAndroidTutorial/app/src/main/res/drawable-xhdpi/ic_launcher.png
diff --git a/examples/0302/MyAndroidTutorial/app/src/main/res/drawable-xxhdpi/ic_launcher.png b/examples/0302/MyAndroidTutorial/app/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..4df1894
Binary files /dev/null and b/examples/0302/MyAndroidTutorial/app/src/main/res/drawable-xxhdpi/ic_launcher.png differ
diff --git a/examples/0302/MyAndroidTutorial/res/drawable/alarm_icon.png b/examples/0302/MyAndroidTutorial/app/src/main/res/drawable/alarm_icon.png
old mode 100755
new mode 100644
similarity index 100%
rename from examples/0302/MyAndroidTutorial/res/drawable/alarm_icon.png
rename to examples/0302/MyAndroidTutorial/app/src/main/res/drawable/alarm_icon.png
diff --git a/examples/0302/MyAndroidTutorial/app/src/main/res/drawable/item_drawable.xml b/examples/0302/MyAndroidTutorial/app/src/main/res/drawable/item_drawable.xml
new file mode 100644
index 0000000..37607e2
--- /dev/null
+++ b/examples/0302/MyAndroidTutorial/app/src/main/res/drawable/item_drawable.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0302/MyAndroidTutorial/res/drawable/location_icon.png b/examples/0302/MyAndroidTutorial/app/src/main/res/drawable/location_icon.png
old mode 100755
new mode 100644
similarity index 100%
rename from examples/0302/MyAndroidTutorial/res/drawable/location_icon.png
rename to examples/0302/MyAndroidTutorial/app/src/main/res/drawable/location_icon.png
diff --git a/examples/0302/MyAndroidTutorial/res/drawable/record_sound_icon.png b/examples/0302/MyAndroidTutorial/app/src/main/res/drawable/record_sound_icon.png
old mode 100755
new mode 100644
similarity index 100%
rename from examples/0302/MyAndroidTutorial/res/drawable/record_sound_icon.png
rename to examples/0302/MyAndroidTutorial/app/src/main/res/drawable/record_sound_icon.png
diff --git a/examples/0302/MyAndroidTutorial/app/src/main/res/drawable/retangle_drawable.xml b/examples/0302/MyAndroidTutorial/app/src/main/res/drawable/retangle_drawable.xml
new file mode 100644
index 0000000..51d1e84
--- /dev/null
+++ b/examples/0302/MyAndroidTutorial/app/src/main/res/drawable/retangle_drawable.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0302/MyAndroidTutorial/res/drawable/select_color_icon.png b/examples/0302/MyAndroidTutorial/app/src/main/res/drawable/select_color_icon.png
old mode 100755
new mode 100644
similarity index 100%
rename from examples/0302/MyAndroidTutorial/res/drawable/select_color_icon.png
rename to examples/0302/MyAndroidTutorial/app/src/main/res/drawable/select_color_icon.png
diff --git a/examples/0302/MyAndroidTutorial/res/drawable/selected_icon.png b/examples/0302/MyAndroidTutorial/app/src/main/res/drawable/selected_icon.png
similarity index 100%
rename from examples/0302/MyAndroidTutorial/res/drawable/selected_icon.png
rename to examples/0302/MyAndroidTutorial/app/src/main/res/drawable/selected_icon.png
diff --git a/examples/0302/MyAndroidTutorial/res/drawable/take_picture_icon.png b/examples/0302/MyAndroidTutorial/app/src/main/res/drawable/take_picture_icon.png
old mode 100755
new mode 100644
similarity index 100%
rename from examples/0302/MyAndroidTutorial/res/drawable/take_picture_icon.png
rename to examples/0302/MyAndroidTutorial/app/src/main/res/drawable/take_picture_icon.png
diff --git a/examples/0302/MyAndroidTutorial/app/src/main/res/layout/activity_about.xml b/examples/0302/MyAndroidTutorial/app/src/main/res/layout/activity_about.xml
new file mode 100644
index 0000000..8e78611
--- /dev/null
+++ b/examples/0302/MyAndroidTutorial/app/src/main/res/layout/activity_about.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0302/MyAndroidTutorial/app/src/main/res/layout/activity_color.xml b/examples/0302/MyAndroidTutorial/app/src/main/res/layout/activity_color.xml
new file mode 100644
index 0000000..d25bbc5
--- /dev/null
+++ b/examples/0302/MyAndroidTutorial/app/src/main/res/layout/activity_color.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
diff --git a/examples/0302/MyAndroidTutorial/app/src/main/res/layout/activity_item.xml b/examples/0302/MyAndroidTutorial/app/src/main/res/layout/activity_item.xml
new file mode 100644
index 0000000..cb0c3bd
--- /dev/null
+++ b/examples/0302/MyAndroidTutorial/app/src/main/res/layout/activity_item.xml
@@ -0,0 +1,108 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0302/MyAndroidTutorial/app/src/main/res/layout/activity_main.xml b/examples/0302/MyAndroidTutorial/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..121511b
--- /dev/null
+++ b/examples/0302/MyAndroidTutorial/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
diff --git a/examples/0302/MyAndroidTutorial/app/src/main/res/layout/single_item.xml b/examples/0302/MyAndroidTutorial/app/src/main/res/layout/single_item.xml
new file mode 100644
index 0000000..40ddbc9
--- /dev/null
+++ b/examples/0302/MyAndroidTutorial/app/src/main/res/layout/single_item.xml
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0302/MyAndroidTutorial/app/src/main/res/menu/menu_about.xml b/examples/0302/MyAndroidTutorial/app/src/main/res/menu/menu_about.xml
new file mode 100644
index 0000000..d481100
--- /dev/null
+++ b/examples/0302/MyAndroidTutorial/app/src/main/res/menu/menu_about.xml
@@ -0,0 +1,7 @@
+
+
+
diff --git a/examples/0302/MyAndroidTutorial/app/src/main/res/menu/menu_color.xml b/examples/0302/MyAndroidTutorial/app/src/main/res/menu/menu_color.xml
new file mode 100644
index 0000000..8ff243b
--- /dev/null
+++ b/examples/0302/MyAndroidTutorial/app/src/main/res/menu/menu_color.xml
@@ -0,0 +1,7 @@
+
+
+
diff --git a/examples/0302/MyAndroidTutorial/app/src/main/res/menu/menu_item.xml b/examples/0302/MyAndroidTutorial/app/src/main/res/menu/menu_item.xml
new file mode 100644
index 0000000..cd2c9e4
--- /dev/null
+++ b/examples/0302/MyAndroidTutorial/app/src/main/res/menu/menu_item.xml
@@ -0,0 +1,7 @@
+
+
+
diff --git a/examples/0302/MyAndroidTutorial/app/src/main/res/menu/menu_main.xml b/examples/0302/MyAndroidTutorial/app/src/main/res/menu/menu_main.xml
new file mode 100644
index 0000000..0203cfa
--- /dev/null
+++ b/examples/0302/MyAndroidTutorial/app/src/main/res/menu/menu_main.xml
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
diff --git a/examples/0302/MyAndroidTutorial/app/src/main/res/values-en/strings.xml b/examples/0302/MyAndroidTutorial/app/src/main/res/values-en/strings.xml
new file mode 100644
index 0000000..c532533
--- /dev/null
+++ b/examples/0302/MyAndroidTutorial/app/src/main/res/values-en/strings.xml
@@ -0,0 +1,12 @@
+
+
+
+ MyAndroidTutorial
+ Hello world!
+ Settings
+
+ Title
+ Enter title
+ Content
+ Enter content
+
diff --git a/examples/0302/MyAndroidTutorial/app/src/main/res/values-w820dp/dimens.xml b/examples/0302/MyAndroidTutorial/app/src/main/res/values-w820dp/dimens.xml
new file mode 100644
index 0000000..63fc816
--- /dev/null
+++ b/examples/0302/MyAndroidTutorial/app/src/main/res/values-w820dp/dimens.xml
@@ -0,0 +1,6 @@
+
+
+ 64dp
+
diff --git a/examples/0302/MyAndroidTutorial/app/src/main/res/values/colors.xml b/examples/0302/MyAndroidTutorial/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..6b13c1d
--- /dev/null
+++ b/examples/0302/MyAndroidTutorial/app/src/main/res/values/colors.xml
@@ -0,0 +1,7 @@
+
+
+ #CCCCCC
+ #AAAAAA
+ #DD999999
+ #111111
+
\ No newline at end of file
diff --git a/examples/0302/MyAndroidTutorial/app/src/main/res/values/dimens.xml b/examples/0302/MyAndroidTutorial/app/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..02898ec
--- /dev/null
+++ b/examples/0302/MyAndroidTutorial/app/src/main/res/values/dimens.xml
@@ -0,0 +1,9 @@
+
+
+ 16dp
+ 16dp
+
+ 6dp
+ 24sp
+ 2dp
+
diff --git a/examples/0302/MyAndroidTutorial/app/src/main/res/values/strings.xml b/examples/0302/MyAndroidTutorial/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..50f82f1
--- /dev/null
+++ b/examples/0302/MyAndroidTutorial/app/src/main/res/values/strings.xml
@@ -0,0 +1,40 @@
+
+
+
+ MyAndroidTutorial
+ Hello world!
+ Settings
+ 標題
+ 輸入標題
+ 內容
+ 輸入內容
+ 這是Android Tutorial應用程式
+ AboutActivity
+ 版本:AndroidTutorial_0.2.4
+ ItemActivity
+ ColorActivity
+ 刪除
+ 確定要刪除 %1$d 個項目?
+ 預設的顏色
+ 新增記事的預設顏色
+
+ 預設提醒時間
+ 在指定的時間之前通知
+
+
+ - 五分鐘
+ - 十分鐘
+ - 二十分鐘
+ - 三十分鐘
+ - 六十分鐘
+
+
+
+ - 5
+ - 10
+ - 20
+ - 30
+ - 60
+
+
+
diff --git a/examples/0302/MyAndroidTutorial/app/src/main/res/values/styles.xml b/examples/0302/MyAndroidTutorial/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..766ab99
--- /dev/null
+++ b/examples/0302/MyAndroidTutorial/app/src/main/res/values/styles.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
diff --git a/examples/0302/MyAndroidTutorial/app/src/main/res/xml/mypreference.xml b/examples/0302/MyAndroidTutorial/app/src/main/res/xml/mypreference.xml
new file mode 100644
index 0000000..33e714c
--- /dev/null
+++ b/examples/0302/MyAndroidTutorial/app/src/main/res/xml/mypreference.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0302/MyAndroidTutorial/bin/AndroidManifest.xml b/examples/0302/MyAndroidTutorial/bin/AndroidManifest.xml
deleted file mode 100755
index a31ecc2..0000000
--- a/examples/0302/MyAndroidTutorial/bin/AndroidManifest.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/examples/0302/MyAndroidTutorial/bin/MyAndroidTutorial.apk b/examples/0302/MyAndroidTutorial/bin/MyAndroidTutorial.apk
deleted file mode 100644
index 58f4bad..0000000
Binary files a/examples/0302/MyAndroidTutorial/bin/MyAndroidTutorial.apk and /dev/null differ
diff --git a/examples/0302/MyAndroidTutorial/bin/classes.dex b/examples/0302/MyAndroidTutorial/bin/classes.dex
deleted file mode 100755
index b802828..0000000
Binary files a/examples/0302/MyAndroidTutorial/bin/classes.dex and /dev/null differ
diff --git a/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/AboutActivity.class b/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/AboutActivity.class
deleted file mode 100644
index abbf876..0000000
Binary files a/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/AboutActivity.class and /dev/null differ
diff --git a/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/BuildConfig.class b/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/BuildConfig.class
deleted file mode 100644
index 30f5623..0000000
Binary files a/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/BuildConfig.class and /dev/null differ
diff --git a/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ColorActivity$ColorListener.class b/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ColorActivity$ColorListener.class
deleted file mode 100644
index 78ad0d3..0000000
Binary files a/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ColorActivity$ColorListener.class and /dev/null differ
diff --git a/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ColorActivity.class b/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ColorActivity.class
deleted file mode 100644
index 2075635..0000000
Binary files a/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ColorActivity.class and /dev/null differ
diff --git a/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/Colors.class b/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/Colors.class
deleted file mode 100644
index 4dda566..0000000
Binary files a/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/Colors.class and /dev/null differ
diff --git a/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/Item.class b/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/Item.class
deleted file mode 100644
index f5449a6..0000000
Binary files a/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/Item.class and /dev/null differ
diff --git a/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ItemActivity.class b/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ItemActivity.class
deleted file mode 100644
index b7d535a..0000000
Binary files a/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ItemActivity.class and /dev/null differ
diff --git a/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ItemAdapter.class b/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ItemAdapter.class
deleted file mode 100644
index f0949d4..0000000
Binary files a/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ItemAdapter.class and /dev/null differ
diff --git a/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$1.class b/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$1.class
deleted file mode 100644
index a62a964..0000000
Binary files a/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$1.class and /dev/null differ
diff --git a/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$2.class b/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$2.class
deleted file mode 100644
index b073618..0000000
Binary files a/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$2.class and /dev/null differ
diff --git a/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$3.class b/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$3.class
deleted file mode 100644
index 879d037..0000000
Binary files a/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$3.class and /dev/null differ
diff --git a/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$4.class b/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$4.class
deleted file mode 100644
index 760804f..0000000
Binary files a/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$4.class and /dev/null differ
diff --git a/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity.class b/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity.class
deleted file mode 100644
index 9b22daf..0000000
Binary files a/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity.class and /dev/null differ
diff --git a/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/PrefActivity.class b/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/PrefActivity.class
deleted file mode 100644
index 3989e38..0000000
Binary files a/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/PrefActivity.class and /dev/null differ
diff --git a/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$array.class b/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$array.class
deleted file mode 100644
index b9a7b7b..0000000
Binary files a/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$array.class and /dev/null differ
diff --git a/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$attr.class b/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$attr.class
deleted file mode 100644
index 01d5c1c..0000000
Binary files a/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$attr.class and /dev/null differ
diff --git a/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$color.class b/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$color.class
deleted file mode 100644
index c246f78..0000000
Binary files a/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$color.class and /dev/null differ
diff --git a/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$dimen.class b/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$dimen.class
deleted file mode 100644
index 4079bf4..0000000
Binary files a/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$dimen.class and /dev/null differ
diff --git a/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$drawable.class b/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$drawable.class
deleted file mode 100644
index 7037211..0000000
Binary files a/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$drawable.class and /dev/null differ
diff --git a/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$id.class b/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$id.class
deleted file mode 100644
index 8ac23be..0000000
Binary files a/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$id.class and /dev/null differ
diff --git a/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$layout.class b/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$layout.class
deleted file mode 100644
index cb476b8..0000000
Binary files a/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$layout.class and /dev/null differ
diff --git a/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$menu.class b/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$menu.class
deleted file mode 100644
index 5295fb4..0000000
Binary files a/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$menu.class and /dev/null differ
diff --git a/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$string.class b/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$string.class
deleted file mode 100644
index 3cda30a..0000000
Binary files a/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$string.class and /dev/null differ
diff --git a/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$style.class b/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$style.class
deleted file mode 100644
index f502898..0000000
Binary files a/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$style.class and /dev/null differ
diff --git a/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$xml.class b/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$xml.class
deleted file mode 100644
index 7dd8390..0000000
Binary files a/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$xml.class and /dev/null differ
diff --git a/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R.class b/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R.class
deleted file mode 100644
index e09c2b9..0000000
Binary files a/examples/0302/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R.class and /dev/null differ
diff --git a/examples/0302/MyAndroidTutorial/bin/dexedLibs/android-support-v4-9b1d5d28bf7d59a4e392b3d4f78c1f13.jar b/examples/0302/MyAndroidTutorial/bin/dexedLibs/android-support-v4-9b1d5d28bf7d59a4e392b3d4f78c1f13.jar
deleted file mode 100755
index 2f330c0..0000000
Binary files a/examples/0302/MyAndroidTutorial/bin/dexedLibs/android-support-v4-9b1d5d28bf7d59a4e392b3d4f78c1f13.jar and /dev/null differ
diff --git a/examples/0302/MyAndroidTutorial/bin/jarlist.cache b/examples/0302/MyAndroidTutorial/bin/jarlist.cache
deleted file mode 100755
index 0565465..0000000
--- a/examples/0302/MyAndroidTutorial/bin/jarlist.cache
+++ /dev/null
@@ -1,3 +0,0 @@
-# cache for current jar dependency. DO NOT EDIT.
-# format is
-# Encoding is UTF-8
diff --git a/examples/0302/MyAndroidTutorial/bin/res/crunch/drawable-hdpi/ic_launcher.png b/examples/0302/MyAndroidTutorial/bin/res/crunch/drawable-hdpi/ic_launcher.png
deleted file mode 100755
index bcfa058..0000000
Binary files a/examples/0302/MyAndroidTutorial/bin/res/crunch/drawable-hdpi/ic_launcher.png and /dev/null differ
diff --git a/examples/0302/MyAndroidTutorial/bin/res/crunch/drawable-mdpi/ic_launcher.png b/examples/0302/MyAndroidTutorial/bin/res/crunch/drawable-mdpi/ic_launcher.png
deleted file mode 100755
index 85848ff..0000000
Binary files a/examples/0302/MyAndroidTutorial/bin/res/crunch/drawable-mdpi/ic_launcher.png and /dev/null differ
diff --git a/examples/0302/MyAndroidTutorial/bin/res/crunch/drawable-xhdpi/ic_launcher.png b/examples/0302/MyAndroidTutorial/bin/res/crunch/drawable-xhdpi/ic_launcher.png
deleted file mode 100755
index 916901e..0000000
Binary files a/examples/0302/MyAndroidTutorial/bin/res/crunch/drawable-xhdpi/ic_launcher.png and /dev/null differ
diff --git a/examples/0302/MyAndroidTutorial/bin/res/crunch/drawable/alarm_icon.png b/examples/0302/MyAndroidTutorial/bin/res/crunch/drawable/alarm_icon.png
deleted file mode 100755
index ebeae27..0000000
Binary files a/examples/0302/MyAndroidTutorial/bin/res/crunch/drawable/alarm_icon.png and /dev/null differ
diff --git a/examples/0302/MyAndroidTutorial/bin/res/crunch/drawable/location_icon.png b/examples/0302/MyAndroidTutorial/bin/res/crunch/drawable/location_icon.png
deleted file mode 100755
index 6897a97..0000000
Binary files a/examples/0302/MyAndroidTutorial/bin/res/crunch/drawable/location_icon.png and /dev/null differ
diff --git a/examples/0302/MyAndroidTutorial/bin/res/crunch/drawable/record_sound_icon.png b/examples/0302/MyAndroidTutorial/bin/res/crunch/drawable/record_sound_icon.png
deleted file mode 100755
index 6fe2060..0000000
Binary files a/examples/0302/MyAndroidTutorial/bin/res/crunch/drawable/record_sound_icon.png and /dev/null differ
diff --git a/examples/0302/MyAndroidTutorial/bin/res/crunch/drawable/select_color_icon.png b/examples/0302/MyAndroidTutorial/bin/res/crunch/drawable/select_color_icon.png
deleted file mode 100755
index 4270ec5..0000000
Binary files a/examples/0302/MyAndroidTutorial/bin/res/crunch/drawable/select_color_icon.png and /dev/null differ
diff --git a/examples/0302/MyAndroidTutorial/bin/res/crunch/drawable/selected_icon.png b/examples/0302/MyAndroidTutorial/bin/res/crunch/drawable/selected_icon.png
deleted file mode 100755
index 982ddee..0000000
Binary files a/examples/0302/MyAndroidTutorial/bin/res/crunch/drawable/selected_icon.png and /dev/null differ
diff --git a/examples/0302/MyAndroidTutorial/bin/res/crunch/drawable/take_picture_icon.png b/examples/0302/MyAndroidTutorial/bin/res/crunch/drawable/take_picture_icon.png
deleted file mode 100755
index c812e2f..0000000
Binary files a/examples/0302/MyAndroidTutorial/bin/res/crunch/drawable/take_picture_icon.png and /dev/null differ
diff --git a/examples/0302/MyAndroidTutorial/bin/resources.ap_ b/examples/0302/MyAndroidTutorial/bin/resources.ap_
deleted file mode 100644
index e01ad50..0000000
Binary files a/examples/0302/MyAndroidTutorial/bin/resources.ap_ and /dev/null differ
diff --git a/examples/0302/MyAndroidTutorial/build.gradle b/examples/0302/MyAndroidTutorial/build.gradle
new file mode 100644
index 0000000..6356aab
--- /dev/null
+++ b/examples/0302/MyAndroidTutorial/build.gradle
@@ -0,0 +1,19 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+ repositories {
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:1.0.0'
+
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+}
+
+allprojects {
+ repositories {
+ jcenter()
+ }
+}
diff --git a/examples/0302/MyAndroidTutorial/gen/net/macdidi/myandroidtutorial/BuildConfig.java b/examples/0302/MyAndroidTutorial/gen/net/macdidi/myandroidtutorial/BuildConfig.java
deleted file mode 100755
index 5d44ea9..0000000
--- a/examples/0302/MyAndroidTutorial/gen/net/macdidi/myandroidtutorial/BuildConfig.java
+++ /dev/null
@@ -1,6 +0,0 @@
-/** Automatically generated file. DO NOT MODIFY */
-package net.macdidi.myandroidtutorial;
-
-public final class BuildConfig {
- public final static boolean DEBUG = true;
-}
\ No newline at end of file
diff --git a/examples/0302/MyAndroidTutorial/gen/net/macdidi/myandroidtutorial/R.java b/examples/0302/MyAndroidTutorial/gen/net/macdidi/myandroidtutorial/R.java
deleted file mode 100755
index c7b4771..0000000
--- a/examples/0302/MyAndroidTutorial/gen/net/macdidi/myandroidtutorial/R.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/* AUTO-GENERATED FILE. DO NOT MODIFY.
- *
- * This class was automatically generated by the
- * aapt tool from the resource data it found. It
- * should not be modified by hand.
- */
-
-package net.macdidi.myandroidtutorial;
-
-public final class R {
- public static final class array {
- public static final int notify_minutes_array=0x7f080000;
- public static final int notify_minutes_value_array=0x7f080001;
- }
- public static final class attr {
- }
- public static final class color {
- public static final int dark_text=0x7f050003;
- public static final int divider_color=0x7f050002;
- public static final int grey=0x7f050001;
- public static final int light_grey=0x7f050000;
- }
- public static final class dimen {
- public static final int default_margin=0x7f060001;
- public static final int default_padding=0x7f060000;
- public static final int title_txt_size=0x7f060002;
- }
- public static final class drawable {
- public static final int alarm_icon=0x7f020000;
- public static final int ic_launcher=0x7f020001;
- public static final int item_drawable=0x7f020002;
- public static final int location_icon=0x7f020003;
- public static final int record_sound_icon=0x7f020004;
- public static final int retangle_drawable=0x7f020005;
- public static final int select_color_icon=0x7f020006;
- public static final int selected_icon=0x7f020007;
- public static final int take_picture_icon=0x7f020008;
- }
- public static final class id {
- public static final int add_item=0x7f0b0010;
- public static final int cancel_item=0x7f0b0008;
- public static final int color_gallery=0x7f0b0000;
- public static final int content_text=0x7f0b0002;
- public static final int date_text=0x7f0b000e;
- public static final int delete_item=0x7f0b0012;
- public static final int facebook_item=0x7f0b0015;
- public static final int googleplus_item=0x7f0b0014;
- public static final int item_list=0x7f0b000a;
- public static final int ok_teim=0x7f0b0009;
- public static final int record_sound=0x7f0b0004;
- public static final int revert_item=0x7f0b0011;
- public static final int search_item=0x7f0b000f;
- public static final int select_color=0x7f0b0007;
- public static final int selected_item=0x7f0b000d;
- public static final int set_alarm=0x7f0b0006;
- public static final int set_location=0x7f0b0005;
- public static final int share_item=0x7f0b0013;
- public static final int show_app_name=0x7f0b000b;
- public static final int take_picture=0x7f0b0003;
- public static final int title_text=0x7f0b0001;
- public static final int type_color=0x7f0b000c;
- }
- public static final class layout {
- public static final int activity_about=0x7f030000;
- public static final int activity_color=0x7f030001;
- public static final int activity_item=0x7f030002;
- public static final int activity_main=0x7f030003;
- public static final int single_item=0x7f030004;
- }
- public static final class menu {
- public static final int main_menu=0x7f0a0000;
- }
- public static final class string {
- public static final int about=0x7f070007;
- public static final int app_name=0x7f070000;
- public static final int content=0x7f070005;
- public static final int default_color=0x7f07000b;
- public static final int default_color_summary=0x7f07000c;
- public static final int default_notify=0x7f07000d;
- public static final int default_notify_summary=0x7f07000e;
- public static final int delete=0x7f070009;
- public static final int delete_item=0x7f07000a;
- public static final int enter_content=0x7f070006;
- public static final int enter_title=0x7f070004;
- public static final int hello_world=0x7f07000f;
- public static final int title=0x7f070003;
- public static final int title_activity_color=0x7f070002;
- public static final int title_activity_main=0x7f070001;
- public static final int version=0x7f070008;
- }
- public static final class style {
- /**
- Base application theme, dependent on API level. This theme is replaced
- by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
-
-
- Theme customizations available in newer API levels can go in
- res/values-vXX/styles.xml, while customizations related to
- backward-compatibility can go here.
-
-
- Base application theme for API 11+. This theme completely replaces
- AppBaseTheme from res/values/styles.xml on API 11+ devices.
-
- API 11 theme customizations can go here.
-
- Base application theme for API 14+. This theme completely replaces
- AppBaseTheme from BOTH res/values/styles.xml and
- res/values-v11/styles.xml on API 14+ devices.
-
- API 14 theme customizations can go here.
- */
- public static final int AppBaseTheme=0x7f090000;
- /** Application theme.
- All customizations that are NOT specific to a particular API-level can go here.
- */
- public static final int AppTheme=0x7f090001;
- }
- public static final class xml {
- public static final int mypreference=0x7f040000;
- }
-}
diff --git a/examples/0302/MyAndroidTutorial/gradle.properties b/examples/0302/MyAndroidTutorial/gradle.properties
new file mode 100644
index 0000000..1d3591c
--- /dev/null
+++ b/examples/0302/MyAndroidTutorial/gradle.properties
@@ -0,0 +1,18 @@
+# Project-wide Gradle settings.
+
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+# Default value: -Xmx10248m -XX:MaxPermSize=256m
+# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
+
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
\ No newline at end of file
diff --git a/examples/0302/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.jar b/examples/0302/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
Binary files /dev/null and b/examples/0302/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/examples/0302/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.properties b/examples/0302/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..0c71e76
--- /dev/null
+++ b/examples/0302/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
diff --git a/examples/0302/MyAndroidTutorial/gradlew b/examples/0302/MyAndroidTutorial/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/examples/0302/MyAndroidTutorial/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/examples/0302/MyAndroidTutorial/gradlew.bat b/examples/0302/MyAndroidTutorial/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/examples/0302/MyAndroidTutorial/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/examples/0302/MyAndroidTutorial/libs/android-support-v4.jar b/examples/0302/MyAndroidTutorial/libs/android-support-v4.jar
deleted file mode 100755
index 187bdf4..0000000
Binary files a/examples/0302/MyAndroidTutorial/libs/android-support-v4.jar and /dev/null differ
diff --git a/examples/0302/MyAndroidTutorial/proguard-project.txt b/examples/0302/MyAndroidTutorial/proguard-project.txt
deleted file mode 100755
index f2fe155..0000000
--- a/examples/0302/MyAndroidTutorial/proguard-project.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-# To enable ProGuard in your project, edit project.properties
-# to define the proguard.config property as described in that file.
-#
-# Add project specific ProGuard rules here.
-# By default, the flags in this file are appended to flags specified
-# in ${sdk.dir}/tools/proguard/proguard-android.txt
-# You can edit the include path and order by changing the ProGuard
-# include property in project.properties.
-#
-# For more details, see
-# http://developer.android.com/guide/developing/tools/proguard.html
-
-# Add any project specific keep options here:
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-# public *;
-#}
diff --git a/examples/0302/MyAndroidTutorial/project.properties b/examples/0302/MyAndroidTutorial/project.properties
deleted file mode 100755
index 4ab1256..0000000
--- a/examples/0302/MyAndroidTutorial/project.properties
+++ /dev/null
@@ -1,14 +0,0 @@
-# This file is automatically generated by Android Tools.
-# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
-#
-# This file must be checked in Version Control Systems.
-#
-# To customize properties used by the Ant build system edit
-# "ant.properties", and override values to adapt the script to your
-# project structure.
-#
-# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
-#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
-
-# Project target.
-target=android-19
diff --git a/examples/0302/MyAndroidTutorial/res/drawable/item_drawable.xml b/examples/0302/MyAndroidTutorial/res/drawable/item_drawable.xml
deleted file mode 100755
index ecc4011..0000000
--- a/examples/0302/MyAndroidTutorial/res/drawable/item_drawable.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/examples/0302/MyAndroidTutorial/res/drawable/retangle_drawable.xml b/examples/0302/MyAndroidTutorial/res/drawable/retangle_drawable.xml
deleted file mode 100755
index e195342..0000000
--- a/examples/0302/MyAndroidTutorial/res/drawable/retangle_drawable.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/examples/0302/MyAndroidTutorial/res/layout/activity_about.xml b/examples/0302/MyAndroidTutorial/res/layout/activity_about.xml
deleted file mode 100755
index 738fe98..0000000
--- a/examples/0302/MyAndroidTutorial/res/layout/activity_about.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/examples/0302/MyAndroidTutorial/res/layout/activity_color.xml b/examples/0302/MyAndroidTutorial/res/layout/activity_color.xml
deleted file mode 100755
index 693a9d4..0000000
--- a/examples/0302/MyAndroidTutorial/res/layout/activity_color.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
-
-
diff --git a/examples/0302/MyAndroidTutorial/res/layout/activity_item.xml b/examples/0302/MyAndroidTutorial/res/layout/activity_item.xml
deleted file mode 100755
index a12c44c..0000000
--- a/examples/0302/MyAndroidTutorial/res/layout/activity_item.xml
+++ /dev/null
@@ -1,94 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/examples/0302/MyAndroidTutorial/res/layout/activity_main.xml b/examples/0302/MyAndroidTutorial/res/layout/activity_main.xml
deleted file mode 100755
index 418c34b..0000000
--- a/examples/0302/MyAndroidTutorial/res/layout/activity_main.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
diff --git a/examples/0302/MyAndroidTutorial/res/layout/single_item.xml b/examples/0302/MyAndroidTutorial/res/layout/single_item.xml
deleted file mode 100755
index c3b579c..0000000
--- a/examples/0302/MyAndroidTutorial/res/layout/single_item.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/examples/0302/MyAndroidTutorial/res/menu/main_menu.xml b/examples/0302/MyAndroidTutorial/res/menu/main_menu.xml
deleted file mode 100755
index dadd8fa..0000000
--- a/examples/0302/MyAndroidTutorial/res/menu/main_menu.xml
+++ /dev/null
@@ -1,51 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/examples/0302/MyAndroidTutorial/res/values-en/strings.xml b/examples/0302/MyAndroidTutorial/res/values-en/strings.xml
deleted file mode 100755
index 34f4fed..0000000
--- a/examples/0302/MyAndroidTutorial/res/values-en/strings.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
- MyAndroidTutorial
- MainActivity
- Hello world!
-
- Title
- Enter title
- Content
- Enter content
-
-
diff --git a/examples/0302/MyAndroidTutorial/res/values-v11/styles.xml b/examples/0302/MyAndroidTutorial/res/values-v11/styles.xml
deleted file mode 100755
index 3c02242..0000000
--- a/examples/0302/MyAndroidTutorial/res/values-v11/styles.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
diff --git a/examples/0302/MyAndroidTutorial/res/values-v14/styles.xml b/examples/0302/MyAndroidTutorial/res/values-v14/styles.xml
deleted file mode 100755
index a91fd03..0000000
--- a/examples/0302/MyAndroidTutorial/res/values-v14/styles.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
diff --git a/examples/0302/MyAndroidTutorial/res/values/colors.xml b/examples/0302/MyAndroidTutorial/res/values/colors.xml
deleted file mode 100755
index c63ec2d..0000000
--- a/examples/0302/MyAndroidTutorial/res/values/colors.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
- #CCCCCC
- #AAAAAA
- #DDCCCCCC
- #111111
-
diff --git a/examples/0302/MyAndroidTutorial/res/values/dimens.xml b/examples/0302/MyAndroidTutorial/res/values/dimens.xml
deleted file mode 100755
index fb03071..0000000
--- a/examples/0302/MyAndroidTutorial/res/values/dimens.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
- 6dp
- 2dp
- 24sp
-
diff --git a/examples/0302/MyAndroidTutorial/res/values/strings.xml b/examples/0302/MyAndroidTutorial/res/values/strings.xml
deleted file mode 100755
index 53d96b7..0000000
--- a/examples/0302/MyAndroidTutorial/res/values/strings.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-
-
-
- MyAndroidTutorial
- MyAndroidTutorial
- 設定顏色
- 標題
- 輸入標題
- 內容
- 輸入內容
- 這是Android Tutorial應用程式
- 版本:AndroidTutorial_0.2.4
-
- 刪除
- 確定要刪除 %1$d 個項目?
-
- 預設的顏色
- 新增記事的預設顏色
-
- 預設提醒時間
- 在指定的時間之前通知
-
-
- - 五分鐘
- - 十分鐘
- - 二十分鐘
- - 三十分鐘
- - 六十分鐘
-
-
-
- - 5
- - 10
- - 20
- - 30
- - 60
-
-
-
diff --git a/examples/0302/MyAndroidTutorial/res/values/styles.xml b/examples/0302/MyAndroidTutorial/res/values/styles.xml
deleted file mode 100755
index 6ce89c7..0000000
--- a/examples/0302/MyAndroidTutorial/res/values/styles.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
-
-
-
-
-
-
diff --git a/examples/0302/MyAndroidTutorial/res/xml/mypreference.xml b/examples/0302/MyAndroidTutorial/res/xml/mypreference.xml
deleted file mode 100644
index 4cd7f5e..0000000
--- a/examples/0302/MyAndroidTutorial/res/xml/mypreference.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/examples/0302/MyAndroidTutorial/settings.gradle b/examples/0302/MyAndroidTutorial/settings.gradle
new file mode 100644
index 0000000..e7b4def
--- /dev/null
+++ b/examples/0302/MyAndroidTutorial/settings.gradle
@@ -0,0 +1 @@
+include ':app'
diff --git a/examples/0302/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/AboutActivity.java b/examples/0302/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/AboutActivity.java
deleted file mode 100755
index 111efc5..0000000
--- a/examples/0302/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/AboutActivity.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package net.macdidi.myandroidtutorial;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.view.View;
-import android.view.Window;
-
-public class AboutActivity extends Activity {
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- // 取消元件的應用程式標題
- requestWindowFeature(Window.FEATURE_NO_TITLE);
- setContentView(R.layout.activity_about);
- }
-
- // 結束按鈕
- public void clickOk(View view) {
- // 呼叫這個方法結束Activity元件
- finish();
- }
-
-}
diff --git a/examples/0302/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/ColorActivity.java b/examples/0302/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/ColorActivity.java
deleted file mode 100755
index 0eafb85..0000000
--- a/examples/0302/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/ColorActivity.java
+++ /dev/null
@@ -1,75 +0,0 @@
-package net.macdidi.myandroidtutorial;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.os.Bundle;
-import android.preference.PreferenceManager;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.widget.Button;
-import android.widget.LinearLayout;
-
-public class ColorActivity extends Activity {
-
- private LinearLayout color_gallery;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_color);
-
- processViews();
-
- ColorListener listener = new ColorListener();
-
- for (Colors c : Colors.values()) {
- Button button = new Button(this);
- button.setId(c.parseColor());
- LinearLayout.LayoutParams layout =
- new LinearLayout.LayoutParams(128, 128);
- layout.setMargins(6, 6, 6, 6);
- button.setLayoutParams(layout);
- button.setBackgroundColor(c.parseColor());
-
- button.setOnClickListener(listener);
-
- color_gallery.addView(button);
- }
- }
-
- private void processViews() {
- color_gallery = (LinearLayout) findViewById(R.id.color_gallery);
- }
-
- private class ColorListener implements OnClickListener {
-
- @Override
- public void onClick(View view) {
- String action = ColorActivity.this.getIntent().getAction();
-
- // 經由設定元件啟動
- if (action != null &&
- action.equals("net.macdidi.myandroidtutorial.CHOOSE_COLOR")) {
- // 建立SharedPreferences物件
- SharedPreferences.Editor editor =
- PreferenceManager.getDefaultSharedPreferences(
- ColorActivity.this).edit();
- // 儲存預設顏色
- editor.putInt("DEFAULT_COLOR", view.getId());
- // 寫入設定值
- editor.commit();
- finish();
- }
- // 經由新增或修改記事的元件啟動
- else {
- Intent result = getIntent();
- result.putExtra("colorId", view.getId());
- setResult(Activity.RESULT_OK, result);
- finish();
- }
- }
-
- }
-
-}
diff --git a/examples/0302/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/Colors.java b/examples/0302/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/Colors.java
deleted file mode 100755
index a3eb9d4..0000000
--- a/examples/0302/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/Colors.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package net.macdidi.myandroidtutorial;
-
-import android.graphics.Color;
-
-public enum Colors {
-
- LIGHTGREY("#D3D3D3"), BLUE("#33B5E5"), PURPLE("#AA66CC"),
- GREEN("#99CC00"), ORANGE("#FFBB33"), RED("#FF4444");
-
- private String code;
-
- private Colors(String code) {
- this.code = code;
- }
-
- public String getCode() {
- return code;
- }
-
- public int parseColor() {
- return Color.parseColor(code);
- }
-
-}
diff --git a/examples/0302/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/Item.java b/examples/0302/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/Item.java
deleted file mode 100755
index d2df2a9..0000000
--- a/examples/0302/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/Item.java
+++ /dev/null
@@ -1,135 +0,0 @@
-package net.macdidi.myandroidtutorial;
-
-import java.util.Date;
-import java.util.Locale;
-
-public class Item implements java.io.Serializable {
-
- // 編號、日期時間、顏色、標題、內容、檔案名稱、經緯度、修改、已選擇
- private long id;
- private long datetime;
- private Colors color;
- private String title;
- private String content;
- private String fileName;
- private double latitude;
- private double longitude;
- private long lastModify;
- private boolean selected;
-
- public Item() {
- title = "";
- content = "";
- color = Colors.LIGHTGREY;
- }
-
- public Item(long id, long datetime, Colors color, String title,
- String content, String fileName, double latitude, double longitude,
- long lastModify) {
- this.id = id;
- this.datetime = datetime;
- this.color = color;
- this.title = title;
- this.content = content;
- this.fileName = fileName;
- this.latitude = latitude;
- this.longitude = longitude;
- this.lastModify = lastModify;
- }
-
- public long getId() {
- return id;
- }
-
- public void setId(long id) {
- this.id = id;
- }
-
- public long getDatetime() {
- return datetime;
- }
-
- // 裝置區域的日期時間
- public String getLocaleDatetime() {
- return String.format(Locale.getDefault(), "%tF % {
-
- // 畫面資源編號
- private int resource;
- // 包裝的記事資料
- private List- items;
-
- public ItemAdapter(Context context, int resource, List
- items) {
- super(context, resource, items);
- this.resource = resource;
- this.items = items;
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- LinearLayout itemView;
- // 讀取目前位置的記事物件
- final Item item = getItem(position);
-
- if (convertView == null) {
- // 建立項目畫面元件
- itemView = new LinearLayout(getContext());
- String inflater = Context.LAYOUT_INFLATER_SERVICE;
- LayoutInflater li = (LayoutInflater)
- getContext().getSystemService(inflater);
- li.inflate(resource, itemView, true);
- }
- else {
- itemView = (LinearLayout) convertView;
- }
-
- // 讀取記事顏色、已選擇、標題與日期時間元件
- RelativeLayout typeColor = (RelativeLayout) itemView.findViewById(R.id.type_color);
- ImageView selectedItem = (ImageView) itemView.findViewById(R.id.selected_item);
- TextView titleView = (TextView) itemView.findViewById(R.id.title_text);
- TextView dateView = (TextView) itemView.findViewById(R.id.date_text);
-
- // 設定記事顏色
- GradientDrawable background = (GradientDrawable)typeColor.getBackground();
- background.setColor(item.getColor().parseColor());
-
- // 設定標題與日期時間
- titleView.setText(item.getTitle());
- dateView.setText(item.getLocaleDatetime());
-
- // 設定是否已選擇
- selectedItem.setVisibility(item.isSelected() ? View.VISIBLE : View.INVISIBLE);
-
- return itemView;
- }
-
- // 設定指定編號的記事資料
- public void set(int index, Item item) {
- if (index >= 0 && index < items.size()) {
- items.set(index, item);
- notifyDataSetChanged();
- }
- }
-
- // 讀取指定編號的記事資料
- public Item get(int index) {
- return items.get(index);
- }
-
-}
diff --git a/examples/0302/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/MainActivity.java b/examples/0302/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/MainActivity.java
deleted file mode 100755
index 87781b9..0000000
--- a/examples/0302/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/MainActivity.java
+++ /dev/null
@@ -1,245 +0,0 @@
-package net.macdidi.myandroidtutorial;
-
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.os.Bundle;
-import android.preference.PreferenceManager;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.View.OnLongClickListener;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemClickListener;
-import android.widget.AdapterView.OnItemLongClickListener;
-import android.widget.ListView;
-import android.widget.TextView;
-import android.widget.Toast;
-
-public class MainActivity extends Activity {
-
- private ListView item_list;
- private TextView show_app_name;
-
- private ItemAdapter itemAdapter;
- private List
- items;
-
- private MenuItem add_item, search_item, revert_item, share_item, delete_item;
-
- private int selectedCount = 0;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
-
- processViews();
- processControllers();
-
- items = new ArrayList
- ();
-
- items.add(new Item(1, new Date().getTime(), Colors.RED, "關於Android Tutorial的事情.", "Hello content", "", 0, 0, 0));
- items.add(new Item(2, new Date().getTime(), Colors.BLUE, "一隻非常可愛的小狗狗!", "她的名字叫「大熱狗」,又叫\n作「奶嘴」,是一隻非常可愛\n的小狗。", "", 0, 0, 0));
- items.add(new Item(3, new Date().getTime(), Colors.GREEN, "一首非常好聽的音樂!", "Hello content", "", 0, 0, 0));
-
- itemAdapter = new ItemAdapter(this, R.layout.single_item, items);
- item_list.setAdapter(itemAdapter);
- }
-
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- if (resultCode == Activity.RESULT_OK) {
- Item item = (Item) data.getExtras().getSerializable(
- "net.macdidi.myandroidtutorial.Item");
-
- if (requestCode == 0) {
- item.setId(items.size() + 1);
- items.add(item);
- itemAdapter.notifyDataSetChanged();
- }
- else if (requestCode == 1) {
- int position = data.getIntExtra("position", -1);
-
- if (position != -1) {
- items.set(position, item);
- itemAdapter.notifyDataSetChanged();
- }
- }
- }
- }
-
- private void processViews() {
- item_list = (ListView)findViewById(R.id.item_list);
- show_app_name = (TextView) findViewById(R.id.show_app_name);
- }
-
- private void processControllers() {
-
- OnItemClickListener itemListener = new OnItemClickListener() {
- @Override
- public void onItemClick(AdapterView> parent, View view,
- int position, long id) {
- Item item = itemAdapter.getItem(position);
-
- if (selectedCount > 0) {
- processMenu(item);
- itemAdapter.set(position, item);
- }
- else {
- Intent intent = new Intent(
- "net.macdidi.myandroidtutorial.EDIT_ITEM");
- intent.putExtra("position", position);
- intent.putExtra("net.macdidi.myandroidtutorial.Item", item);
- startActivityForResult(intent, 1);
- }
- }
- };
-
- item_list.setOnItemClickListener(itemListener);
-
- OnItemLongClickListener itemLongListener = new OnItemLongClickListener() {
- @Override
- public boolean onItemLongClick(AdapterView> parent, View view,
- int position, long id) {
- Item item = itemAdapter.getItem(position);
- processMenu(item);
- itemAdapter.set(position, item);
- return true;
- }
- };
-
- item_list.setOnItemLongClickListener(itemLongListener);
-
- OnLongClickListener listener = new OnLongClickListener() {
-
- @Override
- public boolean onLongClick(View view) {
- AlertDialog.Builder dialog =
- new AlertDialog.Builder(MainActivity.this);
- dialog.setTitle(R.string.app_name)
- .setMessage(R.string.about)
- .show();
- return false;
- }
-
- };
-
- show_app_name.setOnLongClickListener(listener);
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- MenuInflater menuInflater = getMenuInflater();
- menuInflater.inflate(R.menu.main_menu, menu);
-
- add_item = menu.findItem(R.id.add_item);
- search_item = menu.findItem(R.id.search_item);
- revert_item = menu.findItem(R.id.revert_item);
- share_item = menu.findItem(R.id.share_item);
- delete_item = menu.findItem(R.id.delete_item);
-
- processMenu(null);
-
- return true;
- }
-
- public void clickMenuItem(MenuItem item) {
- int itemId = item.getItemId();
-
- switch (itemId) {
- case R.id.search_item:
- break;
- case R.id.add_item:
- Intent intent = new Intent("net.macdidi.myandroidtutorial.ADD_ITEM");
- startActivityForResult(intent, 0);
- break;
- case R.id.revert_item:
- for (int i = 0; i < itemAdapter.getCount(); i++) {
- Item ri = itemAdapter.getItem(i);
-
- if (ri.isSelected()) {
- ri.setSelected(false);
- itemAdapter.set(i, ri);
- }
- }
-
- selectedCount = 0;
- processMenu(null);
-
- break;
- case R.id.delete_item:
- if (selectedCount == 0) {
- break;
- }
-
- AlertDialog.Builder d = new AlertDialog.Builder(this);
- String message = getString(R.string.delete_item);
- d.setTitle(R.string.delete)
- .setMessage(String.format(message, selectedCount));
- d.setPositiveButton(android.R.string.yes,
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- int index = itemAdapter.getCount() - 1;
-
- while (index > -1) {
- Item item = itemAdapter.get(index);
-
- if (item.isSelected()) {
- itemAdapter.remove(item);
- }
-
- index--;
- }
-
- itemAdapter.notifyDataSetChanged();
- }
- });
- d.setNegativeButton(android.R.string.no, null);
- d.show();
-
- break;
- case R.id.googleplus_item:
- break;
- case R.id.facebook_item:
- break;
- }
- }
-
- // 設定
- public void clickPreferences(MenuItem item) {
- // 啟動設定元件
- startActivity(new Intent(this, PrefActivity.class));
- }
-
- private void processMenu(Item item) {
- if (item != null) {
- item.setSelected(!item.isSelected());
-
- if (item.isSelected()) {
- selectedCount++;
- }
- else {
- selectedCount--;
- }
- }
-
- add_item.setVisible(selectedCount == 0);
- search_item.setVisible(selectedCount == 0);
- revert_item.setVisible(selectedCount > 0);
- share_item.setVisible(selectedCount > 0);
- delete_item.setVisible(selectedCount > 0);
- }
-
- public void aboutApp(View view) {
- Intent intent = new Intent(this, AboutActivity.class);
- startActivity(intent);
- }
-}
diff --git a/examples/0302/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/PrefActivity.java b/examples/0302/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/PrefActivity.java
deleted file mode 100644
index aa37810..0000000
--- a/examples/0302/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/PrefActivity.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package net.macdidi.myandroidtutorial;
-
-import android.content.SharedPreferences;
-import android.os.Bundle;
-import android.preference.Preference;
-import android.preference.PreferenceActivity;
-import android.preference.PreferenceManager;
-
-public class PrefActivity extends PreferenceActivity {
-
- private SharedPreferences sharedPreferences;
- private Preference defaultColor;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- // 指定使用的設定畫面配置資源
- addPreferencesFromResource(R.xml.mypreference);
- defaultColor = (Preference)findPreference("DEFAULT_COLOR");
- // 建立SharedPreferences物件
- sharedPreferences =
- PreferenceManager.getDefaultSharedPreferences(this);
- }
-
- @Override
- protected void onResume() {
- super.onResume();
- // 讀取設定的預設顏色
- int color = sharedPreferences.getInt("DEFAULT_COLOR", -1);
-
- if (color != -1) {
- // 設定顏色說明
- defaultColor.setSummary(getString(R.string.default_color_summary) +
- ": " + ItemActivity.getColors(color));
- }
- }
-
-}
diff --git a/examples/0303/MyAndroidTutorial/.classpath b/examples/0303/MyAndroidTutorial/.classpath
deleted file mode 100755
index 7bc01d9..0000000
--- a/examples/0303/MyAndroidTutorial/.classpath
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
-
-
-
-
diff --git a/examples/0303/MyAndroidTutorial/.gitignore b/examples/0303/MyAndroidTutorial/.gitignore
new file mode 100644
index 0000000..afbdab3
--- /dev/null
+++ b/examples/0303/MyAndroidTutorial/.gitignore
@@ -0,0 +1,6 @@
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
diff --git a/examples/0303/MyAndroidTutorial/.idea/.name b/examples/0303/MyAndroidTutorial/.idea/.name
new file mode 100644
index 0000000..5bb7a85
--- /dev/null
+++ b/examples/0303/MyAndroidTutorial/.idea/.name
@@ -0,0 +1 @@
+MyAndroidTutorial
\ No newline at end of file
diff --git a/examples/0303/MyAndroidTutorial/.idea/compiler.xml b/examples/0303/MyAndroidTutorial/.idea/compiler.xml
new file mode 100644
index 0000000..217af47
--- /dev/null
+++ b/examples/0303/MyAndroidTutorial/.idea/compiler.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0303/MyAndroidTutorial/.idea/copyright/profiles_settings.xml b/examples/0303/MyAndroidTutorial/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..e7bedf3
--- /dev/null
+++ b/examples/0303/MyAndroidTutorial/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/examples/0303/MyAndroidTutorial/.idea/encodings.xml b/examples/0303/MyAndroidTutorial/.idea/encodings.xml
new file mode 100644
index 0000000..e206d70
--- /dev/null
+++ b/examples/0303/MyAndroidTutorial/.idea/encodings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/examples/0303/MyAndroidTutorial/.idea/gradle.xml b/examples/0303/MyAndroidTutorial/.idea/gradle.xml
new file mode 100644
index 0000000..fe865d3
--- /dev/null
+++ b/examples/0303/MyAndroidTutorial/.idea/gradle.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0303/MyAndroidTutorial/.idea/misc.xml b/examples/0303/MyAndroidTutorial/.idea/misc.xml
new file mode 100644
index 0000000..9076de5
--- /dev/null
+++ b/examples/0303/MyAndroidTutorial/.idea/misc.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0303/MyAndroidTutorial/.idea/modules.xml b/examples/0303/MyAndroidTutorial/.idea/modules.xml
new file mode 100644
index 0000000..327df67
--- /dev/null
+++ b/examples/0303/MyAndroidTutorial/.idea/modules.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0303/MyAndroidTutorial/.idea/scopes/scope_settings.xml b/examples/0303/MyAndroidTutorial/.idea/scopes/scope_settings.xml
new file mode 100644
index 0000000..922003b
--- /dev/null
+++ b/examples/0303/MyAndroidTutorial/.idea/scopes/scope_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0303/MyAndroidTutorial/.idea/vcs.xml b/examples/0303/MyAndroidTutorial/.idea/vcs.xml
new file mode 100644
index 0000000..def6a6a
--- /dev/null
+++ b/examples/0303/MyAndroidTutorial/.idea/vcs.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/examples/0303/MyAndroidTutorial/.project b/examples/0303/MyAndroidTutorial/.project
deleted file mode 100755
index b1de407..0000000
--- a/examples/0303/MyAndroidTutorial/.project
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
- MyAndroidTutorial
-
-
-
-
-
- com.android.ide.eclipse.adt.ResourceManagerBuilder
-
-
-
-
- com.android.ide.eclipse.adt.PreCompilerBuilder
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- com.android.ide.eclipse.adt.ApkBuilder
-
-
-
-
-
- com.android.ide.eclipse.adt.AndroidNature
- org.eclipse.jdt.core.javanature
-
-
diff --git a/examples/0303/MyAndroidTutorial/.settings/org.eclipse.core.resources.prefs b/examples/0303/MyAndroidTutorial/.settings/org.eclipse.core.resources.prefs
deleted file mode 100644
index 99f26c0..0000000
--- a/examples/0303/MyAndroidTutorial/.settings/org.eclipse.core.resources.prefs
+++ /dev/null
@@ -1,2 +0,0 @@
-eclipse.preferences.version=1
-encoding/=UTF-8
diff --git a/examples/0303/MyAndroidTutorial/AndroidManifest.xml b/examples/0303/MyAndroidTutorial/AndroidManifest.xml
deleted file mode 100755
index a31ecc2..0000000
--- a/examples/0303/MyAndroidTutorial/AndroidManifest.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/examples/0303/MyAndroidTutorial/MyAndroidTutorial.iml b/examples/0303/MyAndroidTutorial/MyAndroidTutorial.iml
new file mode 100644
index 0000000..2a02201
--- /dev/null
+++ b/examples/0303/MyAndroidTutorial/MyAndroidTutorial.iml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0303/MyAndroidTutorial/app/.gitignore b/examples/0303/MyAndroidTutorial/app/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/examples/0303/MyAndroidTutorial/app/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/examples/0303/MyAndroidTutorial/app/app.iml b/examples/0303/MyAndroidTutorial/app/app.iml
new file mode 100644
index 0000000..c6c55c4
--- /dev/null
+++ b/examples/0303/MyAndroidTutorial/app/app.iml
@@ -0,0 +1,91 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0303/MyAndroidTutorial/app/build.gradle b/examples/0303/MyAndroidTutorial/app/build.gradle
new file mode 100644
index 0000000..b09f064
--- /dev/null
+++ b/examples/0303/MyAndroidTutorial/app/build.gradle
@@ -0,0 +1,25 @@
+apply plugin: 'com.android.application'
+
+android {
+ compileSdkVersion 21
+ buildToolsVersion "21.1.2"
+
+ defaultConfig {
+ applicationId "net.macdidi.myandroidtutorial"
+ minSdkVersion 15
+ targetSdkVersion 21
+ versionCode 1
+ versionName "1.0"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ compile fileTree(dir: 'libs', include: ['*.jar'])
+ compile 'com.android.support:appcompat-v7:21.0.3'
+}
diff --git a/examples/0303/MyAndroidTutorial/app/proguard-rules.pro b/examples/0303/MyAndroidTutorial/app/proguard-rules.pro
new file mode 100644
index 0000000..b5fa7ec
--- /dev/null
+++ b/examples/0303/MyAndroidTutorial/app/proguard-rules.pro
@@ -0,0 +1,17 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /Users/macdidi5/Library/Android/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
diff --git a/examples/0303/MyAndroidTutorial/app/src/androidTest/java/net/macdidi/myandroidtutorial/ApplicationTest.java b/examples/0303/MyAndroidTutorial/app/src/androidTest/java/net/macdidi/myandroidtutorial/ApplicationTest.java
new file mode 100644
index 0000000..2cb214e
--- /dev/null
+++ b/examples/0303/MyAndroidTutorial/app/src/androidTest/java/net/macdidi/myandroidtutorial/ApplicationTest.java
@@ -0,0 +1,13 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Application;
+import android.test.ApplicationTestCase;
+
+/**
+ * Testing Fundamentals
+ */
+public class ApplicationTest extends ApplicationTestCase {
+ public ApplicationTest() {
+ super(Application.class);
+ }
+}
\ No newline at end of file
diff --git a/examples/0303/MyAndroidTutorial/app/src/main/AndroidManifest.xml b/examples/0303/MyAndroidTutorial/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..3181c4f
--- /dev/null
+++ b/examples/0303/MyAndroidTutorial/app/src/main/AndroidManifest.xml
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0303/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/AboutActivity.java b/examples/0303/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/AboutActivity.java
new file mode 100644
index 0000000..42dddeb
--- /dev/null
+++ b/examples/0303/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/AboutActivity.java
@@ -0,0 +1,24 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.view.Window;
+
+public class AboutActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ // 取消元件的應用程式標題
+ requestWindowFeature(Window.FEATURE_NO_TITLE);
+ setContentView(R.layout.activity_about);
+ }
+
+ // 結束按鈕
+ public void clickOk(View view) {
+ // 呼叫這個方法結束Activity元件
+ finish();
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0303/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ColorActivity.java b/examples/0303/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ColorActivity.java
new file mode 100644
index 0000000..182cd55
--- /dev/null
+++ b/examples/0303/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ColorActivity.java
@@ -0,0 +1,75 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.LinearLayout;
+
+public class ColorActivity extends Activity {
+
+ private LinearLayout color_gallery;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_color);
+
+ processViews();
+
+ ColorListener listener = new ColorListener();
+
+ for (Colors c : Colors.values()) {
+ Button button = new Button(this);
+ button.setId(c.parseColor());
+ LinearLayout.LayoutParams layout =
+ new LinearLayout.LayoutParams(128, 128);
+ layout.setMargins(6, 6, 6, 6);
+ button.setLayoutParams(layout);
+ button.setBackgroundColor(c.parseColor());
+
+ button.setOnClickListener(listener);
+
+ color_gallery.addView(button);
+ }
+ }
+
+ private void processViews() {
+ color_gallery = (LinearLayout) findViewById(R.id.color_gallery);
+ }
+
+ private class ColorListener implements OnClickListener {
+
+ @Override
+ public void onClick(View view) {
+ String action = ColorActivity.this.getIntent().getAction();
+
+ // 經由設定元件啟動
+ if (action != null &&
+ action.equals("net.macdidi.myandroidtutorial.CHOOSE_COLOR")) {
+ // 建立SharedPreferences物件
+ SharedPreferences.Editor editor =
+ PreferenceManager.getDefaultSharedPreferences(
+ ColorActivity.this).edit();
+ // 儲存預設顏色
+ editor.putInt("DEFAULT_COLOR", view.getId());
+ // 寫入設定值
+ editor.commit();
+ finish();
+ }
+ // 經由新增或修改記事的元件啟動
+ else {
+ Intent result = getIntent();
+ result.putExtra("colorId", view.getId());
+ setResult(Activity.RESULT_OK, result);
+ finish();
+ }
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0303/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Colors.java b/examples/0303/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Colors.java
new file mode 100644
index 0000000..1462149
--- /dev/null
+++ b/examples/0303/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Colors.java
@@ -0,0 +1,24 @@
+package net.macdidi.myandroidtutorial;
+
+import android.graphics.Color;
+
+public enum Colors {
+
+ LIGHTGREY("#D3D3D3"), BLUE("#33B5E5"), PURPLE("#AA66CC"),
+ GREEN("#99CC00"), ORANGE("#FFBB33"), RED("#FF4444");
+
+ private String code;
+
+ private Colors(String code) {
+ this.code = code;
+ }
+
+ public String getCode() {
+ return code;
+ }
+
+ public int parseColor() {
+ return Color.parseColor(code);
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0303/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Item.java b/examples/0303/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Item.java
new file mode 100644
index 0000000..b015021
--- /dev/null
+++ b/examples/0303/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Item.java
@@ -0,0 +1,135 @@
+package net.macdidi.myandroidtutorial;
+
+import java.util.Date;
+import java.util.Locale;
+
+public class Item implements java.io.Serializable {
+
+ // 編號、日期時間、顏色、標題、內容、檔案名稱、經緯度、修改、已選擇
+ private long id;
+ private long datetime;
+ private Colors color;
+ private String title;
+ private String content;
+ private String fileName;
+ private double latitude;
+ private double longitude;
+ private long lastModify;
+ private boolean selected;
+
+ public Item() {
+ title = "";
+ content = "";
+ color = Colors.LIGHTGREY;
+ }
+
+ public Item(long id, long datetime, Colors color, String title,
+ String content, String fileName, double latitude, double longitude,
+ long lastModify) {
+ this.id = id;
+ this.datetime = datetime;
+ this.color = color;
+ this.title = title;
+ this.content = content;
+ this.fileName = fileName;
+ this.latitude = latitude;
+ this.longitude = longitude;
+ this.lastModify = lastModify;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public long getDatetime() {
+ return datetime;
+ }
+
+ // 裝置區域的日期時間
+ public String getLocaleDatetime() {
+ return String.format(Locale.getDefault(), "%tF % {
+
+ // 畫面資源編號
+ private int resource;
+ // 包裝的記事資料
+ private List- items;
+
+ public ItemAdapter(Context context, int resource, List
- items) {
+ super(context, resource, items);
+ this.resource = resource;
+ this.items = items;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ LinearLayout itemView;
+ // 讀取目前位置的記事物件
+ final Item item = getItem(position);
+
+ if (convertView == null) {
+ // 建立項目畫面元件
+ itemView = new LinearLayout(getContext());
+ String inflater = Context.LAYOUT_INFLATER_SERVICE;
+ LayoutInflater li = (LayoutInflater)
+ getContext().getSystemService(inflater);
+ li.inflate(resource, itemView, true);
+ }
+ else {
+ itemView = (LinearLayout) convertView;
+ }
+
+ // 讀取記事顏色、已選擇、標題與日期時間元件
+ RelativeLayout typeColor = (RelativeLayout) itemView.findViewById(R.id.type_color);
+ ImageView selectedItem = (ImageView) itemView.findViewById(R.id.selected_item);
+ TextView titleView = (TextView) itemView.findViewById(R.id.title_text);
+ TextView dateView = (TextView) itemView.findViewById(R.id.date_text);
+
+ // 設定記事顏色
+ GradientDrawable background = (GradientDrawable)typeColor.getBackground();
+ background.setColor(item.getColor().parseColor());
+
+ // 設定標題與日期時間
+ titleView.setText(item.getTitle());
+ dateView.setText(item.getLocaleDatetime());
+
+ // 設定是否已選擇
+ selectedItem.setVisibility(item.isSelected() ? View.VISIBLE : View.INVISIBLE);
+
+ return itemView;
+ }
+
+ // 設定指定編號的記事資料
+ public void set(int index, Item item) {
+ if (index >= 0 && index < items.size()) {
+ items.set(index, item);
+ notifyDataSetChanged();
+ }
+ }
+
+ // 讀取指定編號的記事資料
+ public Item get(int index) {
+ return items.get(index);
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0303/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemDAO.java b/examples/0303/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemDAO.java
new file mode 100644
index 0000000..f5a3f62
--- /dev/null
+++ b/examples/0303/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemDAO.java
@@ -0,0 +1,196 @@
+package net.macdidi.myandroidtutorial;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+// 資料功能類別
+public class ItemDAO {
+ // 表格名稱
+ public static final String TABLE_NAME = "item";
+
+ // 編號表格欄位名稱,固定不變
+ public static final String KEY_ID = "_id";
+
+ // 其它表格欄位名稱
+ public static final String DATETIME_COLUMN = "datetime";
+ public static final String COLOR_COLUMN = "color";
+ public static final String TITLE_COLUMN = "title";
+ public static final String CONTENT_COLUMN = "content";
+ public static final String FILENAME_COLUMN = "filename";
+ public static final String LATITUDE_COLUMN = "latitude";
+ public static final String LONGITUDE_COLUMN = "longitude";
+ public static final String LASTMODIFY_COLUMN = "lastmodify";
+
+ // 使用上面宣告的變數建立表格的SQL指令
+ public static final String CREATE_TABLE =
+ "CREATE TABLE " + TABLE_NAME + " (" +
+ KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
+ DATETIME_COLUMN + " INTEGER NOT NULL, " +
+ COLOR_COLUMN + " INTEGER NOT NULL, " +
+ TITLE_COLUMN + " TEXT NOT NULL, " +
+ CONTENT_COLUMN + " TEXT NOT NULL, " +
+ FILENAME_COLUMN + " TEXT, " +
+ LATITUDE_COLUMN + " REAL, " +
+ LONGITUDE_COLUMN + " REAL, " +
+ LASTMODIFY_COLUMN + " INTEGER)";
+
+ // 資料庫物件
+ private SQLiteDatabase db;
+
+ // 建構子,一般的應用都不需要修改
+ public ItemDAO(Context context) {
+ db = MyDBHelper.getDatabase(context);
+ }
+
+ // 關閉資料庫,一般的應用都不需要修改
+ public void close() {
+ db.close();
+ }
+
+ // 新增參數指定的物件
+ public Item insert(Item item) {
+ // 建立準備新增資料的ContentValues物件
+ ContentValues cv = new ContentValues();
+
+ // 加入ContentValues物件包裝的新增資料
+ // 第一個參數是欄位名稱, 第二個參數是欄位的資料
+ cv.put(DATETIME_COLUMN, item.getDatetime());
+ cv.put(COLOR_COLUMN, item.getColor().parseColor());
+ cv.put(TITLE_COLUMN, item.getTitle());
+ cv.put(CONTENT_COLUMN, item.getContent());
+ cv.put(FILENAME_COLUMN, item.getFileName());
+ cv.put(LATITUDE_COLUMN, item.getLatitude());
+ cv.put(LONGITUDE_COLUMN, item.getLongitude());
+ cv.put(LASTMODIFY_COLUMN, item.getLastModify());
+
+ // 新增一筆資料並取得編號
+ // 第一個參數是表格名稱
+ // 第二個參數是沒有指定欄位值的預設值
+ // 第三個參數是包裝新增資料的ContentValues物件
+ long id = db.insert(TABLE_NAME, null, cv);
+
+ // 設定編號
+ item.setId(id);
+ // 回傳結果
+ return item;
+ }
+
+ // 修改參數指定的物件
+ public boolean update(Item item) {
+ // 建立準備修改資料的ContentValues物件
+ ContentValues cv = new ContentValues();
+
+ // 加入ContentValues物件包裝的修改資料
+ // 第一個參數是欄位名稱, 第二個參數是欄位的資料
+ cv.put(DATETIME_COLUMN, item.getDatetime());
+ cv.put(COLOR_COLUMN, item.getColor().parseColor());
+ cv.put(TITLE_COLUMN, item.getTitle());
+ cv.put(CONTENT_COLUMN, item.getContent());
+ cv.put(FILENAME_COLUMN, item.getFileName());
+ cv.put(LATITUDE_COLUMN, item.getLatitude());
+ cv.put(LONGITUDE_COLUMN, item.getLongitude());
+ cv.put(LASTMODIFY_COLUMN, item.getLastModify());
+
+ // 設定修改資料的條件為編號
+ // 格式為「欄位名稱=資料」
+ String where = KEY_ID + "=" + item.getId();
+
+ // 執行修改資料並回傳修改的資料數量是否成功
+ return db.update(TABLE_NAME, cv, where, null) > 0;
+ }
+
+ // 刪除參數指定編號的資料
+ public boolean delete(long id){
+ // 設定條件為編號,格式為「欄位名稱=資料」
+ String where = KEY_ID + "=" + id;
+ // 刪除指定編號資料並回傳刪除是否成功
+ return db.delete(TABLE_NAME, where , null) > 0;
+ }
+
+ // 讀取所有記事資料
+ public List
- getAll() {
+ List
- result = new ArrayList<>();
+ Cursor cursor = db.query(
+ TABLE_NAME, null, null, null, null, null, null, null);
+
+ while (cursor.moveToNext()) {
+ result.add(getRecord(cursor));
+ }
+
+ cursor.close();
+ return result;
+ }
+
+ // 取得指定編號的資料物件
+ public Item get(long id) {
+ // 準備回傳結果用的物件
+ Item item = null;
+ // 使用編號為查詢條件
+ String where = KEY_ID + "=" + id;
+ // 執行查詢
+ Cursor result = db.query(
+ TABLE_NAME, null, where, null, null, null, null, null);
+
+ // 如果有查詢結果
+ if (result.moveToFirst()) {
+ // 讀取包裝一筆資料的物件
+ item = getRecord(result);
+ }
+
+ // 關閉Cursor物件
+ result.close();
+ // 回傳結果
+ return item;
+ }
+
+ // 把Cursor目前的資料包裝為物件
+ public Item getRecord(Cursor cursor) {
+ // 準備回傳結果用的物件
+ Item result = new Item();
+
+ result.setId(cursor.getLong(0));
+ result.setDatetime(cursor.getLong(1));
+ result.setColor(ItemActivity.getColors(cursor.getInt(2)));
+ result.setTitle(cursor.getString(3));
+ result.setContent(cursor.getString(4));
+ result.setFileName(cursor.getString(5));
+ result.setLatitude(cursor.getDouble(6));
+ result.setLongitude(cursor.getDouble(7));
+ result.setLastModify(cursor.getLong(8));
+
+ // 回傳結果
+ return result;
+ }
+
+ // 取得資料數量
+ public int getCount() {
+ int result = 0;
+ Cursor cursor = db.rawQuery("SELECT COUNT(*) FROM " + TABLE_NAME, null);
+
+ if (cursor.moveToNext()) {
+ result = cursor.getInt(0);
+ }
+
+ return result;
+ }
+
+ // 建立範例資料
+ public void sample() {
+ Item item = new Item(0, new Date().getTime(), Colors.RED, "關於Android Tutorial的事情.", "Hello content", "", 0, 0, 0);
+ Item item2 = new Item(0, new Date().getTime(), Colors.BLUE, "一隻非常可愛的小狗狗!", "她的名字叫「大熱狗」,又叫\n作「奶嘴」,是一隻非常可愛\n的小狗。", "", 25.04719, 121.516981, 0);
+ Item item3 = new Item(0, new Date().getTime(), Colors.GREEN, "一首非常好聽的音樂!", "Hello content", "", 0, 0, 0);
+ Item item4 = new Item(0, new Date().getTime(), Colors.ORANGE, "儲存在資料庫的資料", "Hello content", "", 0, 0, 0);
+
+ insert(item);
+ insert(item2);
+ insert(item3);
+ insert(item4);
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0303/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MainActivity.java b/examples/0303/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MainActivity.java
new file mode 100644
index 0000000..2a30f6a
--- /dev/null
+++ b/examples/0303/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MainActivity.java
@@ -0,0 +1,302 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.v7.app.ActionBarActivity;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import java.util.List;
+
+public class MainActivity extends ActionBarActivity {
+ private ListView item_list;
+ private TextView show_app_name;
+
+ // ListView使用的自定Adapter物件
+ private ItemAdapter itemAdapter;
+ // 儲存所有記事本的List物件
+ private List
- items;
+
+ // 選單項目物件
+ private MenuItem add_item, search_item, revert_item, share_item, delete_item;
+
+ // 已選擇項目數量
+ private int selectedCount = 0;
+
+ // 宣告資料庫功能類別欄位變數
+ private ItemDAO itemDAO;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ processViews();
+ processControllers();
+
+ // 建立資料庫物件
+ itemDAO = new ItemDAO(getApplicationContext());
+
+ // 如果資料庫是空的,就建立一些範例資料
+ // 這是為了方便測試用的,完成應用程式以後可以拿掉
+ if (itemDAO.getCount() == 0) {
+ itemDAO.sample();
+ }
+
+ // 取得所有記事資料
+ items = itemDAO.getAll();
+
+ itemAdapter = new ItemAdapter(this, R.layout.single_item, items);
+ item_list.setAdapter(itemAdapter);
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (resultCode == Activity.RESULT_OK) {
+ Item item = (Item) data.getExtras().getSerializable(
+ "net.macdidi.myandroidtutorial.Item");
+
+ if (requestCode == 0) {
+ // 新增記事資料到資料庫
+ item = itemDAO.insert(item);
+
+ items.add(item);
+ itemAdapter.notifyDataSetChanged();
+ }
+ else if (requestCode == 1) {
+ int position = data.getIntExtra("position", -1);
+
+ if (position != -1) {
+ // 修改資料庫中的記事資料
+ itemDAO.update(item);
+
+ items.set(position, item);
+ itemAdapter.notifyDataSetChanged();
+ }
+ }
+ }
+ }
+
+ private void processViews() {
+ item_list = (ListView)findViewById(R.id.item_list);
+ show_app_name = (TextView) findViewById(R.id.show_app_name);
+ }
+
+ private void processControllers() {
+
+ // 建立選單項目點擊監聽物件
+ AdapterView.OnItemClickListener itemListener = new AdapterView.OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView> parent, View view,
+ int position, long id) {
+ // 讀取選擇的記事物件
+ Item item = itemAdapter.getItem(position);
+
+ // 如果已經有勾選的項目
+ if (selectedCount > 0) {
+ // 處理是否顯示已選擇項目
+ processMenu(item);
+ // 重新設定記事項目
+ itemAdapter.set(position, item);
+ }
+ else {
+ Intent intent = new Intent(
+ "net.macdidi.myandroidtutorial.EDIT_ITEM");
+
+ // 設定記事編號與記事物件
+ intent.putExtra("position", position);
+ intent.putExtra("net.macdidi.myandroidtutorial.Item", item);
+
+ startActivityForResult(intent, 1);
+ }
+ }
+ };
+
+ // 註冊選單項目點擊監聽物件
+ item_list.setOnItemClickListener(itemListener);
+
+ // 建立記事項目長按監聽物件
+ AdapterView.OnItemLongClickListener itemLongListener = new AdapterView.OnItemLongClickListener() {
+ @Override
+ public boolean onItemLongClick(AdapterView> parent, View view,
+ int position, long id) {
+ // 讀取選擇的記事物件
+ Item item = itemAdapter.getItem(position);
+ // 處理是否顯示已選擇項目
+ processMenu(item);
+ // 重新設定記事項目
+ itemAdapter.set(position, item);
+ return true;
+ }
+ };
+
+ // 註冊記事項目長按監聽物件
+ item_list.setOnItemLongClickListener(itemLongListener);
+
+ // 建立長按監聽物件
+ View.OnLongClickListener listener = new View.OnLongClickListener() {
+
+ @Override
+ public boolean onLongClick(View view) {
+ AlertDialog.Builder dialog =
+ new AlertDialog.Builder(MainActivity.this);
+ dialog.setTitle(R.string.app_name)
+ .setMessage(R.string.about)
+ .show();
+ return false;
+ }
+
+ };
+
+ // 註冊長按監聽物件
+ show_app_name.setOnLongClickListener(listener);
+ }
+
+ // 處理是否顯示已選擇項目
+ private void processMenu(Item item) {
+ // 如果需要設定記事項目
+ if (item != null) {
+ // 設定已勾選的狀態
+ item.setSelected(!item.isSelected());
+
+ // 計算已勾選數量
+ if (item.isSelected()) {
+ selectedCount++;
+ }
+ else {
+ selectedCount--;
+ }
+ }
+
+ // 根據選擇的狀況,設定是否顯示選單項目
+ add_item.setVisible(selectedCount == 0);
+ search_item.setVisible(selectedCount == 0);
+ revert_item.setVisible(selectedCount > 0);
+ share_item.setVisible(selectedCount > 0);
+ delete_item.setVisible(selectedCount > 0);
+ }
+
+ // 載入選單資源
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ MenuInflater menuInflater = getMenuInflater();
+ menuInflater.inflate(R.menu.menu_main, menu);
+
+ // 取得選單項目物件
+ add_item = menu.findItem(R.id.add_item);
+ search_item = menu.findItem(R.id.search_item);
+ revert_item = menu.findItem(R.id.revert_item);
+ share_item = menu.findItem(R.id.share_item);
+ delete_item = menu.findItem(R.id.delete_item);
+
+ // 設定選單項目
+ processMenu(null);
+
+ return true;
+ }
+
+ // 使用者選擇所有的選單項目都會呼叫這個方法
+ public void clickMenuItem(MenuItem item) {
+ // 使用參數取得使用者選擇的選單項目元件編號
+ int itemId = item.getItemId();
+
+ // 判斷該執行什麼工作,目前還沒有加入需要執行的工作
+ switch (itemId) {
+ case R.id.search_item:
+ break;
+ // 使用者選擇新增選單項目
+ case R.id.add_item:
+ // 使用Action名稱建立啟動另一個Activity元件需要的Intent物件
+ Intent intent = new Intent("net.macdidi.myandroidtutorial.ADD_ITEM");
+ // 呼叫「startActivityForResult」,,第二個參數「0」表示執行新增
+ startActivityForResult(intent, 0);
+ break;
+ // 取消所有已勾選的項目
+ case R.id.revert_item:
+ for (int i = 0; i < itemAdapter.getCount(); i++) {
+ Item ri = itemAdapter.getItem(i);
+
+ if (ri.isSelected()) {
+ ri.setSelected(false);
+ itemAdapter.set(i, ri);
+ }
+ }
+
+ selectedCount = 0;
+ processMenu(null);
+
+ break;
+ // 刪除
+ case R.id.delete_item:
+ if (selectedCount == 0) {
+ break;
+ }
+
+ AlertDialog.Builder d = new AlertDialog.Builder(this);
+ String message = getString(R.string.delete_item);
+ d.setTitle(R.string.delete)
+ .setMessage(String.format(message, selectedCount));
+ d.setPositiveButton(android.R.string.yes,
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ // 取得最後一個元素的編號
+ int index = itemAdapter.getCount() - 1;
+
+ while (index > -1) {
+ Item item = itemAdapter.get(index);
+
+ if (item.isSelected()) {
+ itemAdapter.remove(item);
+ // 刪除資料庫中的記事資料
+ itemDAO.delete(item.getId());
+ }
+
+ index--;
+ }
+
+ itemAdapter.notifyDataSetChanged();
+ selectedCount = 0;
+ processMenu(null);
+ }
+ });
+ d.setNegativeButton(android.R.string.no, null);
+ d.show();
+
+ break;
+ case R.id.googleplus_item:
+ break;
+ case R.id.facebook_item:
+ break;
+ }
+
+ }
+
+ // 方法名稱與onClick的設定一樣,參數的型態是android.view.View
+ public void aboutApp(View view) {
+ // 建立啟動另一個Activity元件需要的Intent物件
+ // 建構式的第一個參數:「this」
+ // 建構式的第二個參數:「Activity元件類別名稱.class」
+ Intent intent = new Intent(this, AboutActivity.class);
+ // 呼叫「startActivity」,參數為一個建立好的Intent物件
+ // 這行敘述執行以後,如果沒有任何錯誤,就會啟動指定的元件
+ startActivity(intent);
+ }
+
+ // 設定
+ public void clickPreferences(MenuItem item) {
+ // 啟動設定元件
+ startActivity(new Intent(this, PrefActivity.class));
+ }
+
+}
+
+
diff --git a/examples/0303/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MyDBHelper.java b/examples/0303/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MyDBHelper.java
new file mode 100644
index 0000000..b1dc3c4
--- /dev/null
+++ b/examples/0303/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MyDBHelper.java
@@ -0,0 +1,47 @@
+package net.macdidi.myandroidtutorial;
+
+import android.content.Context;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteDatabase.CursorFactory;
+import android.database.sqlite.SQLiteOpenHelper;
+
+public class MyDBHelper extends SQLiteOpenHelper {
+
+ // 資料庫名稱
+ public static final String DATABASE_NAME = "mydata.db";
+ // 資料庫版本,資料結構改變的時候要更改這個數字,通常是加一
+ public static final int VERSION = 1;
+ // 資料庫物件,固定的欄位變數
+ private static SQLiteDatabase database;
+
+ // 建構子,在一般的應用都不需要修改
+ public MyDBHelper(Context context, String name, CursorFactory factory,
+ int version) {
+ super(context, name, factory, version);
+ }
+
+ // 需要資料庫的元件呼叫這個方法,這個方法在一般的應用都不需要修改
+ public static SQLiteDatabase getDatabase(Context context) {
+ if (database == null || !database.isOpen()) {
+ database = new MyDBHelper(context, DATABASE_NAME,
+ null, VERSION).getWritableDatabase();
+ }
+
+ return database;
+ }
+
+ @Override
+ public void onCreate(SQLiteDatabase db) {
+ // 建立應用程式需要的表格
+ db.execSQL(ItemDAO.CREATE_TABLE);
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ // 刪除原有的表格
+ db.execSQL("DROP TABLE IF EXISTS " + ItemDAO.TABLE_NAME);
+ // 呼叫onCreate建立新版的表格
+ onCreate(db);
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0303/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PrefActivity.java b/examples/0303/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PrefActivity.java
new file mode 100644
index 0000000..b2dcc4a
--- /dev/null
+++ b/examples/0303/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PrefActivity.java
@@ -0,0 +1,38 @@
+package net.macdidi.myandroidtutorial;
+
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceManager;
+
+public class PrefActivity extends PreferenceActivity {
+
+ private SharedPreferences sharedPreferences;
+ private Preference defaultColor;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ // 指定使用的設定畫面配置資源
+ addPreferencesFromResource(R.xml.mypreference);
+ defaultColor = (Preference)findPreference("DEFAULT_COLOR");
+ // 建立SharedPreferences物件
+ sharedPreferences =
+ PreferenceManager.getDefaultSharedPreferences(this);
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ // 讀取設定的預設顏色
+ int color = sharedPreferences.getInt("DEFAULT_COLOR", -1);
+
+ if (color != -1) {
+ // 設定顏色說明
+ defaultColor.setSummary(getString(R.string.default_color_summary) +
+ ": " + ItemActivity.getColors(color));
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0303/MyAndroidTutorial/res/drawable-hdpi/ic_launcher.png b/examples/0303/MyAndroidTutorial/app/src/main/res/drawable-hdpi/ic_launcher.png
old mode 100755
new mode 100644
similarity index 100%
rename from examples/0303/MyAndroidTutorial/res/drawable-hdpi/ic_launcher.png
rename to examples/0303/MyAndroidTutorial/app/src/main/res/drawable-hdpi/ic_launcher.png
diff --git a/examples/0303/MyAndroidTutorial/res/drawable-mdpi/ic_launcher.png b/examples/0303/MyAndroidTutorial/app/src/main/res/drawable-mdpi/ic_launcher.png
old mode 100755
new mode 100644
similarity index 100%
rename from examples/0303/MyAndroidTutorial/res/drawable-mdpi/ic_launcher.png
rename to examples/0303/MyAndroidTutorial/app/src/main/res/drawable-mdpi/ic_launcher.png
diff --git a/examples/0303/MyAndroidTutorial/res/drawable-xhdpi/ic_launcher.png b/examples/0303/MyAndroidTutorial/app/src/main/res/drawable-xhdpi/ic_launcher.png
old mode 100755
new mode 100644
similarity index 100%
rename from examples/0303/MyAndroidTutorial/res/drawable-xhdpi/ic_launcher.png
rename to examples/0303/MyAndroidTutorial/app/src/main/res/drawable-xhdpi/ic_launcher.png
diff --git a/examples/0303/MyAndroidTutorial/app/src/main/res/drawable-xxhdpi/ic_launcher.png b/examples/0303/MyAndroidTutorial/app/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..4df1894
Binary files /dev/null and b/examples/0303/MyAndroidTutorial/app/src/main/res/drawable-xxhdpi/ic_launcher.png differ
diff --git a/examples/0303/MyAndroidTutorial/res/drawable/alarm_icon.png b/examples/0303/MyAndroidTutorial/app/src/main/res/drawable/alarm_icon.png
old mode 100755
new mode 100644
similarity index 100%
rename from examples/0303/MyAndroidTutorial/res/drawable/alarm_icon.png
rename to examples/0303/MyAndroidTutorial/app/src/main/res/drawable/alarm_icon.png
diff --git a/examples/0303/MyAndroidTutorial/app/src/main/res/drawable/item_drawable.xml b/examples/0303/MyAndroidTutorial/app/src/main/res/drawable/item_drawable.xml
new file mode 100644
index 0000000..37607e2
--- /dev/null
+++ b/examples/0303/MyAndroidTutorial/app/src/main/res/drawable/item_drawable.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0303/MyAndroidTutorial/res/drawable/location_icon.png b/examples/0303/MyAndroidTutorial/app/src/main/res/drawable/location_icon.png
old mode 100755
new mode 100644
similarity index 100%
rename from examples/0303/MyAndroidTutorial/res/drawable/location_icon.png
rename to examples/0303/MyAndroidTutorial/app/src/main/res/drawable/location_icon.png
diff --git a/examples/0303/MyAndroidTutorial/res/drawable/record_sound_icon.png b/examples/0303/MyAndroidTutorial/app/src/main/res/drawable/record_sound_icon.png
old mode 100755
new mode 100644
similarity index 100%
rename from examples/0303/MyAndroidTutorial/res/drawable/record_sound_icon.png
rename to examples/0303/MyAndroidTutorial/app/src/main/res/drawable/record_sound_icon.png
diff --git a/examples/0303/MyAndroidTutorial/app/src/main/res/drawable/retangle_drawable.xml b/examples/0303/MyAndroidTutorial/app/src/main/res/drawable/retangle_drawable.xml
new file mode 100644
index 0000000..51d1e84
--- /dev/null
+++ b/examples/0303/MyAndroidTutorial/app/src/main/res/drawable/retangle_drawable.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0303/MyAndroidTutorial/res/drawable/select_color_icon.png b/examples/0303/MyAndroidTutorial/app/src/main/res/drawable/select_color_icon.png
old mode 100755
new mode 100644
similarity index 100%
rename from examples/0303/MyAndroidTutorial/res/drawable/select_color_icon.png
rename to examples/0303/MyAndroidTutorial/app/src/main/res/drawable/select_color_icon.png
diff --git a/examples/0303/MyAndroidTutorial/res/drawable/selected_icon.png b/examples/0303/MyAndroidTutorial/app/src/main/res/drawable/selected_icon.png
similarity index 100%
rename from examples/0303/MyAndroidTutorial/res/drawable/selected_icon.png
rename to examples/0303/MyAndroidTutorial/app/src/main/res/drawable/selected_icon.png
diff --git a/examples/0303/MyAndroidTutorial/res/drawable/take_picture_icon.png b/examples/0303/MyAndroidTutorial/app/src/main/res/drawable/take_picture_icon.png
old mode 100755
new mode 100644
similarity index 100%
rename from examples/0303/MyAndroidTutorial/res/drawable/take_picture_icon.png
rename to examples/0303/MyAndroidTutorial/app/src/main/res/drawable/take_picture_icon.png
diff --git a/examples/0303/MyAndroidTutorial/app/src/main/res/layout/activity_about.xml b/examples/0303/MyAndroidTutorial/app/src/main/res/layout/activity_about.xml
new file mode 100644
index 0000000..8e78611
--- /dev/null
+++ b/examples/0303/MyAndroidTutorial/app/src/main/res/layout/activity_about.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0303/MyAndroidTutorial/app/src/main/res/layout/activity_color.xml b/examples/0303/MyAndroidTutorial/app/src/main/res/layout/activity_color.xml
new file mode 100644
index 0000000..d25bbc5
--- /dev/null
+++ b/examples/0303/MyAndroidTutorial/app/src/main/res/layout/activity_color.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
diff --git a/examples/0303/MyAndroidTutorial/app/src/main/res/layout/activity_item.xml b/examples/0303/MyAndroidTutorial/app/src/main/res/layout/activity_item.xml
new file mode 100644
index 0000000..cb0c3bd
--- /dev/null
+++ b/examples/0303/MyAndroidTutorial/app/src/main/res/layout/activity_item.xml
@@ -0,0 +1,108 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0303/MyAndroidTutorial/app/src/main/res/layout/activity_main.xml b/examples/0303/MyAndroidTutorial/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..121511b
--- /dev/null
+++ b/examples/0303/MyAndroidTutorial/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
diff --git a/examples/0303/MyAndroidTutorial/app/src/main/res/layout/single_item.xml b/examples/0303/MyAndroidTutorial/app/src/main/res/layout/single_item.xml
new file mode 100644
index 0000000..40ddbc9
--- /dev/null
+++ b/examples/0303/MyAndroidTutorial/app/src/main/res/layout/single_item.xml
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0303/MyAndroidTutorial/app/src/main/res/menu/menu_about.xml b/examples/0303/MyAndroidTutorial/app/src/main/res/menu/menu_about.xml
new file mode 100644
index 0000000..d481100
--- /dev/null
+++ b/examples/0303/MyAndroidTutorial/app/src/main/res/menu/menu_about.xml
@@ -0,0 +1,7 @@
+
+
+
diff --git a/examples/0303/MyAndroidTutorial/app/src/main/res/menu/menu_color.xml b/examples/0303/MyAndroidTutorial/app/src/main/res/menu/menu_color.xml
new file mode 100644
index 0000000..8ff243b
--- /dev/null
+++ b/examples/0303/MyAndroidTutorial/app/src/main/res/menu/menu_color.xml
@@ -0,0 +1,7 @@
+
+
+
diff --git a/examples/0303/MyAndroidTutorial/app/src/main/res/menu/menu_item.xml b/examples/0303/MyAndroidTutorial/app/src/main/res/menu/menu_item.xml
new file mode 100644
index 0000000..cd2c9e4
--- /dev/null
+++ b/examples/0303/MyAndroidTutorial/app/src/main/res/menu/menu_item.xml
@@ -0,0 +1,7 @@
+
+
+
diff --git a/examples/0303/MyAndroidTutorial/app/src/main/res/menu/menu_main.xml b/examples/0303/MyAndroidTutorial/app/src/main/res/menu/menu_main.xml
new file mode 100644
index 0000000..0203cfa
--- /dev/null
+++ b/examples/0303/MyAndroidTutorial/app/src/main/res/menu/menu_main.xml
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
diff --git a/examples/0303/MyAndroidTutorial/app/src/main/res/values-en/strings.xml b/examples/0303/MyAndroidTutorial/app/src/main/res/values-en/strings.xml
new file mode 100644
index 0000000..c532533
--- /dev/null
+++ b/examples/0303/MyAndroidTutorial/app/src/main/res/values-en/strings.xml
@@ -0,0 +1,12 @@
+
+
+
+ MyAndroidTutorial
+ Hello world!
+ Settings
+
+ Title
+ Enter title
+ Content
+ Enter content
+
diff --git a/examples/0303/MyAndroidTutorial/app/src/main/res/values-w820dp/dimens.xml b/examples/0303/MyAndroidTutorial/app/src/main/res/values-w820dp/dimens.xml
new file mode 100644
index 0000000..63fc816
--- /dev/null
+++ b/examples/0303/MyAndroidTutorial/app/src/main/res/values-w820dp/dimens.xml
@@ -0,0 +1,6 @@
+
+
+ 64dp
+
diff --git a/examples/0303/MyAndroidTutorial/app/src/main/res/values/colors.xml b/examples/0303/MyAndroidTutorial/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..6b13c1d
--- /dev/null
+++ b/examples/0303/MyAndroidTutorial/app/src/main/res/values/colors.xml
@@ -0,0 +1,7 @@
+
+
+ #CCCCCC
+ #AAAAAA
+ #DD999999
+ #111111
+
\ No newline at end of file
diff --git a/examples/0303/MyAndroidTutorial/app/src/main/res/values/dimens.xml b/examples/0303/MyAndroidTutorial/app/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..02898ec
--- /dev/null
+++ b/examples/0303/MyAndroidTutorial/app/src/main/res/values/dimens.xml
@@ -0,0 +1,9 @@
+
+
+ 16dp
+ 16dp
+
+ 6dp
+ 24sp
+ 2dp
+
diff --git a/examples/0303/MyAndroidTutorial/app/src/main/res/values/strings.xml b/examples/0303/MyAndroidTutorial/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..50f82f1
--- /dev/null
+++ b/examples/0303/MyAndroidTutorial/app/src/main/res/values/strings.xml
@@ -0,0 +1,40 @@
+
+
+
+ MyAndroidTutorial
+ Hello world!
+ Settings
+ 標題
+ 輸入標題
+ 內容
+ 輸入內容
+ 這是Android Tutorial應用程式
+ AboutActivity
+ 版本:AndroidTutorial_0.2.4
+ ItemActivity
+ ColorActivity
+ 刪除
+ 確定要刪除 %1$d 個項目?
+ 預設的顏色
+ 新增記事的預設顏色
+
+ 預設提醒時間
+ 在指定的時間之前通知
+
+
+ - 五分鐘
+ - 十分鐘
+ - 二十分鐘
+ - 三十分鐘
+ - 六十分鐘
+
+
+
+ - 5
+ - 10
+ - 20
+ - 30
+ - 60
+
+
+
diff --git a/examples/0303/MyAndroidTutorial/app/src/main/res/values/styles.xml b/examples/0303/MyAndroidTutorial/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..766ab99
--- /dev/null
+++ b/examples/0303/MyAndroidTutorial/app/src/main/res/values/styles.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
diff --git a/examples/0303/MyAndroidTutorial/app/src/main/res/xml/mypreference.xml b/examples/0303/MyAndroidTutorial/app/src/main/res/xml/mypreference.xml
new file mode 100644
index 0000000..33e714c
--- /dev/null
+++ b/examples/0303/MyAndroidTutorial/app/src/main/res/xml/mypreference.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0303/MyAndroidTutorial/bin/AndroidManifest.xml b/examples/0303/MyAndroidTutorial/bin/AndroidManifest.xml
deleted file mode 100755
index a31ecc2..0000000
--- a/examples/0303/MyAndroidTutorial/bin/AndroidManifest.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/examples/0303/MyAndroidTutorial/bin/MyAndroidTutorial.apk b/examples/0303/MyAndroidTutorial/bin/MyAndroidTutorial.apk
deleted file mode 100644
index 8cb0740..0000000
Binary files a/examples/0303/MyAndroidTutorial/bin/MyAndroidTutorial.apk and /dev/null differ
diff --git a/examples/0303/MyAndroidTutorial/bin/classes.dex b/examples/0303/MyAndroidTutorial/bin/classes.dex
deleted file mode 100755
index 94146f6..0000000
Binary files a/examples/0303/MyAndroidTutorial/bin/classes.dex and /dev/null differ
diff --git a/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/AboutActivity.class b/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/AboutActivity.class
deleted file mode 100644
index abbf876..0000000
Binary files a/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/AboutActivity.class and /dev/null differ
diff --git a/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/BuildConfig.class b/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/BuildConfig.class
deleted file mode 100644
index 30f5623..0000000
Binary files a/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/BuildConfig.class and /dev/null differ
diff --git a/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ColorActivity$ColorListener.class b/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ColorActivity$ColorListener.class
deleted file mode 100644
index 78ad0d3..0000000
Binary files a/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ColorActivity$ColorListener.class and /dev/null differ
diff --git a/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ColorActivity.class b/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ColorActivity.class
deleted file mode 100644
index 2075635..0000000
Binary files a/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ColorActivity.class and /dev/null differ
diff --git a/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/Colors.class b/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/Colors.class
deleted file mode 100644
index 4dda566..0000000
Binary files a/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/Colors.class and /dev/null differ
diff --git a/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/Item.class b/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/Item.class
deleted file mode 100644
index 0eabdc5..0000000
Binary files a/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/Item.class and /dev/null differ
diff --git a/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ItemActivity.class b/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ItemActivity.class
deleted file mode 100644
index b7d535a..0000000
Binary files a/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ItemActivity.class and /dev/null differ
diff --git a/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ItemAdapter.class b/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ItemAdapter.class
deleted file mode 100644
index f0949d4..0000000
Binary files a/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ItemAdapter.class and /dev/null differ
diff --git a/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ItemDAO.class b/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ItemDAO.class
deleted file mode 100644
index 7e2d245..0000000
Binary files a/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ItemDAO.class and /dev/null differ
diff --git a/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$1.class b/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$1.class
deleted file mode 100644
index 983cfd6..0000000
Binary files a/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$1.class and /dev/null differ
diff --git a/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$2.class b/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$2.class
deleted file mode 100644
index ab7efab..0000000
Binary files a/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$2.class and /dev/null differ
diff --git a/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$3.class b/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$3.class
deleted file mode 100644
index 0818315..0000000
Binary files a/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$3.class and /dev/null differ
diff --git a/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$4.class b/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$4.class
deleted file mode 100644
index 0dc6594..0000000
Binary files a/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$4.class and /dev/null differ
diff --git a/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity.class b/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity.class
deleted file mode 100644
index 457041a..0000000
Binary files a/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity.class and /dev/null differ
diff --git a/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MyDBHelper.class b/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MyDBHelper.class
deleted file mode 100644
index e1e14ad..0000000
Binary files a/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MyDBHelper.class and /dev/null differ
diff --git a/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/PrefActivity.class b/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/PrefActivity.class
deleted file mode 100644
index 3989e38..0000000
Binary files a/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/PrefActivity.class and /dev/null differ
diff --git a/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$array.class b/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$array.class
deleted file mode 100644
index b9a7b7b..0000000
Binary files a/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$array.class and /dev/null differ
diff --git a/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$attr.class b/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$attr.class
deleted file mode 100644
index 01d5c1c..0000000
Binary files a/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$attr.class and /dev/null differ
diff --git a/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$color.class b/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$color.class
deleted file mode 100644
index c246f78..0000000
Binary files a/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$color.class and /dev/null differ
diff --git a/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$dimen.class b/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$dimen.class
deleted file mode 100644
index 4079bf4..0000000
Binary files a/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$dimen.class and /dev/null differ
diff --git a/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$drawable.class b/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$drawable.class
deleted file mode 100644
index 7037211..0000000
Binary files a/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$drawable.class and /dev/null differ
diff --git a/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$id.class b/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$id.class
deleted file mode 100644
index 8ac23be..0000000
Binary files a/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$id.class and /dev/null differ
diff --git a/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$layout.class b/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$layout.class
deleted file mode 100644
index cb476b8..0000000
Binary files a/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$layout.class and /dev/null differ
diff --git a/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$menu.class b/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$menu.class
deleted file mode 100644
index 5295fb4..0000000
Binary files a/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$menu.class and /dev/null differ
diff --git a/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$string.class b/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$string.class
deleted file mode 100644
index 3cda30a..0000000
Binary files a/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$string.class and /dev/null differ
diff --git a/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$style.class b/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$style.class
deleted file mode 100644
index f502898..0000000
Binary files a/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$style.class and /dev/null differ
diff --git a/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$xml.class b/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$xml.class
deleted file mode 100644
index 7dd8390..0000000
Binary files a/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$xml.class and /dev/null differ
diff --git a/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R.class b/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R.class
deleted file mode 100644
index e09c2b9..0000000
Binary files a/examples/0303/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R.class and /dev/null differ
diff --git a/examples/0303/MyAndroidTutorial/bin/dexedLibs/android-support-v4-9b1d5d28bf7d59a4e392b3d4f78c1f13.jar b/examples/0303/MyAndroidTutorial/bin/dexedLibs/android-support-v4-9b1d5d28bf7d59a4e392b3d4f78c1f13.jar
deleted file mode 100755
index 2f330c0..0000000
Binary files a/examples/0303/MyAndroidTutorial/bin/dexedLibs/android-support-v4-9b1d5d28bf7d59a4e392b3d4f78c1f13.jar and /dev/null differ
diff --git a/examples/0303/MyAndroidTutorial/bin/jarlist.cache b/examples/0303/MyAndroidTutorial/bin/jarlist.cache
deleted file mode 100755
index 0565465..0000000
--- a/examples/0303/MyAndroidTutorial/bin/jarlist.cache
+++ /dev/null
@@ -1,3 +0,0 @@
-# cache for current jar dependency. DO NOT EDIT.
-# format is
-# Encoding is UTF-8
diff --git a/examples/0303/MyAndroidTutorial/bin/res/crunch/drawable-hdpi/ic_launcher.png b/examples/0303/MyAndroidTutorial/bin/res/crunch/drawable-hdpi/ic_launcher.png
deleted file mode 100755
index bcfa058..0000000
Binary files a/examples/0303/MyAndroidTutorial/bin/res/crunch/drawable-hdpi/ic_launcher.png and /dev/null differ
diff --git a/examples/0303/MyAndroidTutorial/bin/res/crunch/drawable-mdpi/ic_launcher.png b/examples/0303/MyAndroidTutorial/bin/res/crunch/drawable-mdpi/ic_launcher.png
deleted file mode 100755
index 85848ff..0000000
Binary files a/examples/0303/MyAndroidTutorial/bin/res/crunch/drawable-mdpi/ic_launcher.png and /dev/null differ
diff --git a/examples/0303/MyAndroidTutorial/bin/res/crunch/drawable-xhdpi/ic_launcher.png b/examples/0303/MyAndroidTutorial/bin/res/crunch/drawable-xhdpi/ic_launcher.png
deleted file mode 100755
index 916901e..0000000
Binary files a/examples/0303/MyAndroidTutorial/bin/res/crunch/drawable-xhdpi/ic_launcher.png and /dev/null differ
diff --git a/examples/0303/MyAndroidTutorial/bin/res/crunch/drawable/alarm_icon.png b/examples/0303/MyAndroidTutorial/bin/res/crunch/drawable/alarm_icon.png
deleted file mode 100755
index ebeae27..0000000
Binary files a/examples/0303/MyAndroidTutorial/bin/res/crunch/drawable/alarm_icon.png and /dev/null differ
diff --git a/examples/0303/MyAndroidTutorial/bin/res/crunch/drawable/location_icon.png b/examples/0303/MyAndroidTutorial/bin/res/crunch/drawable/location_icon.png
deleted file mode 100755
index 6897a97..0000000
Binary files a/examples/0303/MyAndroidTutorial/bin/res/crunch/drawable/location_icon.png and /dev/null differ
diff --git a/examples/0303/MyAndroidTutorial/bin/res/crunch/drawable/record_sound_icon.png b/examples/0303/MyAndroidTutorial/bin/res/crunch/drawable/record_sound_icon.png
deleted file mode 100755
index 6fe2060..0000000
Binary files a/examples/0303/MyAndroidTutorial/bin/res/crunch/drawable/record_sound_icon.png and /dev/null differ
diff --git a/examples/0303/MyAndroidTutorial/bin/res/crunch/drawable/select_color_icon.png b/examples/0303/MyAndroidTutorial/bin/res/crunch/drawable/select_color_icon.png
deleted file mode 100755
index 4270ec5..0000000
Binary files a/examples/0303/MyAndroidTutorial/bin/res/crunch/drawable/select_color_icon.png and /dev/null differ
diff --git a/examples/0303/MyAndroidTutorial/bin/res/crunch/drawable/selected_icon.png b/examples/0303/MyAndroidTutorial/bin/res/crunch/drawable/selected_icon.png
deleted file mode 100755
index 982ddee..0000000
Binary files a/examples/0303/MyAndroidTutorial/bin/res/crunch/drawable/selected_icon.png and /dev/null differ
diff --git a/examples/0303/MyAndroidTutorial/bin/res/crunch/drawable/take_picture_icon.png b/examples/0303/MyAndroidTutorial/bin/res/crunch/drawable/take_picture_icon.png
deleted file mode 100755
index c812e2f..0000000
Binary files a/examples/0303/MyAndroidTutorial/bin/res/crunch/drawable/take_picture_icon.png and /dev/null differ
diff --git a/examples/0303/MyAndroidTutorial/bin/resources.ap_ b/examples/0303/MyAndroidTutorial/bin/resources.ap_
deleted file mode 100644
index e01ad50..0000000
Binary files a/examples/0303/MyAndroidTutorial/bin/resources.ap_ and /dev/null differ
diff --git a/examples/0303/MyAndroidTutorial/build.gradle b/examples/0303/MyAndroidTutorial/build.gradle
new file mode 100644
index 0000000..6356aab
--- /dev/null
+++ b/examples/0303/MyAndroidTutorial/build.gradle
@@ -0,0 +1,19 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+ repositories {
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:1.0.0'
+
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+}
+
+allprojects {
+ repositories {
+ jcenter()
+ }
+}
diff --git a/examples/0303/MyAndroidTutorial/gen/net/macdidi/myandroidtutorial/BuildConfig.java b/examples/0303/MyAndroidTutorial/gen/net/macdidi/myandroidtutorial/BuildConfig.java
deleted file mode 100755
index 5d44ea9..0000000
--- a/examples/0303/MyAndroidTutorial/gen/net/macdidi/myandroidtutorial/BuildConfig.java
+++ /dev/null
@@ -1,6 +0,0 @@
-/** Automatically generated file. DO NOT MODIFY */
-package net.macdidi.myandroidtutorial;
-
-public final class BuildConfig {
- public final static boolean DEBUG = true;
-}
\ No newline at end of file
diff --git a/examples/0303/MyAndroidTutorial/gen/net/macdidi/myandroidtutorial/R.java b/examples/0303/MyAndroidTutorial/gen/net/macdidi/myandroidtutorial/R.java
deleted file mode 100755
index c7b4771..0000000
--- a/examples/0303/MyAndroidTutorial/gen/net/macdidi/myandroidtutorial/R.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/* AUTO-GENERATED FILE. DO NOT MODIFY.
- *
- * This class was automatically generated by the
- * aapt tool from the resource data it found. It
- * should not be modified by hand.
- */
-
-package net.macdidi.myandroidtutorial;
-
-public final class R {
- public static final class array {
- public static final int notify_minutes_array=0x7f080000;
- public static final int notify_minutes_value_array=0x7f080001;
- }
- public static final class attr {
- }
- public static final class color {
- public static final int dark_text=0x7f050003;
- public static final int divider_color=0x7f050002;
- public static final int grey=0x7f050001;
- public static final int light_grey=0x7f050000;
- }
- public static final class dimen {
- public static final int default_margin=0x7f060001;
- public static final int default_padding=0x7f060000;
- public static final int title_txt_size=0x7f060002;
- }
- public static final class drawable {
- public static final int alarm_icon=0x7f020000;
- public static final int ic_launcher=0x7f020001;
- public static final int item_drawable=0x7f020002;
- public static final int location_icon=0x7f020003;
- public static final int record_sound_icon=0x7f020004;
- public static final int retangle_drawable=0x7f020005;
- public static final int select_color_icon=0x7f020006;
- public static final int selected_icon=0x7f020007;
- public static final int take_picture_icon=0x7f020008;
- }
- public static final class id {
- public static final int add_item=0x7f0b0010;
- public static final int cancel_item=0x7f0b0008;
- public static final int color_gallery=0x7f0b0000;
- public static final int content_text=0x7f0b0002;
- public static final int date_text=0x7f0b000e;
- public static final int delete_item=0x7f0b0012;
- public static final int facebook_item=0x7f0b0015;
- public static final int googleplus_item=0x7f0b0014;
- public static final int item_list=0x7f0b000a;
- public static final int ok_teim=0x7f0b0009;
- public static final int record_sound=0x7f0b0004;
- public static final int revert_item=0x7f0b0011;
- public static final int search_item=0x7f0b000f;
- public static final int select_color=0x7f0b0007;
- public static final int selected_item=0x7f0b000d;
- public static final int set_alarm=0x7f0b0006;
- public static final int set_location=0x7f0b0005;
- public static final int share_item=0x7f0b0013;
- public static final int show_app_name=0x7f0b000b;
- public static final int take_picture=0x7f0b0003;
- public static final int title_text=0x7f0b0001;
- public static final int type_color=0x7f0b000c;
- }
- public static final class layout {
- public static final int activity_about=0x7f030000;
- public static final int activity_color=0x7f030001;
- public static final int activity_item=0x7f030002;
- public static final int activity_main=0x7f030003;
- public static final int single_item=0x7f030004;
- }
- public static final class menu {
- public static final int main_menu=0x7f0a0000;
- }
- public static final class string {
- public static final int about=0x7f070007;
- public static final int app_name=0x7f070000;
- public static final int content=0x7f070005;
- public static final int default_color=0x7f07000b;
- public static final int default_color_summary=0x7f07000c;
- public static final int default_notify=0x7f07000d;
- public static final int default_notify_summary=0x7f07000e;
- public static final int delete=0x7f070009;
- public static final int delete_item=0x7f07000a;
- public static final int enter_content=0x7f070006;
- public static final int enter_title=0x7f070004;
- public static final int hello_world=0x7f07000f;
- public static final int title=0x7f070003;
- public static final int title_activity_color=0x7f070002;
- public static final int title_activity_main=0x7f070001;
- public static final int version=0x7f070008;
- }
- public static final class style {
- /**
- Base application theme, dependent on API level. This theme is replaced
- by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
-
-
- Theme customizations available in newer API levels can go in
- res/values-vXX/styles.xml, while customizations related to
- backward-compatibility can go here.
-
-
- Base application theme for API 11+. This theme completely replaces
- AppBaseTheme from res/values/styles.xml on API 11+ devices.
-
- API 11 theme customizations can go here.
-
- Base application theme for API 14+. This theme completely replaces
- AppBaseTheme from BOTH res/values/styles.xml and
- res/values-v11/styles.xml on API 14+ devices.
-
- API 14 theme customizations can go here.
- */
- public static final int AppBaseTheme=0x7f090000;
- /** Application theme.
- All customizations that are NOT specific to a particular API-level can go here.
- */
- public static final int AppTheme=0x7f090001;
- }
- public static final class xml {
- public static final int mypreference=0x7f040000;
- }
-}
diff --git a/examples/0303/MyAndroidTutorial/gradle.properties b/examples/0303/MyAndroidTutorial/gradle.properties
new file mode 100644
index 0000000..1d3591c
--- /dev/null
+++ b/examples/0303/MyAndroidTutorial/gradle.properties
@@ -0,0 +1,18 @@
+# Project-wide Gradle settings.
+
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+# Default value: -Xmx10248m -XX:MaxPermSize=256m
+# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
+
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
\ No newline at end of file
diff --git a/examples/0303/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.jar b/examples/0303/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
Binary files /dev/null and b/examples/0303/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/examples/0303/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.properties b/examples/0303/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..0c71e76
--- /dev/null
+++ b/examples/0303/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
diff --git a/examples/0303/MyAndroidTutorial/gradlew b/examples/0303/MyAndroidTutorial/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/examples/0303/MyAndroidTutorial/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/examples/0303/MyAndroidTutorial/gradlew.bat b/examples/0303/MyAndroidTutorial/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/examples/0303/MyAndroidTutorial/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/examples/0303/MyAndroidTutorial/libs/android-support-v4.jar b/examples/0303/MyAndroidTutorial/libs/android-support-v4.jar
deleted file mode 100755
index 187bdf4..0000000
Binary files a/examples/0303/MyAndroidTutorial/libs/android-support-v4.jar and /dev/null differ
diff --git a/examples/0303/MyAndroidTutorial/proguard-project.txt b/examples/0303/MyAndroidTutorial/proguard-project.txt
deleted file mode 100755
index f2fe155..0000000
--- a/examples/0303/MyAndroidTutorial/proguard-project.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-# To enable ProGuard in your project, edit project.properties
-# to define the proguard.config property as described in that file.
-#
-# Add project specific ProGuard rules here.
-# By default, the flags in this file are appended to flags specified
-# in ${sdk.dir}/tools/proguard/proguard-android.txt
-# You can edit the include path and order by changing the ProGuard
-# include property in project.properties.
-#
-# For more details, see
-# http://developer.android.com/guide/developing/tools/proguard.html
-
-# Add any project specific keep options here:
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-# public *;
-#}
diff --git a/examples/0303/MyAndroidTutorial/project.properties b/examples/0303/MyAndroidTutorial/project.properties
deleted file mode 100755
index 4ab1256..0000000
--- a/examples/0303/MyAndroidTutorial/project.properties
+++ /dev/null
@@ -1,14 +0,0 @@
-# This file is automatically generated by Android Tools.
-# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
-#
-# This file must be checked in Version Control Systems.
-#
-# To customize properties used by the Ant build system edit
-# "ant.properties", and override values to adapt the script to your
-# project structure.
-#
-# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
-#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
-
-# Project target.
-target=android-19
diff --git a/examples/0303/MyAndroidTutorial/res/drawable/item_drawable.xml b/examples/0303/MyAndroidTutorial/res/drawable/item_drawable.xml
deleted file mode 100755
index ecc4011..0000000
--- a/examples/0303/MyAndroidTutorial/res/drawable/item_drawable.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/examples/0303/MyAndroidTutorial/res/drawable/retangle_drawable.xml b/examples/0303/MyAndroidTutorial/res/drawable/retangle_drawable.xml
deleted file mode 100755
index e195342..0000000
--- a/examples/0303/MyAndroidTutorial/res/drawable/retangle_drawable.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/examples/0303/MyAndroidTutorial/res/layout/activity_about.xml b/examples/0303/MyAndroidTutorial/res/layout/activity_about.xml
deleted file mode 100755
index 738fe98..0000000
--- a/examples/0303/MyAndroidTutorial/res/layout/activity_about.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/examples/0303/MyAndroidTutorial/res/layout/activity_color.xml b/examples/0303/MyAndroidTutorial/res/layout/activity_color.xml
deleted file mode 100755
index 693a9d4..0000000
--- a/examples/0303/MyAndroidTutorial/res/layout/activity_color.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
-
-
diff --git a/examples/0303/MyAndroidTutorial/res/layout/activity_item.xml b/examples/0303/MyAndroidTutorial/res/layout/activity_item.xml
deleted file mode 100755
index a12c44c..0000000
--- a/examples/0303/MyAndroidTutorial/res/layout/activity_item.xml
+++ /dev/null
@@ -1,94 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/examples/0303/MyAndroidTutorial/res/layout/activity_main.xml b/examples/0303/MyAndroidTutorial/res/layout/activity_main.xml
deleted file mode 100755
index 418c34b..0000000
--- a/examples/0303/MyAndroidTutorial/res/layout/activity_main.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
diff --git a/examples/0303/MyAndroidTutorial/res/layout/single_item.xml b/examples/0303/MyAndroidTutorial/res/layout/single_item.xml
deleted file mode 100755
index c3b579c..0000000
--- a/examples/0303/MyAndroidTutorial/res/layout/single_item.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/examples/0303/MyAndroidTutorial/res/menu/main_menu.xml b/examples/0303/MyAndroidTutorial/res/menu/main_menu.xml
deleted file mode 100755
index dadd8fa..0000000
--- a/examples/0303/MyAndroidTutorial/res/menu/main_menu.xml
+++ /dev/null
@@ -1,51 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/examples/0303/MyAndroidTutorial/res/values-en/strings.xml b/examples/0303/MyAndroidTutorial/res/values-en/strings.xml
deleted file mode 100755
index 34f4fed..0000000
--- a/examples/0303/MyAndroidTutorial/res/values-en/strings.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
- MyAndroidTutorial
- MainActivity
- Hello world!
-
- Title
- Enter title
- Content
- Enter content
-
-
diff --git a/examples/0303/MyAndroidTutorial/res/values-v11/styles.xml b/examples/0303/MyAndroidTutorial/res/values-v11/styles.xml
deleted file mode 100755
index 3c02242..0000000
--- a/examples/0303/MyAndroidTutorial/res/values-v11/styles.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
diff --git a/examples/0303/MyAndroidTutorial/res/values-v14/styles.xml b/examples/0303/MyAndroidTutorial/res/values-v14/styles.xml
deleted file mode 100755
index a91fd03..0000000
--- a/examples/0303/MyAndroidTutorial/res/values-v14/styles.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
diff --git a/examples/0303/MyAndroidTutorial/res/values/colors.xml b/examples/0303/MyAndroidTutorial/res/values/colors.xml
deleted file mode 100755
index c63ec2d..0000000
--- a/examples/0303/MyAndroidTutorial/res/values/colors.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
- #CCCCCC
- #AAAAAA
- #DDCCCCCC
- #111111
-
diff --git a/examples/0303/MyAndroidTutorial/res/values/dimens.xml b/examples/0303/MyAndroidTutorial/res/values/dimens.xml
deleted file mode 100755
index fb03071..0000000
--- a/examples/0303/MyAndroidTutorial/res/values/dimens.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
- 6dp
- 2dp
- 24sp
-
diff --git a/examples/0303/MyAndroidTutorial/res/values/strings.xml b/examples/0303/MyAndroidTutorial/res/values/strings.xml
deleted file mode 100755
index 53d96b7..0000000
--- a/examples/0303/MyAndroidTutorial/res/values/strings.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-
-
-
- MyAndroidTutorial
- MyAndroidTutorial
- 設定顏色
- 標題
- 輸入標題
- 內容
- 輸入內容
- 這是Android Tutorial應用程式
- 版本:AndroidTutorial_0.2.4
-
- 刪除
- 確定要刪除 %1$d 個項目?
-
- 預設的顏色
- 新增記事的預設顏色
-
- 預設提醒時間
- 在指定的時間之前通知
-
-
- - 五分鐘
- - 十分鐘
- - 二十分鐘
- - 三十分鐘
- - 六十分鐘
-
-
-
- - 5
- - 10
- - 20
- - 30
- - 60
-
-
-
diff --git a/examples/0303/MyAndroidTutorial/res/values/styles.xml b/examples/0303/MyAndroidTutorial/res/values/styles.xml
deleted file mode 100755
index 6ce89c7..0000000
--- a/examples/0303/MyAndroidTutorial/res/values/styles.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
-
-
-
-
-
-
diff --git a/examples/0303/MyAndroidTutorial/res/xml/mypreference.xml b/examples/0303/MyAndroidTutorial/res/xml/mypreference.xml
deleted file mode 100644
index 4cd7f5e..0000000
--- a/examples/0303/MyAndroidTutorial/res/xml/mypreference.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/examples/0303/MyAndroidTutorial/settings.gradle b/examples/0303/MyAndroidTutorial/settings.gradle
new file mode 100644
index 0000000..e7b4def
--- /dev/null
+++ b/examples/0303/MyAndroidTutorial/settings.gradle
@@ -0,0 +1 @@
+include ':app'
diff --git a/examples/0303/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/AboutActivity.java b/examples/0303/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/AboutActivity.java
deleted file mode 100755
index 111efc5..0000000
--- a/examples/0303/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/AboutActivity.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package net.macdidi.myandroidtutorial;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.view.View;
-import android.view.Window;
-
-public class AboutActivity extends Activity {
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- // 取消元件的應用程式標題
- requestWindowFeature(Window.FEATURE_NO_TITLE);
- setContentView(R.layout.activity_about);
- }
-
- // 結束按鈕
- public void clickOk(View view) {
- // 呼叫這個方法結束Activity元件
- finish();
- }
-
-}
diff --git a/examples/0303/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/ColorActivity.java b/examples/0303/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/ColorActivity.java
deleted file mode 100755
index 0eafb85..0000000
--- a/examples/0303/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/ColorActivity.java
+++ /dev/null
@@ -1,75 +0,0 @@
-package net.macdidi.myandroidtutorial;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.os.Bundle;
-import android.preference.PreferenceManager;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.widget.Button;
-import android.widget.LinearLayout;
-
-public class ColorActivity extends Activity {
-
- private LinearLayout color_gallery;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_color);
-
- processViews();
-
- ColorListener listener = new ColorListener();
-
- for (Colors c : Colors.values()) {
- Button button = new Button(this);
- button.setId(c.parseColor());
- LinearLayout.LayoutParams layout =
- new LinearLayout.LayoutParams(128, 128);
- layout.setMargins(6, 6, 6, 6);
- button.setLayoutParams(layout);
- button.setBackgroundColor(c.parseColor());
-
- button.setOnClickListener(listener);
-
- color_gallery.addView(button);
- }
- }
-
- private void processViews() {
- color_gallery = (LinearLayout) findViewById(R.id.color_gallery);
- }
-
- private class ColorListener implements OnClickListener {
-
- @Override
- public void onClick(View view) {
- String action = ColorActivity.this.getIntent().getAction();
-
- // 經由設定元件啟動
- if (action != null &&
- action.equals("net.macdidi.myandroidtutorial.CHOOSE_COLOR")) {
- // 建立SharedPreferences物件
- SharedPreferences.Editor editor =
- PreferenceManager.getDefaultSharedPreferences(
- ColorActivity.this).edit();
- // 儲存預設顏色
- editor.putInt("DEFAULT_COLOR", view.getId());
- // 寫入設定值
- editor.commit();
- finish();
- }
- // 經由新增或修改記事的元件啟動
- else {
- Intent result = getIntent();
- result.putExtra("colorId", view.getId());
- setResult(Activity.RESULT_OK, result);
- finish();
- }
- }
-
- }
-
-}
diff --git a/examples/0303/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/Colors.java b/examples/0303/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/Colors.java
deleted file mode 100755
index a3eb9d4..0000000
--- a/examples/0303/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/Colors.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package net.macdidi.myandroidtutorial;
-
-import android.graphics.Color;
-
-public enum Colors {
-
- LIGHTGREY("#D3D3D3"), BLUE("#33B5E5"), PURPLE("#AA66CC"),
- GREEN("#99CC00"), ORANGE("#FFBB33"), RED("#FF4444");
-
- private String code;
-
- private Colors(String code) {
- this.code = code;
- }
-
- public String getCode() {
- return code;
- }
-
- public int parseColor() {
- return Color.parseColor(code);
- }
-
-}
diff --git a/examples/0303/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/Item.java b/examples/0303/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/Item.java
deleted file mode 100755
index 4724be5..0000000
--- a/examples/0303/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/Item.java
+++ /dev/null
@@ -1,132 +0,0 @@
-package net.macdidi.myandroidtutorial;
-
-import java.util.Date;
-import java.util.Locale;
-
-public class Item implements java.io.Serializable {
-
- // 編號、日期時間、顏色、標題、內容、檔案名稱、經緯度、修改、已選擇
- private long id;
- private long datetime;
- private Colors color;
- private String title;
- private String content;
- private String fileName;
- private double latitude;
- private double longitude;
- private long lastModify;
- private boolean selected;
-
- public Item() {
- title = "";
- content = "";
- color = Colors.LIGHTGREY;
- }
-
- public Item(long id, long datetime, Colors color, String title,
- String content, String fileName, double latitude, double longitude,
- long lastModify) {
- this.id = id;
- this.datetime = datetime;
- this.color = color;
- this.title = title;
- this.content = content;
- this.fileName = fileName;
- this.latitude = latitude;
- this.longitude = longitude;
- this.lastModify = lastModify;
- }
-
- public long getId() {
- return id;
- }
-
- public void setId(long id) {
- this.id = id;
- }
-
- public long getDatetime() {
- return datetime;
- }
-
- public String getLocaleDatetime() {
- return String.format(Locale.getDefault(), "%tF % {
-
- // 畫面資源編號
- private int resource;
- // 包裝的記事資料
- private List- items;
-
- public ItemAdapter(Context context, int resource, List
- items) {
- super(context, resource, items);
- this.resource = resource;
- this.items = items;
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- LinearLayout itemView;
- // 讀取目前位置的記事物件
- final Item item = getItem(position);
-
- if (convertView == null) {
- // 建立項目畫面元件
- itemView = new LinearLayout(getContext());
- String inflater = Context.LAYOUT_INFLATER_SERVICE;
- LayoutInflater li = (LayoutInflater)
- getContext().getSystemService(inflater);
- li.inflate(resource, itemView, true);
- }
- else {
- itemView = (LinearLayout) convertView;
- }
-
- // 讀取記事顏色、已選擇、標題與日期時間元件
- RelativeLayout typeColor = (RelativeLayout) itemView.findViewById(R.id.type_color);
- ImageView selectedItem = (ImageView) itemView.findViewById(R.id.selected_item);
- TextView titleView = (TextView) itemView.findViewById(R.id.title_text);
- TextView dateView = (TextView) itemView.findViewById(R.id.date_text);
-
- // 設定記事顏色
- GradientDrawable background = (GradientDrawable)typeColor.getBackground();
- background.setColor(item.getColor().parseColor());
-
- // 設定標題與日期時間
- titleView.setText(item.getTitle());
- dateView.setText(item.getLocaleDatetime());
-
- // 設定是否已選擇
- selectedItem.setVisibility(item.isSelected() ? View.VISIBLE : View.INVISIBLE);
-
- return itemView;
- }
-
- // 設定指定編號的記事資料
- public void set(int index, Item item) {
- if (index >= 0 && index < items.size()) {
- items.set(index, item);
- notifyDataSetChanged();
- }
- }
-
- // 讀取指定編號的記事資料
- public Item get(int index) {
- return items.get(index);
- }
-
-}
diff --git a/examples/0303/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/ItemDAO.java b/examples/0303/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/ItemDAO.java
deleted file mode 100644
index 3ac59c0..0000000
--- a/examples/0303/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/ItemDAO.java
+++ /dev/null
@@ -1,196 +0,0 @@
-package net.macdidi.myandroidtutorial;
-
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
-
-// 資料功能類別
-public class ItemDAO {
- // 表格名稱
- public static final String TABLE_NAME = "item";
-
- // 編號表格欄位名稱,固定不變
- public static final String KEY_ID = "_id";
-
- // 其它表格欄位名稱
- public static final String DATETIME_COLUMN = "datetime";
- public static final String COLOR_COLUMN = "color";
- public static final String TITLE_COLUMN = "title";
- public static final String CONTENT_COLUMN = "content";
- public static final String FILENAME_COLUMN = "filename";
- public static final String LATITUDE_COLUMN = "latitude";
- public static final String LONGITUDE_COLUMN = "longitude";
- public static final String LASTMODIFY_COLUMN = "lastmodify";
-
- // 使用上面宣告的變數建立表格的SQL指令
- public static final String CREATE_TABLE =
- "CREATE TABLE " + TABLE_NAME + " (" +
- KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
- DATETIME_COLUMN + " INTEGER NOT NULL, " +
- COLOR_COLUMN + " INTEGER NOT NULL, " +
- TITLE_COLUMN + " TEXT NOT NULL, " +
- CONTENT_COLUMN + " TEXT NOT NULL, " +
- FILENAME_COLUMN + " TEXT, " +
- LATITUDE_COLUMN + " REAL, " +
- LONGITUDE_COLUMN + " REAL, " +
- LASTMODIFY_COLUMN + " INTEGER)";
-
- // 資料庫物件
- private SQLiteDatabase db;
-
- // 建構子,一般的應用都不需要修改
- public ItemDAO(Context context) {
- db = MyDBHelper.getDatabase(context);
- }
-
- // 關閉資料庫,一般的應用都不需要修改
- public void close() {
- db.close();
- }
-
- // 新增參數指定的物件
- public Item insert(Item item) {
- // 建立準備新增資料的ContentValues物件
- ContentValues cv = new ContentValues();
-
- // 加入ContentValues物件包裝的新增資料
- // 第一個參數是欄位名稱, 第二個參數是欄位的資料
- cv.put(DATETIME_COLUMN, item.getDatetime());
- cv.put(COLOR_COLUMN, item.getColor().parseColor());
- cv.put(TITLE_COLUMN, item.getTitle());
- cv.put(CONTENT_COLUMN, item.getContent());
- cv.put(FILENAME_COLUMN, item.getFileName());
- cv.put(LATITUDE_COLUMN, item.getLatitude());
- cv.put(LONGITUDE_COLUMN, item.getLongitude());
- cv.put(LASTMODIFY_COLUMN, item.getLastModify());
-
- // 新增一筆資料並取得編號
- // 第一個參數是表格名稱
- // 第二個參數是沒有指定欄位值的預設值
- // 第三個參數是包裝新增資料的ContentValues物件
- long id = db.insert(TABLE_NAME, null, cv);
-
- // 設定編號
- item.setId(id);
- // 回傳結果
- return item;
- }
-
- // 修改參數指定的物件
- public boolean update(Item item) {
- // 建立準備修改資料的ContentValues物件
- ContentValues cv = new ContentValues();
-
- // 加入ContentValues物件包裝的修改資料
- // 第一個參數是欄位名稱, 第二個參數是欄位的資料
- cv.put(DATETIME_COLUMN, item.getDatetime());
- cv.put(COLOR_COLUMN, item.getColor().parseColor());
- cv.put(TITLE_COLUMN, item.getTitle());
- cv.put(CONTENT_COLUMN, item.getContent());
- cv.put(FILENAME_COLUMN, item.getFileName());
- cv.put(LATITUDE_COLUMN, item.getLatitude());
- cv.put(LONGITUDE_COLUMN, item.getLongitude());
- cv.put(LASTMODIFY_COLUMN, item.getLastModify());
-
- // 設定修改資料的條件為編號
- // 格式為「欄位名稱=資料」
- String where = KEY_ID + "=" + item.getId();
-
- // 執行修改資料並回傳修改的資料數量是否成功
- return db.update(TABLE_NAME, cv, where, null) > 0;
- }
-
- // 刪除參數指定編號的資料
- public boolean delete(long id){
- // 設定條件為編號,格式為「欄位名稱=資料」
- String where = KEY_ID + "=" + id;
- // 刪除指定編號資料並回傳刪除是否成功
- return db.delete(TABLE_NAME, where , null) > 0;
- }
-
- // 讀取所有記事資料
- public List
- getAll() {
- List
- result = new ArrayList<>();
- Cursor cursor = db.query(
- TABLE_NAME, null, null, null, null, null, null, null);
-
- while (cursor.moveToNext()) {
- result.add(getRecord(cursor));
- }
-
- cursor.close();
- return result;
- }
-
- // 取得指定編號的資料物件
- public Item get(long id) {
- // 準備回傳結果用的物件
- Item item = null;
- // 使用編號為查詢條件
- String where = KEY_ID + "=" + id;
- // 執行查詢
- Cursor result = db.query(
- TABLE_NAME, null, where, null, null, null, null, null);
-
- // 如果有查詢結果
- if (result.moveToFirst()) {
- // 讀取包裝一筆資料的物件
- item = getRecord(result);
- }
-
- // 關閉Cursor物件
- result.close();
- // 回傳結果
- return item;
- }
-
- // 把Cursor目前的資料包裝為物件
- public Item getRecord(Cursor cursor) {
- // 準備回傳結果用的物件
- Item result = new Item();
-
- result.setId(cursor.getLong(0));
- result.setDatetime(cursor.getLong(1));
- result.setColor(ItemActivity.getColors(cursor.getInt(2)));
- result.setTitle(cursor.getString(3));
- result.setContent(cursor.getString(4));
- result.setFileName(cursor.getString(5));
- result.setLatitude(cursor.getDouble(6));
- result.setLongitude(cursor.getDouble(7));
- result.setLastModify(cursor.getLong(8));
-
- // 回傳結果
- return result;
- }
-
- // 取得資料數量
- public int getCount() {
- int result = 0;
- Cursor cursor = db.rawQuery("SELECT COUNT(*) FROM " + TABLE_NAME, null);
-
- if (cursor.moveToNext()) {
- result = cursor.getInt(0);
- }
-
- return result;
- }
-
- // 建立範例資料
- public void sample() {
- Item item = new Item(0, new Date().getTime(), Colors.RED, "關於Android Tutorial的事情.", "Hello content", "", 0, 0, 0);
- Item item2 = new Item(0, new Date().getTime(), Colors.BLUE, "一隻非常可愛的小狗狗!", "她的名字叫「大熱狗」,又叫\n作「奶嘴」,是一隻非常可愛\n的小狗。", "", 25.04719, 121.516981, 0);
- Item item3 = new Item(0, new Date().getTime(), Colors.GREEN, "一首非常好聽的音樂!", "Hello content", "", 0, 0, 0);
- Item item4 = new Item(0, new Date().getTime(), Colors.ORANGE, "儲存在資料庫的資料", "Hello content", "", 0, 0, 0);
-
- insert(item);
- insert(item2);
- insert(item3);
- insert(item4);
- }
-
-}
diff --git a/examples/0303/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/MainActivity.java b/examples/0303/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/MainActivity.java
deleted file mode 100755
index 8c644c9..0000000
--- a/examples/0303/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/MainActivity.java
+++ /dev/null
@@ -1,254 +0,0 @@
-package net.macdidi.myandroidtutorial;
-
-import java.util.List;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.os.Bundle;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.View.OnLongClickListener;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemClickListener;
-import android.widget.AdapterView.OnItemLongClickListener;
-import android.widget.ListView;
-import android.widget.TextView;
-
-public class MainActivity extends Activity {
-
- private ListView item_list;
- private TextView show_app_name;
-
- private ItemAdapter itemAdapter;
- private List
- items;
-
- private MenuItem add_item, search_item, revert_item, share_item, delete_item;
-
- private int selectedCount = 0;
-
- private ItemDAO itemDAO;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
-
- processViews();
- processControllers();
-
- // 建立資料庫物件
- itemDAO = new ItemDAO(getApplicationContext());
-
- // 如果資料庫是空的,就建立一些範例資料
- // 這是為了方便測試用的,完成應用程式以後可以拿掉
- if (itemDAO.getCount() == 0) {
- itemDAO.sample();
- }
-
- // 取得所有記事資料
- items = itemDAO.getAll();
-
- itemAdapter = new ItemAdapter(this, R.layout.single_item, items);
- item_list.setAdapter(itemAdapter);
- }
-
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- if (resultCode == Activity.RESULT_OK) {
- Item item = (Item) data.getExtras().getSerializable(
- "net.macdidi.myandroidtutorial.Item");
-
- if (requestCode == 0) {
- // 新增記事資料到資料庫
- item = itemDAO.insert(item);
-
- items.add(item);
- itemAdapter.notifyDataSetChanged();
- }
- else if (requestCode == 1) {
- int position = data.getIntExtra("position", -1);
-
- if (position != -1) {
- // 修改資料庫中的記事資料
- itemDAO.update(item);
-
- items.set(position, item);
- itemAdapter.notifyDataSetChanged();
- }
- }
- }
- }
-
- private void processViews() {
- item_list = (ListView)findViewById(R.id.item_list);
- show_app_name = (TextView) findViewById(R.id.show_app_name);
- }
-
- private void processControllers() {
-
- OnItemClickListener itemListener = new OnItemClickListener() {
- @Override
- public void onItemClick(AdapterView> parent, View view,
- int position, long id) {
- Item item = itemAdapter.getItem(position);
-
- if (selectedCount > 0) {
- processMenu(item);
- itemAdapter.set(position, item);
- }
- else {
- Intent intent = new Intent(
- "net.macdidi.myandroidtutorial.EDIT_ITEM");
- intent.putExtra("position", position);
- intent.putExtra("net.macdidi.myandroidtutorial.Item", item);
- startActivityForResult(intent, 1);
- }
- }
- };
-
- item_list.setOnItemClickListener(itemListener);
-
- OnItemLongClickListener itemLongListener = new OnItemLongClickListener() {
- @Override
- public boolean onItemLongClick(AdapterView> parent, View view,
- int position, long id) {
- Item item = itemAdapter.getItem(position);
- processMenu(item);
- itemAdapter.set(position, item);
- return true;
- }
- };
-
- item_list.setOnItemLongClickListener(itemLongListener);
-
- OnLongClickListener listener = new OnLongClickListener() {
-
- @Override
- public boolean onLongClick(View view) {
- AlertDialog.Builder dialog =
- new AlertDialog.Builder(MainActivity.this);
- dialog.setTitle(R.string.app_name)
- .setMessage(R.string.about)
- .show();
- return false;
- }
-
- };
-
- show_app_name.setOnLongClickListener(listener);
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- MenuInflater menuInflater = getMenuInflater();
- menuInflater.inflate(R.menu.main_menu, menu);
-
- add_item = menu.findItem(R.id.add_item);
- search_item = menu.findItem(R.id.search_item);
- revert_item = menu.findItem(R.id.revert_item);
- share_item = menu.findItem(R.id.share_item);
- delete_item = menu.findItem(R.id.delete_item);
-
- processMenu(null);
-
- return true;
- }
-
- public void clickMenuItem(MenuItem item) {
- int itemId = item.getItemId();
-
- switch (itemId) {
- case R.id.search_item:
- break;
- case R.id.add_item:
- Intent intent = new Intent("net.macdidi.myandroidtutorial.ADD_ITEM");
- startActivityForResult(intent, 0);
- break;
- case R.id.revert_item:
- for (int i = 0; i < itemAdapter.getCount(); i++) {
- Item ri = itemAdapter.getItem(i);
-
- if (ri.isSelected()) {
- ri.setSelected(false);
- itemAdapter.set(i, ri);
- }
- }
-
- selectedCount = 0;
- processMenu(null);
-
- break;
- case R.id.delete_item:
- if (selectedCount == 0) {
- break;
- }
-
- AlertDialog.Builder d = new AlertDialog.Builder(this);
- String message = getString(R.string.delete_item);
- d.setTitle(R.string.delete)
- .setMessage(String.format(message, selectedCount));
- d.setPositiveButton(android.R.string.yes,
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- // 取得最後一個元素的編號
- int index = itemAdapter.getCount() - 1;
-
- while (index > -1) {
- Item item = itemAdapter.get(index);
-
- if (item.isSelected()) {
- itemAdapter.remove(item);
- // 刪除資料庫中的記事資料
- itemDAO.delete(item.getId());
- }
-
- index--;
- }
-
- itemAdapter.notifyDataSetChanged();
- }
- });
- d.setNegativeButton(android.R.string.no, null);
- d.show();
-
- break;
- case R.id.googleplus_item:
- break;
- case R.id.facebook_item:
- break;
- }
- }
-
- public void clickPreferences(MenuItem item) {
- startActivity(new Intent(this, PrefActivity.class));
- }
-
- private void processMenu(Item item) {
- if (item != null) {
- item.setSelected(!item.isSelected());
-
- if (item.isSelected()) {
- selectedCount++;
- }
- else {
- selectedCount--;
- }
- }
-
- add_item.setVisible(selectedCount == 0);
- search_item.setVisible(selectedCount == 0);
- revert_item.setVisible(selectedCount > 0);
- share_item.setVisible(selectedCount > 0);
- delete_item.setVisible(selectedCount > 0);
- }
-
- public void aboutApp(View view) {
- Intent intent = new Intent(this, AboutActivity.class);
- startActivity(intent);
- }
-}
diff --git a/examples/0303/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/MyDBHelper.java b/examples/0303/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/MyDBHelper.java
deleted file mode 100644
index bfd1b06..0000000
--- a/examples/0303/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/MyDBHelper.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package net.macdidi.myandroidtutorial;
-
-import android.content.Context;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteDatabase.CursorFactory;
-import android.database.sqlite.SQLiteOpenHelper;
-
-public class MyDBHelper extends SQLiteOpenHelper {
-
- // 資料庫名稱
- public static final String DATABASE_NAME = "mydata.db";
- // 資料庫版本,資料結構改變的時候要更改這個數字,通常是加一
- public static final int VERSION = 1;
- // 資料庫物件,固定的欄位變數
- private static SQLiteDatabase database;
-
- // 建構子,在一般的應用都不需要修改
- public MyDBHelper(Context context, String name, CursorFactory factory,
- int version) {
- super(context, name, factory, version);
- }
-
- // 需要資料庫的元件呼叫這個方法,這個方法在一般的應用都不需要修改
- public static SQLiteDatabase getDatabase(Context context) {
- if (database == null || !database.isOpen()) {
- database = new MyDBHelper(context, DATABASE_NAME,
- null, VERSION).getWritableDatabase();
- }
-
- return database;
- }
-
- @Override
- public void onCreate(SQLiteDatabase db) {
- // 建立應用程式需要的表格
- db.execSQL(ItemDAO.CREATE_TABLE);
- }
-
- @Override
- public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
- // 刪除原有的表格
- db.execSQL("DROP TABLE IF EXISTS " + ItemDAO.TABLE_NAME);
- // 呼叫onCreate建立新版的表格
- onCreate(db);
- }
-
-}
diff --git a/examples/0303/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/PrefActivity.java b/examples/0303/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/PrefActivity.java
deleted file mode 100644
index aa37810..0000000
--- a/examples/0303/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/PrefActivity.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package net.macdidi.myandroidtutorial;
-
-import android.content.SharedPreferences;
-import android.os.Bundle;
-import android.preference.Preference;
-import android.preference.PreferenceActivity;
-import android.preference.PreferenceManager;
-
-public class PrefActivity extends PreferenceActivity {
-
- private SharedPreferences sharedPreferences;
- private Preference defaultColor;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- // 指定使用的設定畫面配置資源
- addPreferencesFromResource(R.xml.mypreference);
- defaultColor = (Preference)findPreference("DEFAULT_COLOR");
- // 建立SharedPreferences物件
- sharedPreferences =
- PreferenceManager.getDefaultSharedPreferences(this);
- }
-
- @Override
- protected void onResume() {
- super.onResume();
- // 讀取設定的預設顏色
- int color = sharedPreferences.getInt("DEFAULT_COLOR", -1);
-
- if (color != -1) {
- // 設定顏色說明
- defaultColor.setSummary(getString(R.string.default_color_summary) +
- ": " + ItemActivity.getColors(color));
- }
- }
-
-}
diff --git a/examples/0304/MyAndroidTutorial/.classpath b/examples/0304/MyAndroidTutorial/.classpath
deleted file mode 100755
index 7bc01d9..0000000
--- a/examples/0304/MyAndroidTutorial/.classpath
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
-
-
-
-
diff --git a/examples/0304/MyAndroidTutorial/.project b/examples/0304/MyAndroidTutorial/.project
deleted file mode 100755
index b1de407..0000000
--- a/examples/0304/MyAndroidTutorial/.project
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
- MyAndroidTutorial
-
-
-
-
-
- com.android.ide.eclipse.adt.ResourceManagerBuilder
-
-
-
-
- com.android.ide.eclipse.adt.PreCompilerBuilder
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- com.android.ide.eclipse.adt.ApkBuilder
-
-
-
-
-
- com.android.ide.eclipse.adt.AndroidNature
- org.eclipse.jdt.core.javanature
-
-
diff --git a/examples/0304/MyAndroidTutorial/.settings/org.eclipse.core.resources.prefs b/examples/0304/MyAndroidTutorial/.settings/org.eclipse.core.resources.prefs
deleted file mode 100644
index 99f26c0..0000000
--- a/examples/0304/MyAndroidTutorial/.settings/org.eclipse.core.resources.prefs
+++ /dev/null
@@ -1,2 +0,0 @@
-eclipse.preferences.version=1
-encoding/=UTF-8
diff --git a/examples/0304/MyAndroidTutorial/AndroidManifest.xml b/examples/0304/MyAndroidTutorial/AndroidManifest.xml
deleted file mode 100755
index de2374a..0000000
--- a/examples/0304/MyAndroidTutorial/AndroidManifest.xml
+++ /dev/null
@@ -1,62 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/examples/0304/MyAndroidTutorial/bin/AndroidManifest.xml b/examples/0304/MyAndroidTutorial/bin/AndroidManifest.xml
deleted file mode 100755
index de2374a..0000000
--- a/examples/0304/MyAndroidTutorial/bin/AndroidManifest.xml
+++ /dev/null
@@ -1,62 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/examples/0304/MyAndroidTutorial/bin/MyAndroidTutorial.apk b/examples/0304/MyAndroidTutorial/bin/MyAndroidTutorial.apk
deleted file mode 100644
index 8cb0740..0000000
Binary files a/examples/0304/MyAndroidTutorial/bin/MyAndroidTutorial.apk and /dev/null differ
diff --git a/examples/0304/MyAndroidTutorial/bin/classes.dex b/examples/0304/MyAndroidTutorial/bin/classes.dex
deleted file mode 100755
index 94146f6..0000000
Binary files a/examples/0304/MyAndroidTutorial/bin/classes.dex and /dev/null differ
diff --git a/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/AboutActivity.class b/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/AboutActivity.class
deleted file mode 100644
index abbf876..0000000
Binary files a/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/AboutActivity.class and /dev/null differ
diff --git a/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/BuildConfig.class b/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/BuildConfig.class
deleted file mode 100644
index 30f5623..0000000
Binary files a/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/BuildConfig.class and /dev/null differ
diff --git a/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ColorActivity$ColorListener.class b/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ColorActivity$ColorListener.class
deleted file mode 100644
index 78ad0d3..0000000
Binary files a/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ColorActivity$ColorListener.class and /dev/null differ
diff --git a/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ColorActivity.class b/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ColorActivity.class
deleted file mode 100644
index 2075635..0000000
Binary files a/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ColorActivity.class and /dev/null differ
diff --git a/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/Colors.class b/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/Colors.class
deleted file mode 100644
index 4dda566..0000000
Binary files a/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/Colors.class and /dev/null differ
diff --git a/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/FileUtil.class b/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/FileUtil.class
deleted file mode 100644
index 2a6d8b7..0000000
Binary files a/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/FileUtil.class and /dev/null differ
diff --git a/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/Item.class b/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/Item.class
deleted file mode 100644
index 549fb77..0000000
Binary files a/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/Item.class and /dev/null differ
diff --git a/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ItemActivity.class b/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ItemActivity.class
deleted file mode 100644
index b7d535a..0000000
Binary files a/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ItemActivity.class and /dev/null differ
diff --git a/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ItemAdapter.class b/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ItemAdapter.class
deleted file mode 100644
index f0949d4..0000000
Binary files a/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ItemAdapter.class and /dev/null differ
diff --git a/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ItemDAO.class b/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ItemDAO.class
deleted file mode 100644
index 7e2d245..0000000
Binary files a/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ItemDAO.class and /dev/null differ
diff --git a/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$1.class b/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$1.class
deleted file mode 100644
index 983cfd6..0000000
Binary files a/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$1.class and /dev/null differ
diff --git a/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$2.class b/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$2.class
deleted file mode 100644
index ab7efab..0000000
Binary files a/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$2.class and /dev/null differ
diff --git a/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$3.class b/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$3.class
deleted file mode 100644
index 0818315..0000000
Binary files a/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$3.class and /dev/null differ
diff --git a/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$4.class b/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$4.class
deleted file mode 100644
index 0dc6594..0000000
Binary files a/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$4.class and /dev/null differ
diff --git a/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity.class b/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity.class
deleted file mode 100644
index 457041a..0000000
Binary files a/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity.class and /dev/null differ
diff --git a/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MyDBHelper.class b/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MyDBHelper.class
deleted file mode 100644
index e1e14ad..0000000
Binary files a/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MyDBHelper.class and /dev/null differ
diff --git a/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/PrefActivity.class b/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/PrefActivity.class
deleted file mode 100644
index 3989e38..0000000
Binary files a/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/PrefActivity.class and /dev/null differ
diff --git a/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$array.class b/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$array.class
deleted file mode 100644
index b9a7b7b..0000000
Binary files a/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$array.class and /dev/null differ
diff --git a/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$attr.class b/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$attr.class
deleted file mode 100644
index 01d5c1c..0000000
Binary files a/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$attr.class and /dev/null differ
diff --git a/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$color.class b/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$color.class
deleted file mode 100644
index c246f78..0000000
Binary files a/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$color.class and /dev/null differ
diff --git a/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$dimen.class b/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$dimen.class
deleted file mode 100644
index 4079bf4..0000000
Binary files a/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$dimen.class and /dev/null differ
diff --git a/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$drawable.class b/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$drawable.class
deleted file mode 100644
index 7037211..0000000
Binary files a/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$drawable.class and /dev/null differ
diff --git a/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$id.class b/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$id.class
deleted file mode 100644
index 8ac23be..0000000
Binary files a/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$id.class and /dev/null differ
diff --git a/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$layout.class b/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$layout.class
deleted file mode 100644
index cb476b8..0000000
Binary files a/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$layout.class and /dev/null differ
diff --git a/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$menu.class b/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$menu.class
deleted file mode 100644
index 5295fb4..0000000
Binary files a/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$menu.class and /dev/null differ
diff --git a/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$string.class b/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$string.class
deleted file mode 100644
index 3cda30a..0000000
Binary files a/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$string.class and /dev/null differ
diff --git a/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$style.class b/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$style.class
deleted file mode 100644
index f502898..0000000
Binary files a/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$style.class and /dev/null differ
diff --git a/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$xml.class b/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$xml.class
deleted file mode 100644
index 7dd8390..0000000
Binary files a/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$xml.class and /dev/null differ
diff --git a/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R.class b/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R.class
deleted file mode 100644
index e09c2b9..0000000
Binary files a/examples/0304/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R.class and /dev/null differ
diff --git a/examples/0304/MyAndroidTutorial/bin/dexedLibs/android-support-v4-9b1d5d28bf7d59a4e392b3d4f78c1f13.jar b/examples/0304/MyAndroidTutorial/bin/dexedLibs/android-support-v4-9b1d5d28bf7d59a4e392b3d4f78c1f13.jar
deleted file mode 100755
index 2f330c0..0000000
Binary files a/examples/0304/MyAndroidTutorial/bin/dexedLibs/android-support-v4-9b1d5d28bf7d59a4e392b3d4f78c1f13.jar and /dev/null differ
diff --git a/examples/0304/MyAndroidTutorial/bin/jarlist.cache b/examples/0304/MyAndroidTutorial/bin/jarlist.cache
deleted file mode 100755
index 0565465..0000000
--- a/examples/0304/MyAndroidTutorial/bin/jarlist.cache
+++ /dev/null
@@ -1,3 +0,0 @@
-# cache for current jar dependency. DO NOT EDIT.
-# format is
-# Encoding is UTF-8
diff --git a/examples/0304/MyAndroidTutorial/bin/res/crunch/drawable-hdpi/ic_launcher.png b/examples/0304/MyAndroidTutorial/bin/res/crunch/drawable-hdpi/ic_launcher.png
deleted file mode 100755
index bcfa058..0000000
Binary files a/examples/0304/MyAndroidTutorial/bin/res/crunch/drawable-hdpi/ic_launcher.png and /dev/null differ
diff --git a/examples/0304/MyAndroidTutorial/bin/res/crunch/drawable-mdpi/ic_launcher.png b/examples/0304/MyAndroidTutorial/bin/res/crunch/drawable-mdpi/ic_launcher.png
deleted file mode 100755
index 85848ff..0000000
Binary files a/examples/0304/MyAndroidTutorial/bin/res/crunch/drawable-mdpi/ic_launcher.png and /dev/null differ
diff --git a/examples/0304/MyAndroidTutorial/bin/res/crunch/drawable-xhdpi/ic_launcher.png b/examples/0304/MyAndroidTutorial/bin/res/crunch/drawable-xhdpi/ic_launcher.png
deleted file mode 100755
index 916901e..0000000
Binary files a/examples/0304/MyAndroidTutorial/bin/res/crunch/drawable-xhdpi/ic_launcher.png and /dev/null differ
diff --git a/examples/0304/MyAndroidTutorial/bin/res/crunch/drawable/alarm_icon.png b/examples/0304/MyAndroidTutorial/bin/res/crunch/drawable/alarm_icon.png
deleted file mode 100755
index ebeae27..0000000
Binary files a/examples/0304/MyAndroidTutorial/bin/res/crunch/drawable/alarm_icon.png and /dev/null differ
diff --git a/examples/0304/MyAndroidTutorial/bin/res/crunch/drawable/location_icon.png b/examples/0304/MyAndroidTutorial/bin/res/crunch/drawable/location_icon.png
deleted file mode 100755
index 6897a97..0000000
Binary files a/examples/0304/MyAndroidTutorial/bin/res/crunch/drawable/location_icon.png and /dev/null differ
diff --git a/examples/0304/MyAndroidTutorial/bin/res/crunch/drawable/record_sound_icon.png b/examples/0304/MyAndroidTutorial/bin/res/crunch/drawable/record_sound_icon.png
deleted file mode 100755
index 6fe2060..0000000
Binary files a/examples/0304/MyAndroidTutorial/bin/res/crunch/drawable/record_sound_icon.png and /dev/null differ
diff --git a/examples/0304/MyAndroidTutorial/bin/res/crunch/drawable/select_color_icon.png b/examples/0304/MyAndroidTutorial/bin/res/crunch/drawable/select_color_icon.png
deleted file mode 100755
index 4270ec5..0000000
Binary files a/examples/0304/MyAndroidTutorial/bin/res/crunch/drawable/select_color_icon.png and /dev/null differ
diff --git a/examples/0304/MyAndroidTutorial/bin/res/crunch/drawable/selected_icon.png b/examples/0304/MyAndroidTutorial/bin/res/crunch/drawable/selected_icon.png
deleted file mode 100755
index 982ddee..0000000
Binary files a/examples/0304/MyAndroidTutorial/bin/res/crunch/drawable/selected_icon.png and /dev/null differ
diff --git a/examples/0304/MyAndroidTutorial/bin/res/crunch/drawable/take_picture_icon.png b/examples/0304/MyAndroidTutorial/bin/res/crunch/drawable/take_picture_icon.png
deleted file mode 100755
index c812e2f..0000000
Binary files a/examples/0304/MyAndroidTutorial/bin/res/crunch/drawable/take_picture_icon.png and /dev/null differ
diff --git a/examples/0304/MyAndroidTutorial/bin/resources.ap_ b/examples/0304/MyAndroidTutorial/bin/resources.ap_
deleted file mode 100644
index e01ad50..0000000
Binary files a/examples/0304/MyAndroidTutorial/bin/resources.ap_ and /dev/null differ
diff --git a/examples/0304/MyAndroidTutorial/gen/net/macdidi/myandroidtutorial/BuildConfig.java b/examples/0304/MyAndroidTutorial/gen/net/macdidi/myandroidtutorial/BuildConfig.java
deleted file mode 100755
index 5d44ea9..0000000
--- a/examples/0304/MyAndroidTutorial/gen/net/macdidi/myandroidtutorial/BuildConfig.java
+++ /dev/null
@@ -1,6 +0,0 @@
-/** Automatically generated file. DO NOT MODIFY */
-package net.macdidi.myandroidtutorial;
-
-public final class BuildConfig {
- public final static boolean DEBUG = true;
-}
\ No newline at end of file
diff --git a/examples/0304/MyAndroidTutorial/gen/net/macdidi/myandroidtutorial/R.java b/examples/0304/MyAndroidTutorial/gen/net/macdidi/myandroidtutorial/R.java
deleted file mode 100755
index c7b4771..0000000
--- a/examples/0304/MyAndroidTutorial/gen/net/macdidi/myandroidtutorial/R.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/* AUTO-GENERATED FILE. DO NOT MODIFY.
- *
- * This class was automatically generated by the
- * aapt tool from the resource data it found. It
- * should not be modified by hand.
- */
-
-package net.macdidi.myandroidtutorial;
-
-public final class R {
- public static final class array {
- public static final int notify_minutes_array=0x7f080000;
- public static final int notify_minutes_value_array=0x7f080001;
- }
- public static final class attr {
- }
- public static final class color {
- public static final int dark_text=0x7f050003;
- public static final int divider_color=0x7f050002;
- public static final int grey=0x7f050001;
- public static final int light_grey=0x7f050000;
- }
- public static final class dimen {
- public static final int default_margin=0x7f060001;
- public static final int default_padding=0x7f060000;
- public static final int title_txt_size=0x7f060002;
- }
- public static final class drawable {
- public static final int alarm_icon=0x7f020000;
- public static final int ic_launcher=0x7f020001;
- public static final int item_drawable=0x7f020002;
- public static final int location_icon=0x7f020003;
- public static final int record_sound_icon=0x7f020004;
- public static final int retangle_drawable=0x7f020005;
- public static final int select_color_icon=0x7f020006;
- public static final int selected_icon=0x7f020007;
- public static final int take_picture_icon=0x7f020008;
- }
- public static final class id {
- public static final int add_item=0x7f0b0010;
- public static final int cancel_item=0x7f0b0008;
- public static final int color_gallery=0x7f0b0000;
- public static final int content_text=0x7f0b0002;
- public static final int date_text=0x7f0b000e;
- public static final int delete_item=0x7f0b0012;
- public static final int facebook_item=0x7f0b0015;
- public static final int googleplus_item=0x7f0b0014;
- public static final int item_list=0x7f0b000a;
- public static final int ok_teim=0x7f0b0009;
- public static final int record_sound=0x7f0b0004;
- public static final int revert_item=0x7f0b0011;
- public static final int search_item=0x7f0b000f;
- public static final int select_color=0x7f0b0007;
- public static final int selected_item=0x7f0b000d;
- public static final int set_alarm=0x7f0b0006;
- public static final int set_location=0x7f0b0005;
- public static final int share_item=0x7f0b0013;
- public static final int show_app_name=0x7f0b000b;
- public static final int take_picture=0x7f0b0003;
- public static final int title_text=0x7f0b0001;
- public static final int type_color=0x7f0b000c;
- }
- public static final class layout {
- public static final int activity_about=0x7f030000;
- public static final int activity_color=0x7f030001;
- public static final int activity_item=0x7f030002;
- public static final int activity_main=0x7f030003;
- public static final int single_item=0x7f030004;
- }
- public static final class menu {
- public static final int main_menu=0x7f0a0000;
- }
- public static final class string {
- public static final int about=0x7f070007;
- public static final int app_name=0x7f070000;
- public static final int content=0x7f070005;
- public static final int default_color=0x7f07000b;
- public static final int default_color_summary=0x7f07000c;
- public static final int default_notify=0x7f07000d;
- public static final int default_notify_summary=0x7f07000e;
- public static final int delete=0x7f070009;
- public static final int delete_item=0x7f07000a;
- public static final int enter_content=0x7f070006;
- public static final int enter_title=0x7f070004;
- public static final int hello_world=0x7f07000f;
- public static final int title=0x7f070003;
- public static final int title_activity_color=0x7f070002;
- public static final int title_activity_main=0x7f070001;
- public static final int version=0x7f070008;
- }
- public static final class style {
- /**
- Base application theme, dependent on API level. This theme is replaced
- by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
-
-
- Theme customizations available in newer API levels can go in
- res/values-vXX/styles.xml, while customizations related to
- backward-compatibility can go here.
-
-
- Base application theme for API 11+. This theme completely replaces
- AppBaseTheme from res/values/styles.xml on API 11+ devices.
-
- API 11 theme customizations can go here.
-
- Base application theme for API 14+. This theme completely replaces
- AppBaseTheme from BOTH res/values/styles.xml and
- res/values-v11/styles.xml on API 14+ devices.
-
- API 14 theme customizations can go here.
- */
- public static final int AppBaseTheme=0x7f090000;
- /** Application theme.
- All customizations that are NOT specific to a particular API-level can go here.
- */
- public static final int AppTheme=0x7f090001;
- }
- public static final class xml {
- public static final int mypreference=0x7f040000;
- }
-}
diff --git a/examples/0304/MyAndroidTutorial/libs/android-support-v4.jar b/examples/0304/MyAndroidTutorial/libs/android-support-v4.jar
deleted file mode 100755
index 187bdf4..0000000
Binary files a/examples/0304/MyAndroidTutorial/libs/android-support-v4.jar and /dev/null differ
diff --git a/examples/0304/MyAndroidTutorial/proguard-project.txt b/examples/0304/MyAndroidTutorial/proguard-project.txt
deleted file mode 100755
index f2fe155..0000000
--- a/examples/0304/MyAndroidTutorial/proguard-project.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-# To enable ProGuard in your project, edit project.properties
-# to define the proguard.config property as described in that file.
-#
-# Add project specific ProGuard rules here.
-# By default, the flags in this file are appended to flags specified
-# in ${sdk.dir}/tools/proguard/proguard-android.txt
-# You can edit the include path and order by changing the ProGuard
-# include property in project.properties.
-#
-# For more details, see
-# http://developer.android.com/guide/developing/tools/proguard.html
-
-# Add any project specific keep options here:
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-# public *;
-#}
diff --git a/examples/0304/MyAndroidTutorial/project.properties b/examples/0304/MyAndroidTutorial/project.properties
deleted file mode 100755
index 4ab1256..0000000
--- a/examples/0304/MyAndroidTutorial/project.properties
+++ /dev/null
@@ -1,14 +0,0 @@
-# This file is automatically generated by Android Tools.
-# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
-#
-# This file must be checked in Version Control Systems.
-#
-# To customize properties used by the Ant build system edit
-# "ant.properties", and override values to adapt the script to your
-# project structure.
-#
-# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
-#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
-
-# Project target.
-target=android-19
diff --git a/examples/0304/MyAndroidTutorial/res/drawable/item_drawable.xml b/examples/0304/MyAndroidTutorial/res/drawable/item_drawable.xml
deleted file mode 100755
index ecc4011..0000000
--- a/examples/0304/MyAndroidTutorial/res/drawable/item_drawable.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/examples/0304/MyAndroidTutorial/res/drawable/retangle_drawable.xml b/examples/0304/MyAndroidTutorial/res/drawable/retangle_drawable.xml
deleted file mode 100755
index e195342..0000000
--- a/examples/0304/MyAndroidTutorial/res/drawable/retangle_drawable.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/examples/0304/MyAndroidTutorial/res/layout/activity_about.xml b/examples/0304/MyAndroidTutorial/res/layout/activity_about.xml
deleted file mode 100755
index 738fe98..0000000
--- a/examples/0304/MyAndroidTutorial/res/layout/activity_about.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/examples/0304/MyAndroidTutorial/res/layout/activity_color.xml b/examples/0304/MyAndroidTutorial/res/layout/activity_color.xml
deleted file mode 100755
index 693a9d4..0000000
--- a/examples/0304/MyAndroidTutorial/res/layout/activity_color.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
-
-
diff --git a/examples/0304/MyAndroidTutorial/res/layout/activity_item.xml b/examples/0304/MyAndroidTutorial/res/layout/activity_item.xml
deleted file mode 100755
index a12c44c..0000000
--- a/examples/0304/MyAndroidTutorial/res/layout/activity_item.xml
+++ /dev/null
@@ -1,94 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/examples/0304/MyAndroidTutorial/res/layout/activity_main.xml b/examples/0304/MyAndroidTutorial/res/layout/activity_main.xml
deleted file mode 100755
index 418c34b..0000000
--- a/examples/0304/MyAndroidTutorial/res/layout/activity_main.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
diff --git a/examples/0304/MyAndroidTutorial/res/layout/single_item.xml b/examples/0304/MyAndroidTutorial/res/layout/single_item.xml
deleted file mode 100755
index c3b579c..0000000
--- a/examples/0304/MyAndroidTutorial/res/layout/single_item.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/examples/0304/MyAndroidTutorial/res/menu/main_menu.xml b/examples/0304/MyAndroidTutorial/res/menu/main_menu.xml
deleted file mode 100755
index dadd8fa..0000000
--- a/examples/0304/MyAndroidTutorial/res/menu/main_menu.xml
+++ /dev/null
@@ -1,51 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/examples/0304/MyAndroidTutorial/res/values-en/strings.xml b/examples/0304/MyAndroidTutorial/res/values-en/strings.xml
deleted file mode 100755
index 34f4fed..0000000
--- a/examples/0304/MyAndroidTutorial/res/values-en/strings.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
- MyAndroidTutorial
- MainActivity
- Hello world!
-
- Title
- Enter title
- Content
- Enter content
-
-
diff --git a/examples/0304/MyAndroidTutorial/res/values-v11/styles.xml b/examples/0304/MyAndroidTutorial/res/values-v11/styles.xml
deleted file mode 100755
index 3c02242..0000000
--- a/examples/0304/MyAndroidTutorial/res/values-v11/styles.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
diff --git a/examples/0304/MyAndroidTutorial/res/values-v14/styles.xml b/examples/0304/MyAndroidTutorial/res/values-v14/styles.xml
deleted file mode 100755
index a91fd03..0000000
--- a/examples/0304/MyAndroidTutorial/res/values-v14/styles.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
diff --git a/examples/0304/MyAndroidTutorial/res/values/colors.xml b/examples/0304/MyAndroidTutorial/res/values/colors.xml
deleted file mode 100755
index c63ec2d..0000000
--- a/examples/0304/MyAndroidTutorial/res/values/colors.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
- #CCCCCC
- #AAAAAA
- #DDCCCCCC
- #111111
-
diff --git a/examples/0304/MyAndroidTutorial/res/values/dimens.xml b/examples/0304/MyAndroidTutorial/res/values/dimens.xml
deleted file mode 100755
index fb03071..0000000
--- a/examples/0304/MyAndroidTutorial/res/values/dimens.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
- 6dp
- 2dp
- 24sp
-
diff --git a/examples/0304/MyAndroidTutorial/res/values/strings.xml b/examples/0304/MyAndroidTutorial/res/values/strings.xml
deleted file mode 100755
index 53d96b7..0000000
--- a/examples/0304/MyAndroidTutorial/res/values/strings.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-
-
-
- MyAndroidTutorial
- MyAndroidTutorial
- 設定顏色
- 標題
- 輸入標題
- 內容
- 輸入內容
- 這是Android Tutorial應用程式
- 版本:AndroidTutorial_0.2.4
-
- 刪除
- 確定要刪除 %1$d 個項目?
-
- 預設的顏色
- 新增記事的預設顏色
-
- 預設提醒時間
- 在指定的時間之前通知
-
-
- - 五分鐘
- - 十分鐘
- - 二十分鐘
- - 三十分鐘
- - 六十分鐘
-
-
-
- - 5
- - 10
- - 20
- - 30
- - 60
-
-
-
diff --git a/examples/0304/MyAndroidTutorial/res/values/styles.xml b/examples/0304/MyAndroidTutorial/res/values/styles.xml
deleted file mode 100755
index 6ce89c7..0000000
--- a/examples/0304/MyAndroidTutorial/res/values/styles.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
-
-
-
-
-
-
diff --git a/examples/0304/MyAndroidTutorial/res/xml/mypreference.xml b/examples/0304/MyAndroidTutorial/res/xml/mypreference.xml
deleted file mode 100644
index 4cd7f5e..0000000
--- a/examples/0304/MyAndroidTutorial/res/xml/mypreference.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/examples/0304/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/AboutActivity.java b/examples/0304/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/AboutActivity.java
deleted file mode 100755
index 111efc5..0000000
--- a/examples/0304/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/AboutActivity.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package net.macdidi.myandroidtutorial;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.view.View;
-import android.view.Window;
-
-public class AboutActivity extends Activity {
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- // 取消元件的應用程式標題
- requestWindowFeature(Window.FEATURE_NO_TITLE);
- setContentView(R.layout.activity_about);
- }
-
- // 結束按鈕
- public void clickOk(View view) {
- // 呼叫這個方法結束Activity元件
- finish();
- }
-
-}
diff --git a/examples/0304/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/ColorActivity.java b/examples/0304/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/ColorActivity.java
deleted file mode 100755
index 0eafb85..0000000
--- a/examples/0304/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/ColorActivity.java
+++ /dev/null
@@ -1,75 +0,0 @@
-package net.macdidi.myandroidtutorial;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.os.Bundle;
-import android.preference.PreferenceManager;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.widget.Button;
-import android.widget.LinearLayout;
-
-public class ColorActivity extends Activity {
-
- private LinearLayout color_gallery;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_color);
-
- processViews();
-
- ColorListener listener = new ColorListener();
-
- for (Colors c : Colors.values()) {
- Button button = new Button(this);
- button.setId(c.parseColor());
- LinearLayout.LayoutParams layout =
- new LinearLayout.LayoutParams(128, 128);
- layout.setMargins(6, 6, 6, 6);
- button.setLayoutParams(layout);
- button.setBackgroundColor(c.parseColor());
-
- button.setOnClickListener(listener);
-
- color_gallery.addView(button);
- }
- }
-
- private void processViews() {
- color_gallery = (LinearLayout) findViewById(R.id.color_gallery);
- }
-
- private class ColorListener implements OnClickListener {
-
- @Override
- public void onClick(View view) {
- String action = ColorActivity.this.getIntent().getAction();
-
- // 經由設定元件啟動
- if (action != null &&
- action.equals("net.macdidi.myandroidtutorial.CHOOSE_COLOR")) {
- // 建立SharedPreferences物件
- SharedPreferences.Editor editor =
- PreferenceManager.getDefaultSharedPreferences(
- ColorActivity.this).edit();
- // 儲存預設顏色
- editor.putInt("DEFAULT_COLOR", view.getId());
- // 寫入設定值
- editor.commit();
- finish();
- }
- // 經由新增或修改記事的元件啟動
- else {
- Intent result = getIntent();
- result.putExtra("colorId", view.getId());
- setResult(Activity.RESULT_OK, result);
- finish();
- }
- }
-
- }
-
-}
diff --git a/examples/0304/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/Colors.java b/examples/0304/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/Colors.java
deleted file mode 100755
index a3eb9d4..0000000
--- a/examples/0304/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/Colors.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package net.macdidi.myandroidtutorial;
-
-import android.graphics.Color;
-
-public enum Colors {
-
- LIGHTGREY("#D3D3D3"), BLUE("#33B5E5"), PURPLE("#AA66CC"),
- GREEN("#99CC00"), ORANGE("#FFBB33"), RED("#FF4444");
-
- private String code;
-
- private Colors(String code) {
- this.code = code;
- }
-
- public String getCode() {
- return code;
- }
-
- public int parseColor() {
- return Color.parseColor(code);
- }
-
-}
diff --git a/examples/0304/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/FileUtil.java b/examples/0304/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/FileUtil.java
deleted file mode 100644
index 62920aa..0000000
--- a/examples/0304/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/FileUtil.java
+++ /dev/null
@@ -1,112 +0,0 @@
-package net.macdidi.myandroidtutorial;
-
-import java.io.File;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.os.Environment;
-import android.util.Log;
-import android.widget.ImageView;
-
-public class FileUtil {
-
- // 應用程式儲存檔案的目錄
- public static final String APP_DIR = "androidtutorial";
-
- // 外部儲存設備是否可寫入
- public static boolean isExternalStorageWritable() {
- // 取得目前外部儲存設備的狀態
- String state = Environment.getExternalStorageState();
-
- // 判斷是否可寫入
- if (Environment.MEDIA_MOUNTED.equals(state)) {
- return true;
- }
-
- return false;
- }
-
- // 外部儲存設備是否可讀取
- public static boolean isExternalStorageReadable() {
- // 取得目前外部儲存設備的狀態
- String state = Environment.getExternalStorageState();
-
- // 判斷是否可讀取
- if (Environment.MEDIA_MOUNTED.equals(state) ||
- Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
- return true;
- }
-
- return false;
- }
-
- // 建立並傳回在公用相簿下參數指定的路徑
- public static File getPublicAlbumStorageDir(String albumName) {
- // 取得公用的照片路徑
- File pictures = Environment.getExternalStoragePublicDirectory(
- Environment.DIRECTORY_PICTURES);
- // 準備在照片路徑下建立一個指定的路徑
- File file = new File(pictures, albumName);
-
- // 如果建立路徑不成功
- if (!file.mkdirs()) {
- Log.e("getAlbumStorageDir", "Directory not created");
- }
-
- return file;
- }
-
- // 建立並傳回在應用程式專用相簿下參數指定的路徑
- public static File getAlbumStorageDir(Context context, String albumName) {
- // 取得應用程式專用的照片路徑
- File pictures = context.getExternalFilesDir(
- Environment.DIRECTORY_PICTURES);
- // 準備在照片路徑下建立一個指定的路徑
- File file = new File(pictures, albumName);
-
- // 如果建立路徑不成功
- if (!file.mkdirs()) {
- Log.e("getAlbumStorageDir", "Directory not created");
- }
-
- return file;
- }
-
- // 建立並傳回外部儲存媒體參數指定的路徑
- public static File getExternalStorageDir(String dir) {
- File result = new File(
- Environment.getExternalStorageDirectory(), dir);
-
- if (!isExternalStorageWritable()) {
- return null;
- }
-
- if (!result.exists() && !result.mkdirs()) {
- return null;
- }
-
- return result;
- }
-
- // 讀取指定的照片檔案名稱設定給ImageView元件
- public static void fileToImageView(String fileName, ImageView imageView) {
- if (new File(fileName).exists()) {
- Bitmap bitmap = BitmapFactory.decodeFile(fileName);
- imageView.setImageBitmap(bitmap);
- }
- else {
- Log.e("fileToImageView", fileName + " not found.");
- }
- }
-
- // 產生唯一的檔案名稱
- public static String getUniqueFileName() {
- // 使用年月日_時分秒格式為檔案名稱
- SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
- return sdf.format(new Date());
- }
-
-}
diff --git a/examples/0304/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/Item.java b/examples/0304/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/Item.java
deleted file mode 100755
index 0161619..0000000
--- a/examples/0304/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/Item.java
+++ /dev/null
@@ -1,136 +0,0 @@
-package net.macdidi.myandroidtutorial;
-
-import java.util.Date;
-import java.util.Locale;
-
-public class Item implements java.io.Serializable {
-
- // 編號、日期時間、顏色、標題、內容、檔案名稱、經緯度、修改、已選擇
- private long id;
- private long datetime;
- private Colors color;
- private String title;
- private String content;
- private String fileName;
- private double latitude;
- private double longitude;
- private long lastModify;
- private boolean selected;
-
- public Item() {
- title = "";
- content = "";
- color = Colors.LIGHTGREY;
- }
-
- public Item(long id, long datetime, Colors color, String title,
- String content, String fileName, double latitude, double longitude,
- long lastModify) {
- this.id = id;
- this.datetime = datetime;
- this.color = color;
- this.title = title;
- this.content = content;
- this.fileName = fileName;
- this.latitude = latitude;
- this.longitude = longitude;
- this.lastModify = lastModify;
- }
-
- public long getId() {
- return id;
- }
-
- public void setId(long id) {
- this.id = id;
- }
-
- public long getDatetime() {
- return datetime;
- }
-
- public String getLocaleDatetime() {
- return String.format(Locale.getDefault(), "%tF % {
-
- // 畫面資源編號
- private int resource;
- // 包裝的記事資料
- private List- items;
-
- public ItemAdapter(Context context, int resource, List
- items) {
- super(context, resource, items);
- this.resource = resource;
- this.items = items;
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- LinearLayout itemView;
- // 讀取目前位置的記事物件
- final Item item = getItem(position);
-
- if (convertView == null) {
- // 建立項目畫面元件
- itemView = new LinearLayout(getContext());
- String inflater = Context.LAYOUT_INFLATER_SERVICE;
- LayoutInflater li = (LayoutInflater)
- getContext().getSystemService(inflater);
- li.inflate(resource, itemView, true);
- }
- else {
- itemView = (LinearLayout) convertView;
- }
-
- // 讀取記事顏色、已選擇、標題與日期時間元件
- RelativeLayout typeColor = (RelativeLayout) itemView.findViewById(R.id.type_color);
- ImageView selectedItem = (ImageView) itemView.findViewById(R.id.selected_item);
- TextView titleView = (TextView) itemView.findViewById(R.id.title_text);
- TextView dateView = (TextView) itemView.findViewById(R.id.date_text);
-
- // 設定記事顏色
- GradientDrawable background = (GradientDrawable)typeColor.getBackground();
- background.setColor(item.getColor().parseColor());
-
- // 設定標題與日期時間
- titleView.setText(item.getTitle());
- dateView.setText(item.getLocaleDatetime());
-
- // 設定是否已選擇
- selectedItem.setVisibility(item.isSelected() ? View.VISIBLE : View.INVISIBLE);
-
- return itemView;
- }
-
- // 設定指定編號的記事資料
- public void set(int index, Item item) {
- if (index >= 0 && index < items.size()) {
- items.set(index, item);
- notifyDataSetChanged();
- }
- }
-
- // 讀取指定編號的記事資料
- public Item get(int index) {
- return items.get(index);
- }
-
-}
diff --git a/examples/0304/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/ItemDAO.java b/examples/0304/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/ItemDAO.java
deleted file mode 100644
index 3ac59c0..0000000
--- a/examples/0304/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/ItemDAO.java
+++ /dev/null
@@ -1,196 +0,0 @@
-package net.macdidi.myandroidtutorial;
-
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
-
-// 資料功能類別
-public class ItemDAO {
- // 表格名稱
- public static final String TABLE_NAME = "item";
-
- // 編號表格欄位名稱,固定不變
- public static final String KEY_ID = "_id";
-
- // 其它表格欄位名稱
- public static final String DATETIME_COLUMN = "datetime";
- public static final String COLOR_COLUMN = "color";
- public static final String TITLE_COLUMN = "title";
- public static final String CONTENT_COLUMN = "content";
- public static final String FILENAME_COLUMN = "filename";
- public static final String LATITUDE_COLUMN = "latitude";
- public static final String LONGITUDE_COLUMN = "longitude";
- public static final String LASTMODIFY_COLUMN = "lastmodify";
-
- // 使用上面宣告的變數建立表格的SQL指令
- public static final String CREATE_TABLE =
- "CREATE TABLE " + TABLE_NAME + " (" +
- KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
- DATETIME_COLUMN + " INTEGER NOT NULL, " +
- COLOR_COLUMN + " INTEGER NOT NULL, " +
- TITLE_COLUMN + " TEXT NOT NULL, " +
- CONTENT_COLUMN + " TEXT NOT NULL, " +
- FILENAME_COLUMN + " TEXT, " +
- LATITUDE_COLUMN + " REAL, " +
- LONGITUDE_COLUMN + " REAL, " +
- LASTMODIFY_COLUMN + " INTEGER)";
-
- // 資料庫物件
- private SQLiteDatabase db;
-
- // 建構子,一般的應用都不需要修改
- public ItemDAO(Context context) {
- db = MyDBHelper.getDatabase(context);
- }
-
- // 關閉資料庫,一般的應用都不需要修改
- public void close() {
- db.close();
- }
-
- // 新增參數指定的物件
- public Item insert(Item item) {
- // 建立準備新增資料的ContentValues物件
- ContentValues cv = new ContentValues();
-
- // 加入ContentValues物件包裝的新增資料
- // 第一個參數是欄位名稱, 第二個參數是欄位的資料
- cv.put(DATETIME_COLUMN, item.getDatetime());
- cv.put(COLOR_COLUMN, item.getColor().parseColor());
- cv.put(TITLE_COLUMN, item.getTitle());
- cv.put(CONTENT_COLUMN, item.getContent());
- cv.put(FILENAME_COLUMN, item.getFileName());
- cv.put(LATITUDE_COLUMN, item.getLatitude());
- cv.put(LONGITUDE_COLUMN, item.getLongitude());
- cv.put(LASTMODIFY_COLUMN, item.getLastModify());
-
- // 新增一筆資料並取得編號
- // 第一個參數是表格名稱
- // 第二個參數是沒有指定欄位值的預設值
- // 第三個參數是包裝新增資料的ContentValues物件
- long id = db.insert(TABLE_NAME, null, cv);
-
- // 設定編號
- item.setId(id);
- // 回傳結果
- return item;
- }
-
- // 修改參數指定的物件
- public boolean update(Item item) {
- // 建立準備修改資料的ContentValues物件
- ContentValues cv = new ContentValues();
-
- // 加入ContentValues物件包裝的修改資料
- // 第一個參數是欄位名稱, 第二個參數是欄位的資料
- cv.put(DATETIME_COLUMN, item.getDatetime());
- cv.put(COLOR_COLUMN, item.getColor().parseColor());
- cv.put(TITLE_COLUMN, item.getTitle());
- cv.put(CONTENT_COLUMN, item.getContent());
- cv.put(FILENAME_COLUMN, item.getFileName());
- cv.put(LATITUDE_COLUMN, item.getLatitude());
- cv.put(LONGITUDE_COLUMN, item.getLongitude());
- cv.put(LASTMODIFY_COLUMN, item.getLastModify());
-
- // 設定修改資料的條件為編號
- // 格式為「欄位名稱=資料」
- String where = KEY_ID + "=" + item.getId();
-
- // 執行修改資料並回傳修改的資料數量是否成功
- return db.update(TABLE_NAME, cv, where, null) > 0;
- }
-
- // 刪除參數指定編號的資料
- public boolean delete(long id){
- // 設定條件為編號,格式為「欄位名稱=資料」
- String where = KEY_ID + "=" + id;
- // 刪除指定編號資料並回傳刪除是否成功
- return db.delete(TABLE_NAME, where , null) > 0;
- }
-
- // 讀取所有記事資料
- public List
- getAll() {
- List
- result = new ArrayList<>();
- Cursor cursor = db.query(
- TABLE_NAME, null, null, null, null, null, null, null);
-
- while (cursor.moveToNext()) {
- result.add(getRecord(cursor));
- }
-
- cursor.close();
- return result;
- }
-
- // 取得指定編號的資料物件
- public Item get(long id) {
- // 準備回傳結果用的物件
- Item item = null;
- // 使用編號為查詢條件
- String where = KEY_ID + "=" + id;
- // 執行查詢
- Cursor result = db.query(
- TABLE_NAME, null, where, null, null, null, null, null);
-
- // 如果有查詢結果
- if (result.moveToFirst()) {
- // 讀取包裝一筆資料的物件
- item = getRecord(result);
- }
-
- // 關閉Cursor物件
- result.close();
- // 回傳結果
- return item;
- }
-
- // 把Cursor目前的資料包裝為物件
- public Item getRecord(Cursor cursor) {
- // 準備回傳結果用的物件
- Item result = new Item();
-
- result.setId(cursor.getLong(0));
- result.setDatetime(cursor.getLong(1));
- result.setColor(ItemActivity.getColors(cursor.getInt(2)));
- result.setTitle(cursor.getString(3));
- result.setContent(cursor.getString(4));
- result.setFileName(cursor.getString(5));
- result.setLatitude(cursor.getDouble(6));
- result.setLongitude(cursor.getDouble(7));
- result.setLastModify(cursor.getLong(8));
-
- // 回傳結果
- return result;
- }
-
- // 取得資料數量
- public int getCount() {
- int result = 0;
- Cursor cursor = db.rawQuery("SELECT COUNT(*) FROM " + TABLE_NAME, null);
-
- if (cursor.moveToNext()) {
- result = cursor.getInt(0);
- }
-
- return result;
- }
-
- // 建立範例資料
- public void sample() {
- Item item = new Item(0, new Date().getTime(), Colors.RED, "關於Android Tutorial的事情.", "Hello content", "", 0, 0, 0);
- Item item2 = new Item(0, new Date().getTime(), Colors.BLUE, "一隻非常可愛的小狗狗!", "她的名字叫「大熱狗」,又叫\n作「奶嘴」,是一隻非常可愛\n的小狗。", "", 25.04719, 121.516981, 0);
- Item item3 = new Item(0, new Date().getTime(), Colors.GREEN, "一首非常好聽的音樂!", "Hello content", "", 0, 0, 0);
- Item item4 = new Item(0, new Date().getTime(), Colors.ORANGE, "儲存在資料庫的資料", "Hello content", "", 0, 0, 0);
-
- insert(item);
- insert(item2);
- insert(item3);
- insert(item4);
- }
-
-}
diff --git a/examples/0304/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/MainActivity.java b/examples/0304/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/MainActivity.java
deleted file mode 100755
index 8c644c9..0000000
--- a/examples/0304/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/MainActivity.java
+++ /dev/null
@@ -1,254 +0,0 @@
-package net.macdidi.myandroidtutorial;
-
-import java.util.List;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.os.Bundle;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.View.OnLongClickListener;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemClickListener;
-import android.widget.AdapterView.OnItemLongClickListener;
-import android.widget.ListView;
-import android.widget.TextView;
-
-public class MainActivity extends Activity {
-
- private ListView item_list;
- private TextView show_app_name;
-
- private ItemAdapter itemAdapter;
- private List
- items;
-
- private MenuItem add_item, search_item, revert_item, share_item, delete_item;
-
- private int selectedCount = 0;
-
- private ItemDAO itemDAO;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
-
- processViews();
- processControllers();
-
- // 建立資料庫物件
- itemDAO = new ItemDAO(getApplicationContext());
-
- // 如果資料庫是空的,就建立一些範例資料
- // 這是為了方便測試用的,完成應用程式以後可以拿掉
- if (itemDAO.getCount() == 0) {
- itemDAO.sample();
- }
-
- // 取得所有記事資料
- items = itemDAO.getAll();
-
- itemAdapter = new ItemAdapter(this, R.layout.single_item, items);
- item_list.setAdapter(itemAdapter);
- }
-
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- if (resultCode == Activity.RESULT_OK) {
- Item item = (Item) data.getExtras().getSerializable(
- "net.macdidi.myandroidtutorial.Item");
-
- if (requestCode == 0) {
- // 新增記事資料到資料庫
- item = itemDAO.insert(item);
-
- items.add(item);
- itemAdapter.notifyDataSetChanged();
- }
- else if (requestCode == 1) {
- int position = data.getIntExtra("position", -1);
-
- if (position != -1) {
- // 修改資料庫中的記事資料
- itemDAO.update(item);
-
- items.set(position, item);
- itemAdapter.notifyDataSetChanged();
- }
- }
- }
- }
-
- private void processViews() {
- item_list = (ListView)findViewById(R.id.item_list);
- show_app_name = (TextView) findViewById(R.id.show_app_name);
- }
-
- private void processControllers() {
-
- OnItemClickListener itemListener = new OnItemClickListener() {
- @Override
- public void onItemClick(AdapterView> parent, View view,
- int position, long id) {
- Item item = itemAdapter.getItem(position);
-
- if (selectedCount > 0) {
- processMenu(item);
- itemAdapter.set(position, item);
- }
- else {
- Intent intent = new Intent(
- "net.macdidi.myandroidtutorial.EDIT_ITEM");
- intent.putExtra("position", position);
- intent.putExtra("net.macdidi.myandroidtutorial.Item", item);
- startActivityForResult(intent, 1);
- }
- }
- };
-
- item_list.setOnItemClickListener(itemListener);
-
- OnItemLongClickListener itemLongListener = new OnItemLongClickListener() {
- @Override
- public boolean onItemLongClick(AdapterView> parent, View view,
- int position, long id) {
- Item item = itemAdapter.getItem(position);
- processMenu(item);
- itemAdapter.set(position, item);
- return true;
- }
- };
-
- item_list.setOnItemLongClickListener(itemLongListener);
-
- OnLongClickListener listener = new OnLongClickListener() {
-
- @Override
- public boolean onLongClick(View view) {
- AlertDialog.Builder dialog =
- new AlertDialog.Builder(MainActivity.this);
- dialog.setTitle(R.string.app_name)
- .setMessage(R.string.about)
- .show();
- return false;
- }
-
- };
-
- show_app_name.setOnLongClickListener(listener);
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- MenuInflater menuInflater = getMenuInflater();
- menuInflater.inflate(R.menu.main_menu, menu);
-
- add_item = menu.findItem(R.id.add_item);
- search_item = menu.findItem(R.id.search_item);
- revert_item = menu.findItem(R.id.revert_item);
- share_item = menu.findItem(R.id.share_item);
- delete_item = menu.findItem(R.id.delete_item);
-
- processMenu(null);
-
- return true;
- }
-
- public void clickMenuItem(MenuItem item) {
- int itemId = item.getItemId();
-
- switch (itemId) {
- case R.id.search_item:
- break;
- case R.id.add_item:
- Intent intent = new Intent("net.macdidi.myandroidtutorial.ADD_ITEM");
- startActivityForResult(intent, 0);
- break;
- case R.id.revert_item:
- for (int i = 0; i < itemAdapter.getCount(); i++) {
- Item ri = itemAdapter.getItem(i);
-
- if (ri.isSelected()) {
- ri.setSelected(false);
- itemAdapter.set(i, ri);
- }
- }
-
- selectedCount = 0;
- processMenu(null);
-
- break;
- case R.id.delete_item:
- if (selectedCount == 0) {
- break;
- }
-
- AlertDialog.Builder d = new AlertDialog.Builder(this);
- String message = getString(R.string.delete_item);
- d.setTitle(R.string.delete)
- .setMessage(String.format(message, selectedCount));
- d.setPositiveButton(android.R.string.yes,
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- // 取得最後一個元素的編號
- int index = itemAdapter.getCount() - 1;
-
- while (index > -1) {
- Item item = itemAdapter.get(index);
-
- if (item.isSelected()) {
- itemAdapter.remove(item);
- // 刪除資料庫中的記事資料
- itemDAO.delete(item.getId());
- }
-
- index--;
- }
-
- itemAdapter.notifyDataSetChanged();
- }
- });
- d.setNegativeButton(android.R.string.no, null);
- d.show();
-
- break;
- case R.id.googleplus_item:
- break;
- case R.id.facebook_item:
- break;
- }
- }
-
- public void clickPreferences(MenuItem item) {
- startActivity(new Intent(this, PrefActivity.class));
- }
-
- private void processMenu(Item item) {
- if (item != null) {
- item.setSelected(!item.isSelected());
-
- if (item.isSelected()) {
- selectedCount++;
- }
- else {
- selectedCount--;
- }
- }
-
- add_item.setVisible(selectedCount == 0);
- search_item.setVisible(selectedCount == 0);
- revert_item.setVisible(selectedCount > 0);
- share_item.setVisible(selectedCount > 0);
- delete_item.setVisible(selectedCount > 0);
- }
-
- public void aboutApp(View view) {
- Intent intent = new Intent(this, AboutActivity.class);
- startActivity(intent);
- }
-}
diff --git a/examples/0304/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/MyDBHelper.java b/examples/0304/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/MyDBHelper.java
deleted file mode 100644
index bfd1b06..0000000
--- a/examples/0304/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/MyDBHelper.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package net.macdidi.myandroidtutorial;
-
-import android.content.Context;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteDatabase.CursorFactory;
-import android.database.sqlite.SQLiteOpenHelper;
-
-public class MyDBHelper extends SQLiteOpenHelper {
-
- // 資料庫名稱
- public static final String DATABASE_NAME = "mydata.db";
- // 資料庫版本,資料結構改變的時候要更改這個數字,通常是加一
- public static final int VERSION = 1;
- // 資料庫物件,固定的欄位變數
- private static SQLiteDatabase database;
-
- // 建構子,在一般的應用都不需要修改
- public MyDBHelper(Context context, String name, CursorFactory factory,
- int version) {
- super(context, name, factory, version);
- }
-
- // 需要資料庫的元件呼叫這個方法,這個方法在一般的應用都不需要修改
- public static SQLiteDatabase getDatabase(Context context) {
- if (database == null || !database.isOpen()) {
- database = new MyDBHelper(context, DATABASE_NAME,
- null, VERSION).getWritableDatabase();
- }
-
- return database;
- }
-
- @Override
- public void onCreate(SQLiteDatabase db) {
- // 建立應用程式需要的表格
- db.execSQL(ItemDAO.CREATE_TABLE);
- }
-
- @Override
- public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
- // 刪除原有的表格
- db.execSQL("DROP TABLE IF EXISTS " + ItemDAO.TABLE_NAME);
- // 呼叫onCreate建立新版的表格
- onCreate(db);
- }
-
-}
diff --git a/examples/0304/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/PrefActivity.java b/examples/0304/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/PrefActivity.java
deleted file mode 100644
index aa37810..0000000
--- a/examples/0304/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/PrefActivity.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package net.macdidi.myandroidtutorial;
-
-import android.content.SharedPreferences;
-import android.os.Bundle;
-import android.preference.Preference;
-import android.preference.PreferenceActivity;
-import android.preference.PreferenceManager;
-
-public class PrefActivity extends PreferenceActivity {
-
- private SharedPreferences sharedPreferences;
- private Preference defaultColor;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- // 指定使用的設定畫面配置資源
- addPreferencesFromResource(R.xml.mypreference);
- defaultColor = (Preference)findPreference("DEFAULT_COLOR");
- // 建立SharedPreferences物件
- sharedPreferences =
- PreferenceManager.getDefaultSharedPreferences(this);
- }
-
- @Override
- protected void onResume() {
- super.onResume();
- // 讀取設定的預設顏色
- int color = sharedPreferences.getInt("DEFAULT_COLOR", -1);
-
- if (color != -1) {
- // 設定顏色說明
- defaultColor.setSummary(getString(R.string.default_color_summary) +
- ": " + ItemActivity.getColors(color));
- }
- }
-
-}
diff --git a/examples/0401/MyAndroidTutorial/.classpath b/examples/0401/MyAndroidTutorial/.classpath
deleted file mode 100755
index 7bc01d9..0000000
--- a/examples/0401/MyAndroidTutorial/.classpath
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
-
-
-
-
diff --git a/examples/0401/MyAndroidTutorial/.gitignore b/examples/0401/MyAndroidTutorial/.gitignore
new file mode 100644
index 0000000..afbdab3
--- /dev/null
+++ b/examples/0401/MyAndroidTutorial/.gitignore
@@ -0,0 +1,6 @@
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
diff --git a/examples/0401/MyAndroidTutorial/.idea/.name b/examples/0401/MyAndroidTutorial/.idea/.name
new file mode 100644
index 0000000..5bb7a85
--- /dev/null
+++ b/examples/0401/MyAndroidTutorial/.idea/.name
@@ -0,0 +1 @@
+MyAndroidTutorial
\ No newline at end of file
diff --git a/examples/0401/MyAndroidTutorial/.idea/compiler.xml b/examples/0401/MyAndroidTutorial/.idea/compiler.xml
new file mode 100644
index 0000000..217af47
--- /dev/null
+++ b/examples/0401/MyAndroidTutorial/.idea/compiler.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0401/MyAndroidTutorial/.idea/copyright/profiles_settings.xml b/examples/0401/MyAndroidTutorial/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..e7bedf3
--- /dev/null
+++ b/examples/0401/MyAndroidTutorial/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/examples/0401/MyAndroidTutorial/.idea/encodings.xml b/examples/0401/MyAndroidTutorial/.idea/encodings.xml
new file mode 100644
index 0000000..e206d70
--- /dev/null
+++ b/examples/0401/MyAndroidTutorial/.idea/encodings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/examples/0401/MyAndroidTutorial/.idea/gradle.xml b/examples/0401/MyAndroidTutorial/.idea/gradle.xml
new file mode 100644
index 0000000..fe865d3
--- /dev/null
+++ b/examples/0401/MyAndroidTutorial/.idea/gradle.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0401/MyAndroidTutorial/.idea/misc.xml b/examples/0401/MyAndroidTutorial/.idea/misc.xml
new file mode 100644
index 0000000..9076de5
--- /dev/null
+++ b/examples/0401/MyAndroidTutorial/.idea/misc.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0401/MyAndroidTutorial/.idea/modules.xml b/examples/0401/MyAndroidTutorial/.idea/modules.xml
new file mode 100644
index 0000000..327df67
--- /dev/null
+++ b/examples/0401/MyAndroidTutorial/.idea/modules.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0401/MyAndroidTutorial/.idea/scopes/scope_settings.xml b/examples/0401/MyAndroidTutorial/.idea/scopes/scope_settings.xml
new file mode 100644
index 0000000..922003b
--- /dev/null
+++ b/examples/0401/MyAndroidTutorial/.idea/scopes/scope_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0401/MyAndroidTutorial/.idea/vcs.xml b/examples/0401/MyAndroidTutorial/.idea/vcs.xml
new file mode 100644
index 0000000..def6a6a
--- /dev/null
+++ b/examples/0401/MyAndroidTutorial/.idea/vcs.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/examples/0401/MyAndroidTutorial/.project b/examples/0401/MyAndroidTutorial/.project
deleted file mode 100755
index b1de407..0000000
--- a/examples/0401/MyAndroidTutorial/.project
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
- MyAndroidTutorial
-
-
-
-
-
- com.android.ide.eclipse.adt.ResourceManagerBuilder
-
-
-
-
- com.android.ide.eclipse.adt.PreCompilerBuilder
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- com.android.ide.eclipse.adt.ApkBuilder
-
-
-
-
-
- com.android.ide.eclipse.adt.AndroidNature
- org.eclipse.jdt.core.javanature
-
-
diff --git a/examples/0401/MyAndroidTutorial/.settings/org.eclipse.core.resources.prefs b/examples/0401/MyAndroidTutorial/.settings/org.eclipse.core.resources.prefs
deleted file mode 100644
index 2d63e5e..0000000
--- a/examples/0401/MyAndroidTutorial/.settings/org.eclipse.core.resources.prefs
+++ /dev/null
@@ -1,4 +0,0 @@
-eclipse.preferences.version=1
-encoding//src/net/macdidi/myandroidtutorial/PlayActivity.java=UTF-8
-encoding//src/net/macdidi/myandroidtutorial/RecordActivity.java=UTF-8
-encoding/=UTF-8
diff --git a/examples/0401/MyAndroidTutorial/AndroidManifest.xml b/examples/0401/MyAndroidTutorial/AndroidManifest.xml
deleted file mode 100755
index adde1ff..0000000
--- a/examples/0401/MyAndroidTutorial/AndroidManifest.xml
+++ /dev/null
@@ -1,74 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/examples/0401/MyAndroidTutorial/MyAndroidTutorial.iml b/examples/0401/MyAndroidTutorial/MyAndroidTutorial.iml
new file mode 100644
index 0000000..42f4ed5
--- /dev/null
+++ b/examples/0401/MyAndroidTutorial/MyAndroidTutorial.iml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0401/MyAndroidTutorial/app/.gitignore b/examples/0401/MyAndroidTutorial/app/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/examples/0401/MyAndroidTutorial/app/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/examples/0401/MyAndroidTutorial/app/app.iml b/examples/0401/MyAndroidTutorial/app/app.iml
new file mode 100644
index 0000000..86cbf3a
--- /dev/null
+++ b/examples/0401/MyAndroidTutorial/app/app.iml
@@ -0,0 +1,93 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0401/MyAndroidTutorial/app/build.gradle b/examples/0401/MyAndroidTutorial/app/build.gradle
new file mode 100644
index 0000000..b09f064
--- /dev/null
+++ b/examples/0401/MyAndroidTutorial/app/build.gradle
@@ -0,0 +1,25 @@
+apply plugin: 'com.android.application'
+
+android {
+ compileSdkVersion 21
+ buildToolsVersion "21.1.2"
+
+ defaultConfig {
+ applicationId "net.macdidi.myandroidtutorial"
+ minSdkVersion 15
+ targetSdkVersion 21
+ versionCode 1
+ versionName "1.0"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ compile fileTree(dir: 'libs', include: ['*.jar'])
+ compile 'com.android.support:appcompat-v7:21.0.3'
+}
diff --git a/examples/0401/MyAndroidTutorial/app/proguard-rules.pro b/examples/0401/MyAndroidTutorial/app/proguard-rules.pro
new file mode 100644
index 0000000..b5fa7ec
--- /dev/null
+++ b/examples/0401/MyAndroidTutorial/app/proguard-rules.pro
@@ -0,0 +1,17 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /Users/macdidi5/Library/Android/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
diff --git a/examples/0401/MyAndroidTutorial/app/src/androidTest/java/net/macdidi/myandroidtutorial/ApplicationTest.java b/examples/0401/MyAndroidTutorial/app/src/androidTest/java/net/macdidi/myandroidtutorial/ApplicationTest.java
new file mode 100644
index 0000000..2cb214e
--- /dev/null
+++ b/examples/0401/MyAndroidTutorial/app/src/androidTest/java/net/macdidi/myandroidtutorial/ApplicationTest.java
@@ -0,0 +1,13 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Application;
+import android.test.ApplicationTestCase;
+
+/**
+ * Testing Fundamentals
+ */
+public class ApplicationTest extends ApplicationTestCase {
+ public ApplicationTest() {
+ super(Application.class);
+ }
+}
\ No newline at end of file
diff --git a/examples/0401/MyAndroidTutorial/app/src/main/AndroidManifest.xml b/examples/0401/MyAndroidTutorial/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..a591634
--- /dev/null
+++ b/examples/0401/MyAndroidTutorial/app/src/main/AndroidManifest.xml
@@ -0,0 +1,70 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0401/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/AboutActivity.java b/examples/0401/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/AboutActivity.java
new file mode 100644
index 0000000..42dddeb
--- /dev/null
+++ b/examples/0401/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/AboutActivity.java
@@ -0,0 +1,24 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.view.Window;
+
+public class AboutActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ // 取消元件的應用程式標題
+ requestWindowFeature(Window.FEATURE_NO_TITLE);
+ setContentView(R.layout.activity_about);
+ }
+
+ // 結束按鈕
+ public void clickOk(View view) {
+ // 呼叫這個方法結束Activity元件
+ finish();
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0401/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ColorActivity.java b/examples/0401/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ColorActivity.java
new file mode 100644
index 0000000..182cd55
--- /dev/null
+++ b/examples/0401/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ColorActivity.java
@@ -0,0 +1,75 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.LinearLayout;
+
+public class ColorActivity extends Activity {
+
+ private LinearLayout color_gallery;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_color);
+
+ processViews();
+
+ ColorListener listener = new ColorListener();
+
+ for (Colors c : Colors.values()) {
+ Button button = new Button(this);
+ button.setId(c.parseColor());
+ LinearLayout.LayoutParams layout =
+ new LinearLayout.LayoutParams(128, 128);
+ layout.setMargins(6, 6, 6, 6);
+ button.setLayoutParams(layout);
+ button.setBackgroundColor(c.parseColor());
+
+ button.setOnClickListener(listener);
+
+ color_gallery.addView(button);
+ }
+ }
+
+ private void processViews() {
+ color_gallery = (LinearLayout) findViewById(R.id.color_gallery);
+ }
+
+ private class ColorListener implements OnClickListener {
+
+ @Override
+ public void onClick(View view) {
+ String action = ColorActivity.this.getIntent().getAction();
+
+ // 經由設定元件啟動
+ if (action != null &&
+ action.equals("net.macdidi.myandroidtutorial.CHOOSE_COLOR")) {
+ // 建立SharedPreferences物件
+ SharedPreferences.Editor editor =
+ PreferenceManager.getDefaultSharedPreferences(
+ ColorActivity.this).edit();
+ // 儲存預設顏色
+ editor.putInt("DEFAULT_COLOR", view.getId());
+ // 寫入設定值
+ editor.commit();
+ finish();
+ }
+ // 經由新增或修改記事的元件啟動
+ else {
+ Intent result = getIntent();
+ result.putExtra("colorId", view.getId());
+ setResult(Activity.RESULT_OK, result);
+ finish();
+ }
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0401/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Colors.java b/examples/0401/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Colors.java
new file mode 100644
index 0000000..1462149
--- /dev/null
+++ b/examples/0401/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Colors.java
@@ -0,0 +1,24 @@
+package net.macdidi.myandroidtutorial;
+
+import android.graphics.Color;
+
+public enum Colors {
+
+ LIGHTGREY("#D3D3D3"), BLUE("#33B5E5"), PURPLE("#AA66CC"),
+ GREEN("#99CC00"), ORANGE("#FFBB33"), RED("#FF4444");
+
+ private String code;
+
+ private Colors(String code) {
+ this.code = code;
+ }
+
+ public String getCode() {
+ return code;
+ }
+
+ public int parseColor() {
+ return Color.parseColor(code);
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0401/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/FileUtil.java b/examples/0401/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/FileUtil.java
new file mode 100644
index 0000000..1fb41be
--- /dev/null
+++ b/examples/0401/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/FileUtil.java
@@ -0,0 +1,112 @@
+package net.macdidi.myandroidtutorial;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.os.Environment;
+import android.util.Log;
+import android.widget.ImageView;
+
+import java.io.File;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+public class FileUtil {
+
+ // 應用程式儲存檔案的目錄
+ public static final String APP_DIR = "androidtutorial";
+
+ // 外部儲存設備是否可寫入
+ public static boolean isExternalStorageWritable() {
+ // 取得目前外部儲存設備的狀態
+ String state = Environment.getExternalStorageState();
+
+ // 判斷是否可寫入
+ if (Environment.MEDIA_MOUNTED.equals(state)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ // 外部儲存設備是否可讀取
+ public static boolean isExternalStorageReadable() {
+ // 取得目前外部儲存設備的狀態
+ String state = Environment.getExternalStorageState();
+
+ // 判斷是否可讀取
+ if (Environment.MEDIA_MOUNTED.equals(state) ||
+ Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ // 建立並傳回在公用相簿下參數指定的路徑
+ public static File getPublicAlbumStorageDir(String albumName) {
+ // 取得公用的照片路徑
+ File pictures = Environment.getExternalStoragePublicDirectory(
+ Environment.DIRECTORY_PICTURES);
+ // 準備在照片路徑下建立一個指定的路徑
+ File file = new File(pictures, albumName);
+
+ // 如果建立路徑不成功
+ if (!file.mkdirs()) {
+ Log.e("getAlbumStorageDir", "Directory not created");
+ }
+
+ return file;
+ }
+
+ // 建立並傳回在應用程式專用相簿下參數指定的路徑
+ public static File getAlbumStorageDir(Context context, String albumName) {
+ // 取得應用程式專用的照片路徑
+ File pictures = context.getExternalFilesDir(
+ Environment.DIRECTORY_PICTURES);
+ // 準備在照片路徑下建立一個指定的路徑
+ File file = new File(pictures, albumName);
+
+ // 如果建立路徑不成功
+ if (!file.mkdirs()) {
+ Log.e("getAlbumStorageDir", "Directory not created");
+ }
+
+ return file;
+ }
+
+ // 建立並傳回外部儲存媒體參數指定的路徑
+ public static File getExternalStorageDir(String dir) {
+ File result = new File(
+ Environment.getExternalStorageDirectory(), dir);
+
+ if (!isExternalStorageWritable()) {
+ return null;
+ }
+
+ if (!result.exists() && !result.mkdirs()) {
+ return null;
+ }
+
+ return result;
+ }
+
+ // 讀取指定的照片檔案名稱設定給ImageView元件
+ public static void fileToImageView(String fileName, ImageView imageView) {
+ if (new File(fileName).exists()) {
+ Bitmap bitmap = BitmapFactory.decodeFile(fileName);
+ imageView.setImageBitmap(bitmap);
+ }
+ else {
+ Log.e("fileToImageView", fileName + " not found.");
+ }
+ }
+
+ // 產生唯一的檔案名稱
+ public static String getUniqueFileName() {
+ // 使用年月日_時分秒格式為檔案名稱
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
+ return sdf.format(new Date());
+ }
+
+}
diff --git a/examples/0401/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Item.java b/examples/0401/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Item.java
new file mode 100644
index 0000000..7fa030a
--- /dev/null
+++ b/examples/0401/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Item.java
@@ -0,0 +1,145 @@
+package net.macdidi.myandroidtutorial;
+
+import java.util.Date;
+import java.util.Locale;
+
+public class Item implements java.io.Serializable {
+
+ // 編號、日期時間、顏色、標題、內容、檔案名稱、錄音檔案名稱、經緯度、修改、已選擇
+ private long id;
+ private long datetime;
+ private Colors color;
+ private String title;
+ private String content;
+ private String fileName;
+ private String recFileName;
+ private double latitude;
+ private double longitude;
+ private long lastModify;
+ private boolean selected;
+
+ public Item() {
+ title = "";
+ content = "";
+ color = Colors.LIGHTGREY;
+ }
+
+ public Item(long id, long datetime, Colors color, String title,
+ String content, String fileName, String recFileName,
+ double latitude, double longitude, long lastModify) {
+ this.id = id;
+ this.datetime = datetime;
+ this.color = color;
+ this.title = title;
+ this.content = content;
+ this.fileName = fileName;
+ this.recFileName = recFileName;
+ this.latitude = latitude;
+ this.longitude = longitude;
+ this.lastModify = lastModify;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public long getDatetime() {
+ return datetime;
+ }
+
+ // 裝置區域的日期時間
+ public String getLocaleDatetime() {
+ return String.format(Locale.getDefault(), "%tF % 0) {
+ // 照片檔案物件
+ File file = configFileName("P", ".jpg");
+
+ // 如果照片檔案存在
+ if (file.exists()) {
+ // 顯示照片元件
+ picture.setVisibility(View.VISIBLE);
+ // 設定照片
+ FileUtil.fileToImageView(file.getAbsolutePath(), picture);
+ }
+ }
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (resultCode == Activity.RESULT_OK) {
+ switch (requestCode) {
+ // 照像
+ case START_CAMERA:
+ // 設定照片檔案名稱
+ item.setFileName(fileName);
+ break;
+ case START_RECORD:
+ // 設定錄音檔案名稱
+ item.setRecFileName(recFileName);
+ break;
+ case START_LOCATION:
+ break;
+ case START_ALARM:
+ break;
+ // 設定顏色
+ case START_COLOR:
+ int colorId = data.getIntExtra(
+ "colorId", Colors.LIGHTGREY.parseColor());
+ item.setColor(getColors(colorId));
+ break;
+ }
+ }
+ }
+
+ public static Colors getColors(int color) {
+ Colors result = Colors.LIGHTGREY;
+
+ if (color == Colors.BLUE.parseColor()) {
+ result = Colors.BLUE;
+ }
+ else if (color == Colors.PURPLE.parseColor()) {
+ result = Colors.PURPLE;
+ }
+ else if (color == Colors.GREEN.parseColor()) {
+ result = Colors.GREEN;
+ }
+ else if (color == Colors.ORANGE.parseColor()) {
+ result = Colors.ORANGE;
+ }
+ else if (color == Colors.RED.parseColor()) {
+ result = Colors.RED;
+ }
+
+ return result;
+ }
+
+ private void processViews() {
+ title_text = (EditText) findViewById(R.id.title_text);
+ content_text = (EditText) findViewById(R.id.content_text);
+ // 取得顯示照片的ImageView元件
+ picture = (ImageView) findViewById(R.id.picture);
+ }
+
+ // 點擊確定與取消按鈕都會呼叫這個方法
+ public void onSubmit(View view) {
+
+ if (view.getId() == R.id.ok_teim) {
+ String titleText = title_text.getText().toString();
+ String contentText = content_text.getText().toString();
+
+ item.setTitle(titleText);
+ item.setContent(contentText);
+
+ if (getIntent().getAction().equals(
+ "net.macdidi.myandroidtutorial.EDIT_ITEM")) {
+ item.setLastModify(new Date().getTime());
+ }
+ // 新增記事
+ else {
+ item.setDatetime(new Date().getTime());
+ // 建立SharedPreferences物件
+ SharedPreferences sharedPreferences =
+ PreferenceManager.getDefaultSharedPreferences(this);
+ // 讀取設定的預設顏色
+ int color = sharedPreferences.getInt("DEFAULT_COLOR", -1);
+ item.setColor(getColors(color));
+ }
+
+ Intent result = getIntent();
+ result.putExtra("net.macdidi.myandroidtutorial.Item", item);
+ setResult(Activity.RESULT_OK, result);
+ }
+
+ // 結束
+ finish();
+ }
+
+ public void clickFunction(View view) {
+ int id = view.getId();
+
+ switch (id) {
+ case R.id.take_picture:
+ // 啟動相機元件用的Intent物件
+ Intent intentCamera =
+ new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
+
+ // 照片檔案名稱
+ File pictureFile = configFileName("P", ".jpg");
+ Uri uri = Uri.fromFile(pictureFile);
+ // 設定檔案名稱
+ intentCamera.putExtra(MediaStore.EXTRA_OUTPUT, uri);
+ // 啟動相機元件
+ startActivityForResult(intentCamera, START_CAMERA);
+ break;
+ case R.id.record_sound:
+ // 錄音檔案名稱
+ final File recordFile = configRecFileName("R", ".mp3");
+
+ // 如果已經有錄音檔,詢問播放或重新錄製
+ if (recordFile.exists()) {
+ // 詢問播放還是重新錄製的對話框
+ AlertDialog.Builder d = new AlertDialog.Builder(this);
+
+ d.setTitle(R.string.title_record)
+ .setCancelable(false);
+ d.setPositiveButton(R.string.record_play,
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ // 播放
+ Intent playIntent = new Intent(
+ ItemActivity.this, PlayActivity.class);
+ playIntent.putExtra("fileName",
+ recordFile.getAbsolutePath());
+ startActivity(playIntent);
+ }
+ });
+ d.setNeutralButton(R.string.record_new,
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ goToRecord(recordFile);
+ }
+ });
+ d.setNegativeButton(android.R.string.cancel, null);
+
+ // 顯示對話框
+ d.show();
+ }
+ // 如果沒有錄音檔,啟動錄音元件
+ else {
+ goToRecord(recordFile);
+ }
+
+ break;
+ case R.id.set_location:
+ break;
+ case R.id.set_alarm:
+ break;
+ case R.id.select_color:
+ // 啟動設定顏色的Activity元件
+ startActivityForResult(
+ new Intent(this, ColorActivity.class), START_COLOR);
+ break;
+ }
+
+ }
+
+ private void goToRecord(File recordFile) {
+ // 錄音
+ Intent recordIntent = new Intent(this, RecordActivity.class);
+ recordIntent.putExtra("fileName", recordFile.getAbsolutePath());
+ startActivityForResult(recordIntent, START_RECORD);
+ }
+
+ private File configFileName(String prefix, String extension) {
+ // 如果記事資料已經有檔案名稱
+ if (item.getFileName() != null && item.getFileName().length() > 0) {
+ fileName = item.getFileName();
+ }
+ // 產生檔案名稱
+ else {
+ fileName = FileUtil.getUniqueFileName();
+ }
+
+ return new File(FileUtil.getExternalStorageDir(FileUtil.APP_DIR),
+ prefix + fileName + extension);
+ }
+
+ private File configRecFileName(String prefix, String extension) {
+ // 如果記事資料已經有檔案名稱
+ if (item.getRecFileName() != null && item.getRecFileName().length() > 0) {
+ recFileName = item.getRecFileName();
+ }
+ // 產生檔案名稱
+ else {
+ recFileName = FileUtil.getUniqueFileName();
+ }
+
+ return new File(FileUtil.getExternalStorageDir(FileUtil.APP_DIR),
+ prefix + recFileName + extension);
+ }
+
+}
diff --git a/examples/0401/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemAdapter.java b/examples/0401/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemAdapter.java
new file mode 100644
index 0000000..85b40ba
--- /dev/null
+++ b/examples/0401/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemAdapter.java
@@ -0,0 +1,80 @@
+package net.macdidi.myandroidtutorial;
+
+import android.content.Context;
+import android.graphics.drawable.GradientDrawable;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+import java.util.List;
+
+public class ItemAdapter extends ArrayAdapter- {
+
+ // 畫面資源編號
+ private int resource;
+ // 包裝的記事資料
+ private List
- items;
+
+ public ItemAdapter(Context context, int resource, List
- items) {
+ super(context, resource, items);
+ this.resource = resource;
+ this.items = items;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ LinearLayout itemView;
+ // 讀取目前位置的記事物件
+ final Item item = getItem(position);
+
+ if (convertView == null) {
+ // 建立項目畫面元件
+ itemView = new LinearLayout(getContext());
+ String inflater = Context.LAYOUT_INFLATER_SERVICE;
+ LayoutInflater li = (LayoutInflater)
+ getContext().getSystemService(inflater);
+ li.inflate(resource, itemView, true);
+ }
+ else {
+ itemView = (LinearLayout) convertView;
+ }
+
+ // 讀取記事顏色、已選擇、標題與日期時間元件
+ RelativeLayout typeColor = (RelativeLayout) itemView.findViewById(R.id.type_color);
+ ImageView selectedItem = (ImageView) itemView.findViewById(R.id.selected_item);
+ TextView titleView = (TextView) itemView.findViewById(R.id.title_text);
+ TextView dateView = (TextView) itemView.findViewById(R.id.date_text);
+
+ // 設定記事顏色
+ GradientDrawable background = (GradientDrawable)typeColor.getBackground();
+ background.setColor(item.getColor().parseColor());
+
+ // 設定標題與日期時間
+ titleView.setText(item.getTitle());
+ dateView.setText(item.getLocaleDatetime());
+
+ // 設定是否已選擇
+ selectedItem.setVisibility(item.isSelected() ? View.VISIBLE : View.INVISIBLE);
+
+ return itemView;
+ }
+
+ // 設定指定編號的記事資料
+ public void set(int index, Item item) {
+ if (index >= 0 && index < items.size()) {
+ items.set(index, item);
+ notifyDataSetChanged();
+ }
+ }
+
+ // 讀取指定編號的記事資料
+ public Item get(int index) {
+ return items.get(index);
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0401/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemDAO.java b/examples/0401/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemDAO.java
new file mode 100644
index 0000000..ac5a57a
--- /dev/null
+++ b/examples/0401/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemDAO.java
@@ -0,0 +1,201 @@
+package net.macdidi.myandroidtutorial;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+// 資料功能類別
+public class ItemDAO {
+ // 表格名稱
+ public static final String TABLE_NAME = "item";
+
+ // 編號表格欄位名稱,固定不變
+ public static final String KEY_ID = "_id";
+
+ // 其它表格欄位名稱
+ public static final String DATETIME_COLUMN = "datetime";
+ public static final String COLOR_COLUMN = "color";
+ public static final String TITLE_COLUMN = "title";
+ public static final String CONTENT_COLUMN = "content";
+ public static final String FILENAME_COLUMN = "filename";
+ public static final String RECFILENAME_COLUMN = "recfilename";
+ public static final String LATITUDE_COLUMN = "latitude";
+ public static final String LONGITUDE_COLUMN = "longitude";
+ public static final String LASTMODIFY_COLUMN = "lastmodify";
+
+ // 使用上面宣告的變數建立表格的SQL指令
+ public static final String CREATE_TABLE =
+ "CREATE TABLE " + TABLE_NAME + " (" +
+ KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
+ DATETIME_COLUMN + " INTEGER NOT NULL, " +
+ COLOR_COLUMN + " INTEGER NOT NULL, " +
+ TITLE_COLUMN + " TEXT NOT NULL, " +
+ CONTENT_COLUMN + " TEXT NOT NULL, " +
+ FILENAME_COLUMN + " TEXT, " +
+ RECFILENAME_COLUMN + " TEXT, " +
+ LATITUDE_COLUMN + " REAL, " +
+ LONGITUDE_COLUMN + " REAL, " +
+ LASTMODIFY_COLUMN + " INTEGER)";
+
+ // 資料庫物件
+ private SQLiteDatabase db;
+
+ // 建構子,一般的應用都不需要修改
+ public ItemDAO(Context context) {
+ db = MyDBHelper.getDatabase(context);
+ }
+
+ // 關閉資料庫,一般的應用都不需要修改
+ public void close() {
+ db.close();
+ }
+
+ // 新增參數指定的物件
+ public Item insert(Item item) {
+ // 建立準備新增資料的ContentValues物件
+ ContentValues cv = new ContentValues();
+
+ // 加入ContentValues物件包裝的新增資料
+ // 第一個參數是欄位名稱, 第二個參數是欄位的資料
+ cv.put(DATETIME_COLUMN, item.getDatetime());
+ cv.put(COLOR_COLUMN, item.getColor().parseColor());
+ cv.put(TITLE_COLUMN, item.getTitle());
+ cv.put(CONTENT_COLUMN, item.getContent());
+ cv.put(FILENAME_COLUMN, item.getFileName());
+ cv.put(RECFILENAME_COLUMN, item.getRecFileName());
+ cv.put(LATITUDE_COLUMN, item.getLatitude());
+ cv.put(LONGITUDE_COLUMN, item.getLongitude());
+ cv.put(LASTMODIFY_COLUMN, item.getLastModify());
+
+ // 新增一筆資料並取得編號
+ // 第一個參數是表格名稱
+ // 第二個參數是沒有指定欄位值的預設值
+ // 第三個參數是包裝新增資料的ContentValues物件
+ long id = db.insert(TABLE_NAME, null, cv);
+
+ // 設定編號
+ item.setId(id);
+ // 回傳結果
+ return item;
+ }
+
+ // 修改參數指定的物件
+ public boolean update(Item item) {
+ // 建立準備修改資料的ContentValues物件
+ ContentValues cv = new ContentValues();
+
+ // 加入ContentValues物件包裝的修改資料
+ // 第一個參數是欄位名稱, 第二個參數是欄位的資料
+ cv.put(DATETIME_COLUMN, item.getDatetime());
+ cv.put(COLOR_COLUMN, item.getColor().parseColor());
+ cv.put(TITLE_COLUMN, item.getTitle());
+ cv.put(CONTENT_COLUMN, item.getContent());
+ cv.put(FILENAME_COLUMN, item.getFileName());
+ cv.put(RECFILENAME_COLUMN, item.getRecFileName());
+ cv.put(LATITUDE_COLUMN, item.getLatitude());
+ cv.put(LONGITUDE_COLUMN, item.getLongitude());
+ cv.put(LASTMODIFY_COLUMN, item.getLastModify());
+
+ // 設定修改資料的條件為編號
+ // 格式為「欄位名稱=資料」
+ String where = KEY_ID + "=" + item.getId();
+
+ // 執行修改資料並回傳修改的資料數量是否成功
+ return db.update(TABLE_NAME, cv, where, null) > 0;
+ }
+
+ // 刪除參數指定編號的資料
+ public boolean delete(long id){
+ // 設定條件為編號,格式為「欄位名稱=資料」
+ String where = KEY_ID + "=" + id;
+ // 刪除指定編號資料並回傳刪除是否成功
+ return db.delete(TABLE_NAME, where , null) > 0;
+ }
+
+ // 讀取所有記事資料
+ public List
- getAll() {
+ List
- result = new ArrayList<>();
+ Cursor cursor = db.query(
+ TABLE_NAME, null, null, null, null, null, null, null);
+
+ while (cursor.moveToNext()) {
+ result.add(getRecord(cursor));
+ }
+
+ cursor.close();
+ return result;
+ }
+
+ // 取得指定編號的資料物件
+ public Item get(long id) {
+ // 準備回傳結果用的物件
+ Item item = null;
+ // 使用編號為查詢條件
+ String where = KEY_ID + "=" + id;
+ // 執行查詢
+ Cursor result = db.query(
+ TABLE_NAME, null, where, null, null, null, null, null);
+
+ // 如果有查詢結果
+ if (result.moveToFirst()) {
+ // 讀取包裝一筆資料的物件
+ item = getRecord(result);
+ }
+
+ // 關閉Cursor物件
+ result.close();
+ // 回傳結果
+ return item;
+ }
+
+ // 把Cursor目前的資料包裝為物件
+ public Item getRecord(Cursor cursor) {
+ // 準備回傳結果用的物件
+ Item result = new Item();
+
+ result.setId(cursor.getLong(0));
+ result.setDatetime(cursor.getLong(1));
+ result.setColor(ItemActivity.getColors(cursor.getInt(2)));
+ result.setTitle(cursor.getString(3));
+ result.setContent(cursor.getString(4));
+ result.setFileName(cursor.getString(5));
+ result.setRecFileName(cursor.getString(6));
+ result.setLatitude(cursor.getDouble(7));
+ result.setLongitude(cursor.getDouble(8));
+ result.setLastModify(cursor.getLong(9));
+
+ // 回傳結果
+ return result;
+ }
+
+ // 取得資料數量
+ public int getCount() {
+ int result = 0;
+ Cursor cursor = db.rawQuery("SELECT COUNT(*) FROM " + TABLE_NAME, null);
+
+ if (cursor.moveToNext()) {
+ result = cursor.getInt(0);
+ }
+
+ return result;
+ }
+
+ // 建立範例資料
+ public void sample() {
+ Item item = new Item(0, new Date().getTime(), Colors.RED, "關於Android Tutorial的事情.", "Hello content", "", "", 0, 0, 0);
+ Item item2 = new Item(0, new Date().getTime(), Colors.BLUE, "一隻非常可愛的小狗狗!", "她的名字叫「大熱狗」,又叫\n作「奶嘴」,是一隻非常可愛\n的小狗。", "", "", 25.04719, 121.516981, 0);
+ Item item3 = new Item(0, new Date().getTime(), Colors.GREEN, "一首非常好聽的音樂!", "Hello content", "", "", 0, 0, 0);
+ Item item4 = new Item(0, new Date().getTime(), Colors.ORANGE, "儲存在資料庫的資料", "Hello content", "", "", 0, 0, 0);
+
+ insert(item);
+ insert(item2);
+ insert(item3);
+ insert(item4);
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0401/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MainActivity.java b/examples/0401/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MainActivity.java
new file mode 100644
index 0000000..2a30f6a
--- /dev/null
+++ b/examples/0401/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MainActivity.java
@@ -0,0 +1,302 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.v7.app.ActionBarActivity;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import java.util.List;
+
+public class MainActivity extends ActionBarActivity {
+ private ListView item_list;
+ private TextView show_app_name;
+
+ // ListView使用的自定Adapter物件
+ private ItemAdapter itemAdapter;
+ // 儲存所有記事本的List物件
+ private List
- items;
+
+ // 選單項目物件
+ private MenuItem add_item, search_item, revert_item, share_item, delete_item;
+
+ // 已選擇項目數量
+ private int selectedCount = 0;
+
+ // 宣告資料庫功能類別欄位變數
+ private ItemDAO itemDAO;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ processViews();
+ processControllers();
+
+ // 建立資料庫物件
+ itemDAO = new ItemDAO(getApplicationContext());
+
+ // 如果資料庫是空的,就建立一些範例資料
+ // 這是為了方便測試用的,完成應用程式以後可以拿掉
+ if (itemDAO.getCount() == 0) {
+ itemDAO.sample();
+ }
+
+ // 取得所有記事資料
+ items = itemDAO.getAll();
+
+ itemAdapter = new ItemAdapter(this, R.layout.single_item, items);
+ item_list.setAdapter(itemAdapter);
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (resultCode == Activity.RESULT_OK) {
+ Item item = (Item) data.getExtras().getSerializable(
+ "net.macdidi.myandroidtutorial.Item");
+
+ if (requestCode == 0) {
+ // 新增記事資料到資料庫
+ item = itemDAO.insert(item);
+
+ items.add(item);
+ itemAdapter.notifyDataSetChanged();
+ }
+ else if (requestCode == 1) {
+ int position = data.getIntExtra("position", -1);
+
+ if (position != -1) {
+ // 修改資料庫中的記事資料
+ itemDAO.update(item);
+
+ items.set(position, item);
+ itemAdapter.notifyDataSetChanged();
+ }
+ }
+ }
+ }
+
+ private void processViews() {
+ item_list = (ListView)findViewById(R.id.item_list);
+ show_app_name = (TextView) findViewById(R.id.show_app_name);
+ }
+
+ private void processControllers() {
+
+ // 建立選單項目點擊監聽物件
+ AdapterView.OnItemClickListener itemListener = new AdapterView.OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView> parent, View view,
+ int position, long id) {
+ // 讀取選擇的記事物件
+ Item item = itemAdapter.getItem(position);
+
+ // 如果已經有勾選的項目
+ if (selectedCount > 0) {
+ // 處理是否顯示已選擇項目
+ processMenu(item);
+ // 重新設定記事項目
+ itemAdapter.set(position, item);
+ }
+ else {
+ Intent intent = new Intent(
+ "net.macdidi.myandroidtutorial.EDIT_ITEM");
+
+ // 設定記事編號與記事物件
+ intent.putExtra("position", position);
+ intent.putExtra("net.macdidi.myandroidtutorial.Item", item);
+
+ startActivityForResult(intent, 1);
+ }
+ }
+ };
+
+ // 註冊選單項目點擊監聽物件
+ item_list.setOnItemClickListener(itemListener);
+
+ // 建立記事項目長按監聽物件
+ AdapterView.OnItemLongClickListener itemLongListener = new AdapterView.OnItemLongClickListener() {
+ @Override
+ public boolean onItemLongClick(AdapterView> parent, View view,
+ int position, long id) {
+ // 讀取選擇的記事物件
+ Item item = itemAdapter.getItem(position);
+ // 處理是否顯示已選擇項目
+ processMenu(item);
+ // 重新設定記事項目
+ itemAdapter.set(position, item);
+ return true;
+ }
+ };
+
+ // 註冊記事項目長按監聽物件
+ item_list.setOnItemLongClickListener(itemLongListener);
+
+ // 建立長按監聽物件
+ View.OnLongClickListener listener = new View.OnLongClickListener() {
+
+ @Override
+ public boolean onLongClick(View view) {
+ AlertDialog.Builder dialog =
+ new AlertDialog.Builder(MainActivity.this);
+ dialog.setTitle(R.string.app_name)
+ .setMessage(R.string.about)
+ .show();
+ return false;
+ }
+
+ };
+
+ // 註冊長按監聽物件
+ show_app_name.setOnLongClickListener(listener);
+ }
+
+ // 處理是否顯示已選擇項目
+ private void processMenu(Item item) {
+ // 如果需要設定記事項目
+ if (item != null) {
+ // 設定已勾選的狀態
+ item.setSelected(!item.isSelected());
+
+ // 計算已勾選數量
+ if (item.isSelected()) {
+ selectedCount++;
+ }
+ else {
+ selectedCount--;
+ }
+ }
+
+ // 根據選擇的狀況,設定是否顯示選單項目
+ add_item.setVisible(selectedCount == 0);
+ search_item.setVisible(selectedCount == 0);
+ revert_item.setVisible(selectedCount > 0);
+ share_item.setVisible(selectedCount > 0);
+ delete_item.setVisible(selectedCount > 0);
+ }
+
+ // 載入選單資源
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ MenuInflater menuInflater = getMenuInflater();
+ menuInflater.inflate(R.menu.menu_main, menu);
+
+ // 取得選單項目物件
+ add_item = menu.findItem(R.id.add_item);
+ search_item = menu.findItem(R.id.search_item);
+ revert_item = menu.findItem(R.id.revert_item);
+ share_item = menu.findItem(R.id.share_item);
+ delete_item = menu.findItem(R.id.delete_item);
+
+ // 設定選單項目
+ processMenu(null);
+
+ return true;
+ }
+
+ // 使用者選擇所有的選單項目都會呼叫這個方法
+ public void clickMenuItem(MenuItem item) {
+ // 使用參數取得使用者選擇的選單項目元件編號
+ int itemId = item.getItemId();
+
+ // 判斷該執行什麼工作,目前還沒有加入需要執行的工作
+ switch (itemId) {
+ case R.id.search_item:
+ break;
+ // 使用者選擇新增選單項目
+ case R.id.add_item:
+ // 使用Action名稱建立啟動另一個Activity元件需要的Intent物件
+ Intent intent = new Intent("net.macdidi.myandroidtutorial.ADD_ITEM");
+ // 呼叫「startActivityForResult」,,第二個參數「0」表示執行新增
+ startActivityForResult(intent, 0);
+ break;
+ // 取消所有已勾選的項目
+ case R.id.revert_item:
+ for (int i = 0; i < itemAdapter.getCount(); i++) {
+ Item ri = itemAdapter.getItem(i);
+
+ if (ri.isSelected()) {
+ ri.setSelected(false);
+ itemAdapter.set(i, ri);
+ }
+ }
+
+ selectedCount = 0;
+ processMenu(null);
+
+ break;
+ // 刪除
+ case R.id.delete_item:
+ if (selectedCount == 0) {
+ break;
+ }
+
+ AlertDialog.Builder d = new AlertDialog.Builder(this);
+ String message = getString(R.string.delete_item);
+ d.setTitle(R.string.delete)
+ .setMessage(String.format(message, selectedCount));
+ d.setPositiveButton(android.R.string.yes,
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ // 取得最後一個元素的編號
+ int index = itemAdapter.getCount() - 1;
+
+ while (index > -1) {
+ Item item = itemAdapter.get(index);
+
+ if (item.isSelected()) {
+ itemAdapter.remove(item);
+ // 刪除資料庫中的記事資料
+ itemDAO.delete(item.getId());
+ }
+
+ index--;
+ }
+
+ itemAdapter.notifyDataSetChanged();
+ selectedCount = 0;
+ processMenu(null);
+ }
+ });
+ d.setNegativeButton(android.R.string.no, null);
+ d.show();
+
+ break;
+ case R.id.googleplus_item:
+ break;
+ case R.id.facebook_item:
+ break;
+ }
+
+ }
+
+ // 方法名稱與onClick的設定一樣,參數的型態是android.view.View
+ public void aboutApp(View view) {
+ // 建立啟動另一個Activity元件需要的Intent物件
+ // 建構式的第一個參數:「this」
+ // 建構式的第二個參數:「Activity元件類別名稱.class」
+ Intent intent = new Intent(this, AboutActivity.class);
+ // 呼叫「startActivity」,參數為一個建立好的Intent物件
+ // 這行敘述執行以後,如果沒有任何錯誤,就會啟動指定的元件
+ startActivity(intent);
+ }
+
+ // 設定
+ public void clickPreferences(MenuItem item) {
+ // 啟動設定元件
+ startActivity(new Intent(this, PrefActivity.class));
+ }
+
+}
+
+
diff --git a/examples/0401/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MyDBHelper.java b/examples/0401/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MyDBHelper.java
new file mode 100644
index 0000000..b8b77d6
--- /dev/null
+++ b/examples/0401/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MyDBHelper.java
@@ -0,0 +1,47 @@
+package net.macdidi.myandroidtutorial;
+
+import android.content.Context;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteDatabase.CursorFactory;
+import android.database.sqlite.SQLiteOpenHelper;
+
+public class MyDBHelper extends SQLiteOpenHelper {
+
+ // 資料庫名稱
+ public static final String DATABASE_NAME = "mydata.db";
+ // 資料庫版本,資料結構改變的時候要更改這個數字,通常是加一
+ public static final int VERSION = 2;
+ // 資料庫物件,固定的欄位變數
+ private static SQLiteDatabase database;
+
+ // 建構子,在一般的應用都不需要修改
+ public MyDBHelper(Context context, String name, CursorFactory factory,
+ int version) {
+ super(context, name, factory, version);
+ }
+
+ // 需要資料庫的元件呼叫這個方法,這個方法在一般的應用都不需要修改
+ public static SQLiteDatabase getDatabase(Context context) {
+ if (database == null || !database.isOpen()) {
+ database = new MyDBHelper(context, DATABASE_NAME,
+ null, VERSION).getWritableDatabase();
+ }
+
+ return database;
+ }
+
+ @Override
+ public void onCreate(SQLiteDatabase db) {
+ // 建立應用程式需要的表格
+ db.execSQL(ItemDAO.CREATE_TABLE);
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ // 刪除原有的表格
+ db.execSQL("DROP TABLE IF EXISTS " + ItemDAO.TABLE_NAME);
+ // 呼叫onCreate建立新版的表格
+ onCreate(db);
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0401/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PlayActivity.java b/examples/0401/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PlayActivity.java
new file mode 100644
index 0000000..5cfb523
--- /dev/null
+++ b/examples/0401/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PlayActivity.java
@@ -0,0 +1,64 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.media.MediaPlayer;
+import android.net.Uri;
+import android.os.Bundle;
+import android.view.View;
+
+public class PlayActivity extends Activity {
+
+ private MediaPlayer mediaPlayer;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_play);
+
+ Intent intent = getIntent();
+ String fileName = intent.getStringExtra("fileName");
+
+ // 建立指定資源的MediaPlayer物件
+ Uri uri = Uri.parse(fileName);
+ mediaPlayer = MediaPlayer.create(this, uri);
+ }
+
+ @Override
+ protected void onStop() {
+ if (mediaPlayer.isPlaying()) {
+ // 停止播放
+ mediaPlayer.stop();
+ }
+
+ // 清除MediaPlayer物件
+ mediaPlayer.release();
+ super.onStop();
+ }
+
+ public void onSubmit(View view) {
+ // 結束Activity元件
+ finish();
+ }
+
+ public void clickPlay(View view) {
+ // 開始播放
+ mediaPlayer.start();
+ }
+
+ public void clickPause(View view) {
+ // 暫停播放
+ mediaPlayer.pause();
+ }
+
+ public void clickStop(View view) {
+ // 停止播放
+ if (mediaPlayer.isPlaying()) {
+ mediaPlayer.stop();
+ }
+
+ // 回到開始的位置
+ mediaPlayer.seekTo(0);
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0401/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PrefActivity.java b/examples/0401/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PrefActivity.java
new file mode 100644
index 0000000..b2dcc4a
--- /dev/null
+++ b/examples/0401/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PrefActivity.java
@@ -0,0 +1,38 @@
+package net.macdidi.myandroidtutorial;
+
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceManager;
+
+public class PrefActivity extends PreferenceActivity {
+
+ private SharedPreferences sharedPreferences;
+ private Preference defaultColor;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ // 指定使用的設定畫面配置資源
+ addPreferencesFromResource(R.xml.mypreference);
+ defaultColor = (Preference)findPreference("DEFAULT_COLOR");
+ // 建立SharedPreferences物件
+ sharedPreferences =
+ PreferenceManager.getDefaultSharedPreferences(this);
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ // 讀取設定的預設顏色
+ int color = sharedPreferences.getInt("DEFAULT_COLOR", -1);
+
+ if (color != -1) {
+ // 設定顏色說明
+ defaultColor.setSummary(getString(R.string.default_color_summary) +
+ ": " + ItemActivity.getColors(color));
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0401/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/RecordActivity.java b/examples/0401/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/RecordActivity.java
new file mode 100644
index 0000000..62b5e93
--- /dev/null
+++ b/examples/0401/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/RecordActivity.java
@@ -0,0 +1,180 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.media.MediaRecorder;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.widget.ImageButton;
+import android.widget.ProgressBar;
+
+import java.io.IOException;
+
+public class RecordActivity extends Activity {
+
+ private ImageButton record_button;
+ private boolean isRecording = false;
+ private ProgressBar record_volumn;
+
+ private MyRecoder myRecoder;
+
+ private String fileName;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_record);
+
+ processViews();
+
+ // 讀取檔案名稱
+ Intent intent = getIntent();
+ fileName = intent.getStringExtra("fileName");
+ }
+
+ public void onSubmit(View view) {
+ if (isRecording) {
+ // 停止錄音
+ myRecoder.stop();
+ }
+
+ // 確定
+ if (view.getId() == R.id.record_ok) {
+ Intent result = getIntent();
+ setResult(Activity.RESULT_OK, result);
+ }
+
+ finish();
+ }
+
+ private void processViews() {
+ record_button = (ImageButton) findViewById(R.id.record_button);
+ record_volumn = (ProgressBar) findViewById(R.id.record_volumn);
+ // 隱藏狀態列ProgressBar
+ setProgressBarIndeterminateVisibility(false);
+ }
+
+ public void clickRecord(View view) {
+ // 切換
+ isRecording = !isRecording;
+
+ // 開始錄音
+ if (isRecording) {
+ // 設定按鈕圖示為錄音中
+ record_button.setImageResource(R.drawable.record_red_icon);
+ // 建立錄音物件
+ myRecoder = new MyRecoder(fileName);
+ // 開始錄音
+ myRecoder.start();
+ // 建立並執行顯示麥克風音量的AsyncTask物件
+ new MicLevelTask().execute();
+ }
+ // 停止錄音
+ else {
+ // 設定按鈕圖示為停止錄音
+ record_button.setImageResource(R.drawable.record_dark_icon);
+ // 麥克風音量歸零
+ record_volumn.setProgress(0);
+ // 停止錄音
+ myRecoder.stop();
+ }
+ }
+
+ // 在錄音過程中顯示麥克風音量
+ private class MicLevelTask extends AsyncTask
{
+ @Override
+ protected Void doInBackground(Void... args) {
+ while (isRecording) {
+ publishProgress();
+
+ try {
+ Thread.sleep(200);
+ }
+ catch (InterruptedException e) {
+ Log.d("RecordActivity", e.toString());
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ protected void onProgressUpdate(Void... values) {
+ record_volumn.setProgress((int) myRecoder.getAmplitudeEMA());
+ }
+
+ }
+
+ // 執行錄音並且可以取得麥克風音量的錄音物件
+ private class MyRecoder {
+
+ private static final double EMA_FILTER = 0.6;
+ private MediaRecorder recorder = null;
+ private double mEMA = 0.0;
+ private String output;
+
+ // 建立錄音物件,參數為錄音儲存的位置與檔名
+ MyRecoder(String output) {
+ this.output = output;
+ }
+
+ // 開始錄音
+ public void start() {
+ if (recorder == null) {
+ // 建立錄音用的MediaRecorder物件
+ recorder = new MediaRecorder();
+ // 設定錄音來源為麥克風,必須在setOutputFormat方法之前呼叫
+ recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
+ // 設定輸出格式為3GP壓縮格式,必須在setAudioSource方法之後,
+ // 在prepare方法之前呼叫
+ recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
+ // 設定錄音的編碼方式,必須在setOutputFormat方法之後,
+ // 在prepare方法之前呼叫
+ recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
+ // 設定輸出的檔案名稱,必須在setOutputFormat方法之後,
+ // 在prepare方法之前呼叫
+ recorder.setOutputFile(output);
+
+ try {
+ // 準備執行錄音工作,必須在所有設定之後呼叫
+ recorder.prepare();
+ }
+ catch (IOException e) {
+ Log.d("RecordActivity", e.toString());
+ }
+
+ // 開始錄音
+ recorder.start();
+ mEMA = 0.0;
+ }
+ }
+
+ // 停止錄音
+ public void stop() {
+ if (recorder != null) {
+ // 停止錄音
+ recorder.stop();
+ // 清除錄音資源
+ recorder.release();
+ recorder = null;
+ }
+ }
+
+ public double getAmplitude() {
+ if (recorder != null)
+ return (recorder.getMaxAmplitude() / 2700.0);
+ else
+ return 0;
+ }
+
+ // 取得麥克風音量
+ public double getAmplitudeEMA() {
+ double amp = getAmplitude();
+ mEMA = EMA_FILTER * amp + (1.0 - EMA_FILTER) * mEMA;
+ return mEMA;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0304/MyAndroidTutorial/res/drawable-hdpi/ic_launcher.png b/examples/0401/MyAndroidTutorial/app/src/main/res/drawable-hdpi/ic_launcher.png
old mode 100755
new mode 100644
similarity index 100%
rename from examples/0304/MyAndroidTutorial/res/drawable-hdpi/ic_launcher.png
rename to examples/0401/MyAndroidTutorial/app/src/main/res/drawable-hdpi/ic_launcher.png
diff --git a/examples/0304/MyAndroidTutorial/res/drawable-mdpi/ic_launcher.png b/examples/0401/MyAndroidTutorial/app/src/main/res/drawable-mdpi/ic_launcher.png
old mode 100755
new mode 100644
similarity index 100%
rename from examples/0304/MyAndroidTutorial/res/drawable-mdpi/ic_launcher.png
rename to examples/0401/MyAndroidTutorial/app/src/main/res/drawable-mdpi/ic_launcher.png
diff --git a/examples/0304/MyAndroidTutorial/res/drawable-xhdpi/ic_launcher.png b/examples/0401/MyAndroidTutorial/app/src/main/res/drawable-xhdpi/ic_launcher.png
old mode 100755
new mode 100644
similarity index 100%
rename from examples/0304/MyAndroidTutorial/res/drawable-xhdpi/ic_launcher.png
rename to examples/0401/MyAndroidTutorial/app/src/main/res/drawable-xhdpi/ic_launcher.png
diff --git a/examples/0401/MyAndroidTutorial/app/src/main/res/drawable-xxhdpi/ic_launcher.png b/examples/0401/MyAndroidTutorial/app/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..4df1894
Binary files /dev/null and b/examples/0401/MyAndroidTutorial/app/src/main/res/drawable-xxhdpi/ic_launcher.png differ
diff --git a/examples/0304/MyAndroidTutorial/res/drawable/alarm_icon.png b/examples/0401/MyAndroidTutorial/app/src/main/res/drawable/alarm_icon.png
old mode 100755
new mode 100644
similarity index 100%
rename from examples/0304/MyAndroidTutorial/res/drawable/alarm_icon.png
rename to examples/0401/MyAndroidTutorial/app/src/main/res/drawable/alarm_icon.png
diff --git a/examples/0401/MyAndroidTutorial/app/src/main/res/drawable/item_drawable.xml b/examples/0401/MyAndroidTutorial/app/src/main/res/drawable/item_drawable.xml
new file mode 100644
index 0000000..37607e2
--- /dev/null
+++ b/examples/0401/MyAndroidTutorial/app/src/main/res/drawable/item_drawable.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0304/MyAndroidTutorial/res/drawable/location_icon.png b/examples/0401/MyAndroidTutorial/app/src/main/res/drawable/location_icon.png
old mode 100755
new mode 100644
similarity index 100%
rename from examples/0304/MyAndroidTutorial/res/drawable/location_icon.png
rename to examples/0401/MyAndroidTutorial/app/src/main/res/drawable/location_icon.png
diff --git a/examples/0401/MyAndroidTutorial/res/drawable/pause_icon.png b/examples/0401/MyAndroidTutorial/app/src/main/res/drawable/pause_icon.png
similarity index 100%
rename from examples/0401/MyAndroidTutorial/res/drawable/pause_icon.png
rename to examples/0401/MyAndroidTutorial/app/src/main/res/drawable/pause_icon.png
diff --git a/examples/0401/MyAndroidTutorial/res/drawable/play_icon.png b/examples/0401/MyAndroidTutorial/app/src/main/res/drawable/play_icon.png
similarity index 100%
rename from examples/0401/MyAndroidTutorial/res/drawable/play_icon.png
rename to examples/0401/MyAndroidTutorial/app/src/main/res/drawable/play_icon.png
diff --git a/examples/0401/MyAndroidTutorial/res/drawable/record_dark_icon.png b/examples/0401/MyAndroidTutorial/app/src/main/res/drawable/record_dark_icon.png
similarity index 100%
rename from examples/0401/MyAndroidTutorial/res/drawable/record_dark_icon.png
rename to examples/0401/MyAndroidTutorial/app/src/main/res/drawable/record_dark_icon.png
diff --git a/examples/0401/MyAndroidTutorial/res/drawable/record_red_icon.png b/examples/0401/MyAndroidTutorial/app/src/main/res/drawable/record_red_icon.png
similarity index 100%
rename from examples/0401/MyAndroidTutorial/res/drawable/record_red_icon.png
rename to examples/0401/MyAndroidTutorial/app/src/main/res/drawable/record_red_icon.png
diff --git a/examples/0304/MyAndroidTutorial/res/drawable/record_sound_icon.png b/examples/0401/MyAndroidTutorial/app/src/main/res/drawable/record_sound_icon.png
similarity index 100%
rename from examples/0304/MyAndroidTutorial/res/drawable/record_sound_icon.png
rename to examples/0401/MyAndroidTutorial/app/src/main/res/drawable/record_sound_icon.png
diff --git a/examples/0401/MyAndroidTutorial/app/src/main/res/drawable/retangle_drawable.xml b/examples/0401/MyAndroidTutorial/app/src/main/res/drawable/retangle_drawable.xml
new file mode 100644
index 0000000..51d1e84
--- /dev/null
+++ b/examples/0401/MyAndroidTutorial/app/src/main/res/drawable/retangle_drawable.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0304/MyAndroidTutorial/res/drawable/select_color_icon.png b/examples/0401/MyAndroidTutorial/app/src/main/res/drawable/select_color_icon.png
old mode 100755
new mode 100644
similarity index 100%
rename from examples/0304/MyAndroidTutorial/res/drawable/select_color_icon.png
rename to examples/0401/MyAndroidTutorial/app/src/main/res/drawable/select_color_icon.png
diff --git a/examples/0304/MyAndroidTutorial/res/drawable/selected_icon.png b/examples/0401/MyAndroidTutorial/app/src/main/res/drawable/selected_icon.png
similarity index 100%
rename from examples/0304/MyAndroidTutorial/res/drawable/selected_icon.png
rename to examples/0401/MyAndroidTutorial/app/src/main/res/drawable/selected_icon.png
diff --git a/examples/0401/MyAndroidTutorial/res/drawable/stop_icon.png b/examples/0401/MyAndroidTutorial/app/src/main/res/drawable/stop_icon.png
similarity index 100%
rename from examples/0401/MyAndroidTutorial/res/drawable/stop_icon.png
rename to examples/0401/MyAndroidTutorial/app/src/main/res/drawable/stop_icon.png
diff --git a/examples/0304/MyAndroidTutorial/res/drawable/take_picture_icon.png b/examples/0401/MyAndroidTutorial/app/src/main/res/drawable/take_picture_icon.png
old mode 100755
new mode 100644
similarity index 100%
rename from examples/0304/MyAndroidTutorial/res/drawable/take_picture_icon.png
rename to examples/0401/MyAndroidTutorial/app/src/main/res/drawable/take_picture_icon.png
diff --git a/examples/0401/MyAndroidTutorial/app/src/main/res/layout/activity_about.xml b/examples/0401/MyAndroidTutorial/app/src/main/res/layout/activity_about.xml
new file mode 100644
index 0000000..8e78611
--- /dev/null
+++ b/examples/0401/MyAndroidTutorial/app/src/main/res/layout/activity_about.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0401/MyAndroidTutorial/app/src/main/res/layout/activity_color.xml b/examples/0401/MyAndroidTutorial/app/src/main/res/layout/activity_color.xml
new file mode 100644
index 0000000..d25bbc5
--- /dev/null
+++ b/examples/0401/MyAndroidTutorial/app/src/main/res/layout/activity_color.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
diff --git a/examples/0401/MyAndroidTutorial/app/src/main/res/layout/activity_item.xml b/examples/0401/MyAndroidTutorial/app/src/main/res/layout/activity_item.xml
new file mode 100644
index 0000000..4ec4362
--- /dev/null
+++ b/examples/0401/MyAndroidTutorial/app/src/main/res/layout/activity_item.xml
@@ -0,0 +1,125 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0401/MyAndroidTutorial/app/src/main/res/layout/activity_main.xml b/examples/0401/MyAndroidTutorial/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..121511b
--- /dev/null
+++ b/examples/0401/MyAndroidTutorial/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
diff --git a/examples/0401/MyAndroidTutorial/app/src/main/res/layout/activity_play.xml b/examples/0401/MyAndroidTutorial/app/src/main/res/layout/activity_play.xml
new file mode 100644
index 0000000..52db308
--- /dev/null
+++ b/examples/0401/MyAndroidTutorial/app/src/main/res/layout/activity_play.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0401/MyAndroidTutorial/app/src/main/res/layout/activity_record.xml b/examples/0401/MyAndroidTutorial/app/src/main/res/layout/activity_record.xml
new file mode 100644
index 0000000..63d9e36
--- /dev/null
+++ b/examples/0401/MyAndroidTutorial/app/src/main/res/layout/activity_record.xml
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0401/MyAndroidTutorial/app/src/main/res/layout/single_item.xml b/examples/0401/MyAndroidTutorial/app/src/main/res/layout/single_item.xml
new file mode 100644
index 0000000..40ddbc9
--- /dev/null
+++ b/examples/0401/MyAndroidTutorial/app/src/main/res/layout/single_item.xml
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0401/MyAndroidTutorial/app/src/main/res/menu/menu_about.xml b/examples/0401/MyAndroidTutorial/app/src/main/res/menu/menu_about.xml
new file mode 100644
index 0000000..d481100
--- /dev/null
+++ b/examples/0401/MyAndroidTutorial/app/src/main/res/menu/menu_about.xml
@@ -0,0 +1,7 @@
+
+
+
diff --git a/examples/0401/MyAndroidTutorial/app/src/main/res/menu/menu_color.xml b/examples/0401/MyAndroidTutorial/app/src/main/res/menu/menu_color.xml
new file mode 100644
index 0000000..8ff243b
--- /dev/null
+++ b/examples/0401/MyAndroidTutorial/app/src/main/res/menu/menu_color.xml
@@ -0,0 +1,7 @@
+
+
+
diff --git a/examples/0401/MyAndroidTutorial/app/src/main/res/menu/menu_item.xml b/examples/0401/MyAndroidTutorial/app/src/main/res/menu/menu_item.xml
new file mode 100644
index 0000000..cd2c9e4
--- /dev/null
+++ b/examples/0401/MyAndroidTutorial/app/src/main/res/menu/menu_item.xml
@@ -0,0 +1,7 @@
+
+
+
diff --git a/examples/0401/MyAndroidTutorial/app/src/main/res/menu/menu_main.xml b/examples/0401/MyAndroidTutorial/app/src/main/res/menu/menu_main.xml
new file mode 100644
index 0000000..0203cfa
--- /dev/null
+++ b/examples/0401/MyAndroidTutorial/app/src/main/res/menu/menu_main.xml
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
diff --git a/examples/0401/MyAndroidTutorial/app/src/main/res/values-en/strings.xml b/examples/0401/MyAndroidTutorial/app/src/main/res/values-en/strings.xml
new file mode 100644
index 0000000..c532533
--- /dev/null
+++ b/examples/0401/MyAndroidTutorial/app/src/main/res/values-en/strings.xml
@@ -0,0 +1,12 @@
+
+
+
+ MyAndroidTutorial
+ Hello world!
+ Settings
+
+ Title
+ Enter title
+ Content
+ Enter content
+
diff --git a/examples/0401/MyAndroidTutorial/app/src/main/res/values-w820dp/dimens.xml b/examples/0401/MyAndroidTutorial/app/src/main/res/values-w820dp/dimens.xml
new file mode 100644
index 0000000..63fc816
--- /dev/null
+++ b/examples/0401/MyAndroidTutorial/app/src/main/res/values-w820dp/dimens.xml
@@ -0,0 +1,6 @@
+
+
+ 64dp
+
diff --git a/examples/0401/MyAndroidTutorial/app/src/main/res/values/colors.xml b/examples/0401/MyAndroidTutorial/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..6b13c1d
--- /dev/null
+++ b/examples/0401/MyAndroidTutorial/app/src/main/res/values/colors.xml
@@ -0,0 +1,7 @@
+
+
+ #CCCCCC
+ #AAAAAA
+ #DD999999
+ #111111
+
\ No newline at end of file
diff --git a/examples/0401/MyAndroidTutorial/app/src/main/res/values/dimens.xml b/examples/0401/MyAndroidTutorial/app/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..02898ec
--- /dev/null
+++ b/examples/0401/MyAndroidTutorial/app/src/main/res/values/dimens.xml
@@ -0,0 +1,9 @@
+
+
+ 16dp
+ 16dp
+
+ 6dp
+ 24sp
+ 2dp
+
diff --git a/examples/0401/MyAndroidTutorial/app/src/main/res/values/strings.xml b/examples/0401/MyAndroidTutorial/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..ac34407
--- /dev/null
+++ b/examples/0401/MyAndroidTutorial/app/src/main/res/values/strings.xml
@@ -0,0 +1,45 @@
+
+
+
+ MyAndroidTutorial
+ Hello world!
+ Settings
+ 標題
+ 輸入標題
+ 內容
+ 輸入內容
+ 這是Android Tutorial應用程式
+ AboutActivity
+ 版本:AndroidTutorial_0.2.4
+ ItemActivity
+ ColorActivity
+ 刪除
+ 確定要刪除 %1$d 個項目?
+ 預設的顏色
+ 新增記事的預設顏色
+
+ 預設提醒時間
+ 在指定的時間之前通知
+
+
+ - 五分鐘
+ - 十分鐘
+ - 二十分鐘
+ - 三十分鐘
+ - 六十分鐘
+
+
+
+ - 5
+ - 10
+ - 20
+ - 30
+ - 60
+
+
+ 語音備忘
+ 播放語音備忘
+ 播放
+ 重新錄製
+
+
diff --git a/examples/0401/MyAndroidTutorial/app/src/main/res/values/styles.xml b/examples/0401/MyAndroidTutorial/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..766ab99
--- /dev/null
+++ b/examples/0401/MyAndroidTutorial/app/src/main/res/values/styles.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
diff --git a/examples/0401/MyAndroidTutorial/app/src/main/res/xml/mypreference.xml b/examples/0401/MyAndroidTutorial/app/src/main/res/xml/mypreference.xml
new file mode 100644
index 0000000..33e714c
--- /dev/null
+++ b/examples/0401/MyAndroidTutorial/app/src/main/res/xml/mypreference.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0401/MyAndroidTutorial/bin/AndroidManifest.xml b/examples/0401/MyAndroidTutorial/bin/AndroidManifest.xml
deleted file mode 100755
index adde1ff..0000000
--- a/examples/0401/MyAndroidTutorial/bin/AndroidManifest.xml
+++ /dev/null
@@ -1,74 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/examples/0401/MyAndroidTutorial/bin/MyAndroidTutorial.apk b/examples/0401/MyAndroidTutorial/bin/MyAndroidTutorial.apk
deleted file mode 100644
index dd4eea8..0000000
Binary files a/examples/0401/MyAndroidTutorial/bin/MyAndroidTutorial.apk and /dev/null differ
diff --git a/examples/0401/MyAndroidTutorial/bin/classes.dex b/examples/0401/MyAndroidTutorial/bin/classes.dex
deleted file mode 100755
index e60bbd0..0000000
Binary files a/examples/0401/MyAndroidTutorial/bin/classes.dex and /dev/null differ
diff --git a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/AboutActivity.class b/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/AboutActivity.class
deleted file mode 100644
index abbf876..0000000
Binary files a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/AboutActivity.class and /dev/null differ
diff --git a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/BuildConfig.class b/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/BuildConfig.class
deleted file mode 100644
index 30f5623..0000000
Binary files a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/BuildConfig.class and /dev/null differ
diff --git a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ColorActivity$ColorListener.class b/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ColorActivity$ColorListener.class
deleted file mode 100644
index 78ad0d3..0000000
Binary files a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ColorActivity$ColorListener.class and /dev/null differ
diff --git a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ColorActivity.class b/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ColorActivity.class
deleted file mode 100644
index 2075635..0000000
Binary files a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ColorActivity.class and /dev/null differ
diff --git a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/Colors.class b/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/Colors.class
deleted file mode 100644
index 4dda566..0000000
Binary files a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/Colors.class and /dev/null differ
diff --git a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/FileUtil.class b/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/FileUtil.class
deleted file mode 100644
index d48e65b..0000000
Binary files a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/FileUtil.class and /dev/null differ
diff --git a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/Item.class b/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/Item.class
deleted file mode 100644
index 549fb77..0000000
Binary files a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/Item.class and /dev/null differ
diff --git a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ItemActivity$1.class b/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ItemActivity$1.class
deleted file mode 100644
index 3f10acd..0000000
Binary files a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ItemActivity$1.class and /dev/null differ
diff --git a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ItemActivity$2.class b/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ItemActivity$2.class
deleted file mode 100644
index 65bd945..0000000
Binary files a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ItemActivity$2.class and /dev/null differ
diff --git a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ItemActivity.class b/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ItemActivity.class
deleted file mode 100644
index b7fd6f4..0000000
Binary files a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ItemActivity.class and /dev/null differ
diff --git a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ItemAdapter.class b/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ItemAdapter.class
deleted file mode 100644
index 5aa29f4..0000000
Binary files a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ItemAdapter.class and /dev/null differ
diff --git a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ItemDAO.class b/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ItemDAO.class
deleted file mode 100644
index 7e2d245..0000000
Binary files a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/ItemDAO.class and /dev/null differ
diff --git a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$1.class b/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$1.class
deleted file mode 100644
index a62a964..0000000
Binary files a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$1.class and /dev/null differ
diff --git a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$2.class b/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$2.class
deleted file mode 100644
index b073618..0000000
Binary files a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$2.class and /dev/null differ
diff --git a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$3.class b/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$3.class
deleted file mode 100644
index 879d037..0000000
Binary files a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$3.class and /dev/null differ
diff --git a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$4.class b/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$4.class
deleted file mode 100644
index 6f608be..0000000
Binary files a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity$4.class and /dev/null differ
diff --git a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity.class b/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity.class
deleted file mode 100644
index 6304a33..0000000
Binary files a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MainActivity.class and /dev/null differ
diff --git a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MyDBHelper.class b/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MyDBHelper.class
deleted file mode 100644
index e1e14ad..0000000
Binary files a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/MyDBHelper.class and /dev/null differ
diff --git a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/PlayActivity$1.class b/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/PlayActivity$1.class
deleted file mode 100644
index d43ec42..0000000
Binary files a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/PlayActivity$1.class and /dev/null differ
diff --git a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/PlayActivity$2.class b/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/PlayActivity$2.class
deleted file mode 100644
index a6572ed..0000000
Binary files a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/PlayActivity$2.class and /dev/null differ
diff --git a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/PlayActivity$MyCompletion.class b/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/PlayActivity$MyCompletion.class
deleted file mode 100644
index 674f983..0000000
Binary files a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/PlayActivity$MyCompletion.class and /dev/null differ
diff --git a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/PlayActivity$MyPlayTask.class b/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/PlayActivity$MyPlayTask.class
deleted file mode 100644
index 83b2771..0000000
Binary files a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/PlayActivity$MyPlayTask.class and /dev/null differ
diff --git a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/PlayActivity.class b/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/PlayActivity.class
deleted file mode 100644
index 6f8bc4d..0000000
Binary files a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/PlayActivity.class and /dev/null differ
diff --git a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/PrefActivity.class b/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/PrefActivity.class
deleted file mode 100644
index 3989e38..0000000
Binary files a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/PrefActivity.class and /dev/null differ
diff --git a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$array.class b/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$array.class
deleted file mode 100644
index b9a7b7b..0000000
Binary files a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$array.class and /dev/null differ
diff --git a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$attr.class b/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$attr.class
deleted file mode 100644
index 01d5c1c..0000000
Binary files a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$attr.class and /dev/null differ
diff --git a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$color.class b/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$color.class
deleted file mode 100644
index c246f78..0000000
Binary files a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$color.class and /dev/null differ
diff --git a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$dimen.class b/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$dimen.class
deleted file mode 100644
index 4079bf4..0000000
Binary files a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$dimen.class and /dev/null differ
diff --git a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$drawable.class b/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$drawable.class
deleted file mode 100644
index e93810f..0000000
Binary files a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$drawable.class and /dev/null differ
diff --git a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$id.class b/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$id.class
deleted file mode 100644
index b896136..0000000
Binary files a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$id.class and /dev/null differ
diff --git a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$layout.class b/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$layout.class
deleted file mode 100644
index ff371b7..0000000
Binary files a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$layout.class and /dev/null differ
diff --git a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$menu.class b/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$menu.class
deleted file mode 100644
index d949815..0000000
Binary files a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$menu.class and /dev/null differ
diff --git a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$string.class b/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$string.class
deleted file mode 100644
index fddb801..0000000
Binary files a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$string.class and /dev/null differ
diff --git a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$style.class b/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$style.class
deleted file mode 100644
index ad46499..0000000
Binary files a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$style.class and /dev/null differ
diff --git a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$xml.class b/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$xml.class
deleted file mode 100644
index d9a7dfe..0000000
Binary files a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R$xml.class and /dev/null differ
diff --git a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R.class b/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R.class
deleted file mode 100644
index e09c2b9..0000000
Binary files a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/R.class and /dev/null differ
diff --git a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/RecordActivity$MicLevelTask.class b/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/RecordActivity$MicLevelTask.class
deleted file mode 100644
index 6e5e830..0000000
Binary files a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/RecordActivity$MicLevelTask.class and /dev/null differ
diff --git a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/RecordActivity$MyRecoder.class b/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/RecordActivity$MyRecoder.class
deleted file mode 100644
index 817dd80..0000000
Binary files a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/RecordActivity$MyRecoder.class and /dev/null differ
diff --git a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/RecordActivity.class b/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/RecordActivity.class
deleted file mode 100644
index 06bcfb9..0000000
Binary files a/examples/0401/MyAndroidTutorial/bin/classes/net/macdidi/myandroidtutorial/RecordActivity.class and /dev/null differ
diff --git a/examples/0401/MyAndroidTutorial/bin/dexedLibs/android-support-v4-9b1d5d28bf7d59a4e392b3d4f78c1f13.jar b/examples/0401/MyAndroidTutorial/bin/dexedLibs/android-support-v4-9b1d5d28bf7d59a4e392b3d4f78c1f13.jar
deleted file mode 100755
index 2f330c0..0000000
Binary files a/examples/0401/MyAndroidTutorial/bin/dexedLibs/android-support-v4-9b1d5d28bf7d59a4e392b3d4f78c1f13.jar and /dev/null differ
diff --git a/examples/0401/MyAndroidTutorial/bin/jarlist.cache b/examples/0401/MyAndroidTutorial/bin/jarlist.cache
deleted file mode 100755
index 0565465..0000000
--- a/examples/0401/MyAndroidTutorial/bin/jarlist.cache
+++ /dev/null
@@ -1,3 +0,0 @@
-# cache for current jar dependency. DO NOT EDIT.
-# format is
-# Encoding is UTF-8
diff --git a/examples/0401/MyAndroidTutorial/bin/res/crunch/drawable-hdpi/ic_launcher.png b/examples/0401/MyAndroidTutorial/bin/res/crunch/drawable-hdpi/ic_launcher.png
deleted file mode 100755
index bcfa058..0000000
Binary files a/examples/0401/MyAndroidTutorial/bin/res/crunch/drawable-hdpi/ic_launcher.png and /dev/null differ
diff --git a/examples/0401/MyAndroidTutorial/bin/res/crunch/drawable-mdpi/ic_launcher.png b/examples/0401/MyAndroidTutorial/bin/res/crunch/drawable-mdpi/ic_launcher.png
deleted file mode 100755
index 85848ff..0000000
Binary files a/examples/0401/MyAndroidTutorial/bin/res/crunch/drawable-mdpi/ic_launcher.png and /dev/null differ
diff --git a/examples/0401/MyAndroidTutorial/bin/res/crunch/drawable-xhdpi/ic_launcher.png b/examples/0401/MyAndroidTutorial/bin/res/crunch/drawable-xhdpi/ic_launcher.png
deleted file mode 100755
index 916901e..0000000
Binary files a/examples/0401/MyAndroidTutorial/bin/res/crunch/drawable-xhdpi/ic_launcher.png and /dev/null differ
diff --git a/examples/0401/MyAndroidTutorial/bin/res/crunch/drawable/alarm_icon.png b/examples/0401/MyAndroidTutorial/bin/res/crunch/drawable/alarm_icon.png
deleted file mode 100755
index ebeae27..0000000
Binary files a/examples/0401/MyAndroidTutorial/bin/res/crunch/drawable/alarm_icon.png and /dev/null differ
diff --git a/examples/0401/MyAndroidTutorial/bin/res/crunch/drawable/location_icon.png b/examples/0401/MyAndroidTutorial/bin/res/crunch/drawable/location_icon.png
deleted file mode 100755
index 6897a97..0000000
Binary files a/examples/0401/MyAndroidTutorial/bin/res/crunch/drawable/location_icon.png and /dev/null differ
diff --git a/examples/0401/MyAndroidTutorial/bin/res/crunch/drawable/pause_icon.png b/examples/0401/MyAndroidTutorial/bin/res/crunch/drawable/pause_icon.png
deleted file mode 100644
index ac6d373..0000000
Binary files a/examples/0401/MyAndroidTutorial/bin/res/crunch/drawable/pause_icon.png and /dev/null differ
diff --git a/examples/0401/MyAndroidTutorial/bin/res/crunch/drawable/play_icon.png b/examples/0401/MyAndroidTutorial/bin/res/crunch/drawable/play_icon.png
deleted file mode 100644
index 3f3ef9c..0000000
Binary files a/examples/0401/MyAndroidTutorial/bin/res/crunch/drawable/play_icon.png and /dev/null differ
diff --git a/examples/0401/MyAndroidTutorial/bin/res/crunch/drawable/record_dark_icon.png b/examples/0401/MyAndroidTutorial/bin/res/crunch/drawable/record_dark_icon.png
deleted file mode 100644
index 0684b5c..0000000
Binary files a/examples/0401/MyAndroidTutorial/bin/res/crunch/drawable/record_dark_icon.png and /dev/null differ
diff --git a/examples/0401/MyAndroidTutorial/bin/res/crunch/drawable/record_red_icon.png b/examples/0401/MyAndroidTutorial/bin/res/crunch/drawable/record_red_icon.png
deleted file mode 100644
index 37ccbd2..0000000
Binary files a/examples/0401/MyAndroidTutorial/bin/res/crunch/drawable/record_red_icon.png and /dev/null differ
diff --git a/examples/0401/MyAndroidTutorial/bin/res/crunch/drawable/record_sound_icon.png b/examples/0401/MyAndroidTutorial/bin/res/crunch/drawable/record_sound_icon.png
deleted file mode 100755
index 6fe2060..0000000
Binary files a/examples/0401/MyAndroidTutorial/bin/res/crunch/drawable/record_sound_icon.png and /dev/null differ
diff --git a/examples/0401/MyAndroidTutorial/bin/res/crunch/drawable/select_color_icon.png b/examples/0401/MyAndroidTutorial/bin/res/crunch/drawable/select_color_icon.png
deleted file mode 100755
index 4270ec5..0000000
Binary files a/examples/0401/MyAndroidTutorial/bin/res/crunch/drawable/select_color_icon.png and /dev/null differ
diff --git a/examples/0401/MyAndroidTutorial/bin/res/crunch/drawable/selected_icon.png b/examples/0401/MyAndroidTutorial/bin/res/crunch/drawable/selected_icon.png
deleted file mode 100755
index 982ddee..0000000
Binary files a/examples/0401/MyAndroidTutorial/bin/res/crunch/drawable/selected_icon.png and /dev/null differ
diff --git a/examples/0401/MyAndroidTutorial/bin/res/crunch/drawable/stop_icon.png b/examples/0401/MyAndroidTutorial/bin/res/crunch/drawable/stop_icon.png
deleted file mode 100644
index 38148ec..0000000
Binary files a/examples/0401/MyAndroidTutorial/bin/res/crunch/drawable/stop_icon.png and /dev/null differ
diff --git a/examples/0401/MyAndroidTutorial/bin/res/crunch/drawable/take_picture_icon.png b/examples/0401/MyAndroidTutorial/bin/res/crunch/drawable/take_picture_icon.png
deleted file mode 100755
index c812e2f..0000000
Binary files a/examples/0401/MyAndroidTutorial/bin/res/crunch/drawable/take_picture_icon.png and /dev/null differ
diff --git a/examples/0401/MyAndroidTutorial/bin/resources.ap_ b/examples/0401/MyAndroidTutorial/bin/resources.ap_
deleted file mode 100644
index ae943e8..0000000
Binary files a/examples/0401/MyAndroidTutorial/bin/resources.ap_ and /dev/null differ
diff --git a/examples/0401/MyAndroidTutorial/build.gradle b/examples/0401/MyAndroidTutorial/build.gradle
new file mode 100644
index 0000000..6356aab
--- /dev/null
+++ b/examples/0401/MyAndroidTutorial/build.gradle
@@ -0,0 +1,19 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+ repositories {
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:1.0.0'
+
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+}
+
+allprojects {
+ repositories {
+ jcenter()
+ }
+}
diff --git a/examples/0401/MyAndroidTutorial/gen/net/macdidi/myandroidtutorial/BuildConfig.java b/examples/0401/MyAndroidTutorial/gen/net/macdidi/myandroidtutorial/BuildConfig.java
deleted file mode 100755
index 5d44ea9..0000000
--- a/examples/0401/MyAndroidTutorial/gen/net/macdidi/myandroidtutorial/BuildConfig.java
+++ /dev/null
@@ -1,6 +0,0 @@
-/** Automatically generated file. DO NOT MODIFY */
-package net.macdidi.myandroidtutorial;
-
-public final class BuildConfig {
- public final static boolean DEBUG = true;
-}
\ No newline at end of file
diff --git a/examples/0401/MyAndroidTutorial/gen/net/macdidi/myandroidtutorial/R.java b/examples/0401/MyAndroidTutorial/gen/net/macdidi/myandroidtutorial/R.java
deleted file mode 100755
index 3a03aa2..0000000
--- a/examples/0401/MyAndroidTutorial/gen/net/macdidi/myandroidtutorial/R.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/* AUTO-GENERATED FILE. DO NOT MODIFY.
- *
- * This class was automatically generated by the
- * aapt tool from the resource data it found. It
- * should not be modified by hand.
- */
-
-package net.macdidi.myandroidtutorial;
-
-public final class R {
- public static final class array {
- public static final int notify_minutes_array=0x7f080000;
- public static final int notify_minutes_value_array=0x7f080001;
- }
- public static final class attr {
- }
- public static final class color {
- public static final int dark_text=0x7f050003;
- public static final int divider_color=0x7f050002;
- public static final int grey=0x7f050001;
- public static final int light_grey=0x7f050000;
- }
- public static final class dimen {
- public static final int default_margin=0x7f060001;
- public static final int default_padding=0x7f060000;
- public static final int title_txt_size=0x7f060002;
- }
- public static final class drawable {
- public static final int alarm_icon=0x7f020000;
- public static final int ic_launcher=0x7f020001;
- public static final int item_drawable=0x7f020002;
- public static final int location_icon=0x7f020003;
- public static final int pause_icon=0x7f020004;
- public static final int play_icon=0x7f020005;
- public static final int record_dark_icon=0x7f020006;
- public static final int record_red_icon=0x7f020007;
- public static final int record_sound_icon=0x7f020008;
- public static final int retangle_drawable=0x7f020009;
- public static final int select_color_icon=0x7f02000a;
- public static final int selected_icon=0x7f02000b;
- public static final int stop_icon=0x7f02000c;
- public static final int take_picture_icon=0x7f02000d;
- }
- public static final class id {
- public static final int add_item=0x7f0b0016;
- public static final int cancel_item=0x7f0b0009;
- public static final int color_gallery=0x7f0b0000;
- public static final int content_text=0x7f0b0002;
- public static final int control=0x7f0b000d;
- public static final int date_text=0x7f0b0014;
- public static final int delete_item=0x7f0b0018;
- public static final int facebook_item=0x7f0b001b;
- public static final int googleplus_item=0x7f0b001a;
- public static final int item_list=0x7f0b000b;
- public static final int ok_add_teim=0x7f0b000e;
- public static final int ok_teim=0x7f0b000a;
- public static final int picture=0x7f0b0003;
- public static final int record_button=0x7f0b000f;
- public static final int record_ok=0x7f0b0011;
- public static final int record_sound=0x7f0b0005;
- public static final int record_volumn=0x7f0b0010;
- public static final int revert_item=0x7f0b0017;
- public static final int search_item=0x7f0b0015;
- public static final int select_color=0x7f0b0008;
- public static final int selected_item=0x7f0b0013;
- public static final int set_alarm=0x7f0b0007;
- public static final int set_location=0x7f0b0006;
- public static final int share_item=0x7f0b0019;
- public static final int show_app_name=0x7f0b000c;
- public static final int take_picture=0x7f0b0004;
- public static final int title_text=0x7f0b0001;
- public static final int type_color=0x7f0b0012;
- }
- public static final class layout {
- public static final int activity_about=0x7f030000;
- public static final int activity_color=0x7f030001;
- public static final int activity_item=0x7f030002;
- public static final int activity_main=0x7f030003;
- public static final int activity_play=0x7f030004;
- public static final int activity_record=0x7f030005;
- public static final int single_item=0x7f030006;
- }
- public static final class menu {
- public static final int main_menu=0x7f0a0000;
- }
- public static final class string {
- public static final int about=0x7f070007;
- public static final int app_name=0x7f070000;
- public static final int content=0x7f070005;
- public static final int default_color=0x7f07000b;
- public static final int default_color_summary=0x7f07000c;
- public static final int default_notify=0x7f07000d;
- public static final int default_notify_summary=0x7f07000e;
- public static final int delete=0x7f070009;
- public static final int delete_item=0x7f07000a;
- public static final int enter_content=0x7f070006;
- public static final int enter_title=0x7f070004;
- public static final int hello_world=0x7f070012;
- public static final int record_new=0x7f070011;
- public static final int record_play=0x7f070010;
- public static final int title=0x7f070003;
- public static final int title_activity_color=0x7f070002;
- public static final int title_activity_main=0x7f070001;
- public static final int title_record=0x7f07000f;
- public static final int version=0x7f070008;
- }
- public static final class style {
- /**
- Base application theme, dependent on API level. This theme is replaced
- by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
-
-
- Theme customizations available in newer API levels can go in
- res/values-vXX/styles.xml, while customizations related to
- backward-compatibility can go here.
-
-
- Base application theme for API 11+. This theme completely replaces
- AppBaseTheme from res/values/styles.xml on API 11+ devices.
-
- API 11 theme customizations can go here.
-
- Base application theme for API 14+. This theme completely replaces
- AppBaseTheme from BOTH res/values/styles.xml and
- res/values-v11/styles.xml on API 14+ devices.
-
- API 14 theme customizations can go here.
- */
- public static final int AppBaseTheme=0x7f090000;
- /** Application theme.
- All customizations that are NOT specific to a particular API-level can go here.
- */
- public static final int AppTheme=0x7f090001;
- }
- public static final class xml {
- public static final int mypreference=0x7f040000;
- }
-}
diff --git a/examples/0401/MyAndroidTutorial/gradle.properties b/examples/0401/MyAndroidTutorial/gradle.properties
new file mode 100644
index 0000000..1d3591c
--- /dev/null
+++ b/examples/0401/MyAndroidTutorial/gradle.properties
@@ -0,0 +1,18 @@
+# Project-wide Gradle settings.
+
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+# Default value: -Xmx10248m -XX:MaxPermSize=256m
+# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
+
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
\ No newline at end of file
diff --git a/examples/0401/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.jar b/examples/0401/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
Binary files /dev/null and b/examples/0401/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/examples/0401/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.properties b/examples/0401/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..0c71e76
--- /dev/null
+++ b/examples/0401/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
diff --git a/examples/0401/MyAndroidTutorial/gradlew b/examples/0401/MyAndroidTutorial/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/examples/0401/MyAndroidTutorial/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/examples/0401/MyAndroidTutorial/gradlew.bat b/examples/0401/MyAndroidTutorial/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/examples/0401/MyAndroidTutorial/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/examples/0401/MyAndroidTutorial/libs/android-support-v4.jar b/examples/0401/MyAndroidTutorial/libs/android-support-v4.jar
deleted file mode 100755
index 187bdf4..0000000
Binary files a/examples/0401/MyAndroidTutorial/libs/android-support-v4.jar and /dev/null differ
diff --git a/examples/0401/MyAndroidTutorial/proguard-project.txt b/examples/0401/MyAndroidTutorial/proguard-project.txt
deleted file mode 100755
index f2fe155..0000000
--- a/examples/0401/MyAndroidTutorial/proguard-project.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-# To enable ProGuard in your project, edit project.properties
-# to define the proguard.config property as described in that file.
-#
-# Add project specific ProGuard rules here.
-# By default, the flags in this file are appended to flags specified
-# in ${sdk.dir}/tools/proguard/proguard-android.txt
-# You can edit the include path and order by changing the ProGuard
-# include property in project.properties.
-#
-# For more details, see
-# http://developer.android.com/guide/developing/tools/proguard.html
-
-# Add any project specific keep options here:
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-# public *;
-#}
diff --git a/examples/0401/MyAndroidTutorial/project.properties b/examples/0401/MyAndroidTutorial/project.properties
deleted file mode 100755
index 4ab1256..0000000
--- a/examples/0401/MyAndroidTutorial/project.properties
+++ /dev/null
@@ -1,14 +0,0 @@
-# This file is automatically generated by Android Tools.
-# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
-#
-# This file must be checked in Version Control Systems.
-#
-# To customize properties used by the Ant build system edit
-# "ant.properties", and override values to adapt the script to your
-# project structure.
-#
-# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
-#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
-
-# Project target.
-target=android-19
diff --git a/examples/0401/MyAndroidTutorial/res/drawable/item_drawable.xml b/examples/0401/MyAndroidTutorial/res/drawable/item_drawable.xml
deleted file mode 100755
index ecc4011..0000000
--- a/examples/0401/MyAndroidTutorial/res/drawable/item_drawable.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/examples/0401/MyAndroidTutorial/res/drawable/retangle_drawable.xml b/examples/0401/MyAndroidTutorial/res/drawable/retangle_drawable.xml
deleted file mode 100755
index e195342..0000000
--- a/examples/0401/MyAndroidTutorial/res/drawable/retangle_drawable.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/examples/0401/MyAndroidTutorial/res/layout/activity_about.xml b/examples/0401/MyAndroidTutorial/res/layout/activity_about.xml
deleted file mode 100755
index 738fe98..0000000
--- a/examples/0401/MyAndroidTutorial/res/layout/activity_about.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/examples/0401/MyAndroidTutorial/res/layout/activity_color.xml b/examples/0401/MyAndroidTutorial/res/layout/activity_color.xml
deleted file mode 100755
index 693a9d4..0000000
--- a/examples/0401/MyAndroidTutorial/res/layout/activity_color.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
-
-
diff --git a/examples/0401/MyAndroidTutorial/res/layout/activity_item.xml b/examples/0401/MyAndroidTutorial/res/layout/activity_item.xml
deleted file mode 100755
index eb22774..0000000
--- a/examples/0401/MyAndroidTutorial/res/layout/activity_item.xml
+++ /dev/null
@@ -1,110 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/examples/0401/MyAndroidTutorial/res/layout/activity_main.xml b/examples/0401/MyAndroidTutorial/res/layout/activity_main.xml
deleted file mode 100755
index 418c34b..0000000
--- a/examples/0401/MyAndroidTutorial/res/layout/activity_main.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
diff --git a/examples/0401/MyAndroidTutorial/res/layout/activity_play.xml b/examples/0401/MyAndroidTutorial/res/layout/activity_play.xml
deleted file mode 100755
index ac71122..0000000
--- a/examples/0401/MyAndroidTutorial/res/layout/activity_play.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/examples/0401/MyAndroidTutorial/res/layout/activity_record.xml b/examples/0401/MyAndroidTutorial/res/layout/activity_record.xml
deleted file mode 100755
index 4d31503..0000000
--- a/examples/0401/MyAndroidTutorial/res/layout/activity_record.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/examples/0401/MyAndroidTutorial/res/layout/single_item.xml b/examples/0401/MyAndroidTutorial/res/layout/single_item.xml
deleted file mode 100755
index c3b579c..0000000
--- a/examples/0401/MyAndroidTutorial/res/layout/single_item.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/examples/0401/MyAndroidTutorial/res/menu/main_menu.xml b/examples/0401/MyAndroidTutorial/res/menu/main_menu.xml
deleted file mode 100755
index dadd8fa..0000000
--- a/examples/0401/MyAndroidTutorial/res/menu/main_menu.xml
+++ /dev/null
@@ -1,51 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/examples/0401/MyAndroidTutorial/res/values-en/strings.xml b/examples/0401/MyAndroidTutorial/res/values-en/strings.xml
deleted file mode 100755
index 34f4fed..0000000
--- a/examples/0401/MyAndroidTutorial/res/values-en/strings.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
- MyAndroidTutorial
- MainActivity
- Hello world!
-
- Title
- Enter title
- Content
- Enter content
-
-
diff --git a/examples/0401/MyAndroidTutorial/res/values-v11/styles.xml b/examples/0401/MyAndroidTutorial/res/values-v11/styles.xml
deleted file mode 100755
index 3c02242..0000000
--- a/examples/0401/MyAndroidTutorial/res/values-v11/styles.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
diff --git a/examples/0401/MyAndroidTutorial/res/values-v14/styles.xml b/examples/0401/MyAndroidTutorial/res/values-v14/styles.xml
deleted file mode 100755
index a91fd03..0000000
--- a/examples/0401/MyAndroidTutorial/res/values-v14/styles.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
diff --git a/examples/0401/MyAndroidTutorial/res/values/colors.xml b/examples/0401/MyAndroidTutorial/res/values/colors.xml
deleted file mode 100755
index c63ec2d..0000000
--- a/examples/0401/MyAndroidTutorial/res/values/colors.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
- #CCCCCC
- #AAAAAA
- #DDCCCCCC
- #111111
-
diff --git a/examples/0401/MyAndroidTutorial/res/values/dimens.xml b/examples/0401/MyAndroidTutorial/res/values/dimens.xml
deleted file mode 100755
index fb03071..0000000
--- a/examples/0401/MyAndroidTutorial/res/values/dimens.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
- 6dp
- 2dp
- 24sp
-
diff --git a/examples/0401/MyAndroidTutorial/res/values/strings.xml b/examples/0401/MyAndroidTutorial/res/values/strings.xml
deleted file mode 100755
index 4914824..0000000
--- a/examples/0401/MyAndroidTutorial/res/values/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-
-
-
- MyAndroidTutorial
- MyAndroidTutorial
- 設定顏色
- 標題
- 輸入標題
- 內容
- 輸入內容
- 這是Android Tutorial應用程式
- 版本:AndroidTutorial_0.2.4
-
- 刪除
- 確定要刪除 %1$d 個項目?
-
- 預設的顏色
- 新增記事的預設顏色
-
- 預設提醒時間
- 在指定的時間之前通知
-
-
- - 五分鐘
- - 十分鐘
- - 二十分鐘
- - 三十分鐘
- - 六十分鐘
-
-
-
- - 5
- - 10
- - 20
- - 30
- - 60
-
-
- 語音備忘
- 播放
- 重新錄製
-
-
diff --git a/examples/0401/MyAndroidTutorial/res/values/styles.xml b/examples/0401/MyAndroidTutorial/res/values/styles.xml
deleted file mode 100755
index 6ce89c7..0000000
--- a/examples/0401/MyAndroidTutorial/res/values/styles.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
-
-
-
-
-
-
diff --git a/examples/0401/MyAndroidTutorial/res/xml/mypreference.xml b/examples/0401/MyAndroidTutorial/res/xml/mypreference.xml
deleted file mode 100644
index 4cd7f5e..0000000
--- a/examples/0401/MyAndroidTutorial/res/xml/mypreference.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/examples/0401/MyAndroidTutorial/settings.gradle b/examples/0401/MyAndroidTutorial/settings.gradle
new file mode 100644
index 0000000..e7b4def
--- /dev/null
+++ b/examples/0401/MyAndroidTutorial/settings.gradle
@@ -0,0 +1 @@
+include ':app'
diff --git a/examples/0401/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/AboutActivity.java b/examples/0401/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/AboutActivity.java
deleted file mode 100755
index 111efc5..0000000
--- a/examples/0401/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/AboutActivity.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package net.macdidi.myandroidtutorial;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.view.View;
-import android.view.Window;
-
-public class AboutActivity extends Activity {
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- // 取消元件的應用程式標題
- requestWindowFeature(Window.FEATURE_NO_TITLE);
- setContentView(R.layout.activity_about);
- }
-
- // 結束按鈕
- public void clickOk(View view) {
- // 呼叫這個方法結束Activity元件
- finish();
- }
-
-}
diff --git a/examples/0401/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/ColorActivity.java b/examples/0401/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/ColorActivity.java
deleted file mode 100755
index 0eafb85..0000000
--- a/examples/0401/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/ColorActivity.java
+++ /dev/null
@@ -1,75 +0,0 @@
-package net.macdidi.myandroidtutorial;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.os.Bundle;
-import android.preference.PreferenceManager;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.widget.Button;
-import android.widget.LinearLayout;
-
-public class ColorActivity extends Activity {
-
- private LinearLayout color_gallery;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_color);
-
- processViews();
-
- ColorListener listener = new ColorListener();
-
- for (Colors c : Colors.values()) {
- Button button = new Button(this);
- button.setId(c.parseColor());
- LinearLayout.LayoutParams layout =
- new LinearLayout.LayoutParams(128, 128);
- layout.setMargins(6, 6, 6, 6);
- button.setLayoutParams(layout);
- button.setBackgroundColor(c.parseColor());
-
- button.setOnClickListener(listener);
-
- color_gallery.addView(button);
- }
- }
-
- private void processViews() {
- color_gallery = (LinearLayout) findViewById(R.id.color_gallery);
- }
-
- private class ColorListener implements OnClickListener {
-
- @Override
- public void onClick(View view) {
- String action = ColorActivity.this.getIntent().getAction();
-
- // 經由設定元件啟動
- if (action != null &&
- action.equals("net.macdidi.myandroidtutorial.CHOOSE_COLOR")) {
- // 建立SharedPreferences物件
- SharedPreferences.Editor editor =
- PreferenceManager.getDefaultSharedPreferences(
- ColorActivity.this).edit();
- // 儲存預設顏色
- editor.putInt("DEFAULT_COLOR", view.getId());
- // 寫入設定值
- editor.commit();
- finish();
- }
- // 經由新增或修改記事的元件啟動
- else {
- Intent result = getIntent();
- result.putExtra("colorId", view.getId());
- setResult(Activity.RESULT_OK, result);
- finish();
- }
- }
-
- }
-
-}
diff --git a/examples/0401/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/Colors.java b/examples/0401/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/Colors.java
deleted file mode 100755
index a3eb9d4..0000000
--- a/examples/0401/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/Colors.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package net.macdidi.myandroidtutorial;
-
-import android.graphics.Color;
-
-public enum Colors {
-
- LIGHTGREY("#D3D3D3"), BLUE("#33B5E5"), PURPLE("#AA66CC"),
- GREEN("#99CC00"), ORANGE("#FFBB33"), RED("#FF4444");
-
- private String code;
-
- private Colors(String code) {
- this.code = code;
- }
-
- public String getCode() {
- return code;
- }
-
- public int parseColor() {
- return Color.parseColor(code);
- }
-
-}
diff --git a/examples/0401/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/FileUtil.java b/examples/0401/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/FileUtil.java
deleted file mode 100644
index 62920aa..0000000
--- a/examples/0401/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/FileUtil.java
+++ /dev/null
@@ -1,112 +0,0 @@
-package net.macdidi.myandroidtutorial;
-
-import java.io.File;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.os.Environment;
-import android.util.Log;
-import android.widget.ImageView;
-
-public class FileUtil {
-
- // 應用程式儲存檔案的目錄
- public static final String APP_DIR = "androidtutorial";
-
- // 外部儲存設備是否可寫入
- public static boolean isExternalStorageWritable() {
- // 取得目前外部儲存設備的狀態
- String state = Environment.getExternalStorageState();
-
- // 判斷是否可寫入
- if (Environment.MEDIA_MOUNTED.equals(state)) {
- return true;
- }
-
- return false;
- }
-
- // 外部儲存設備是否可讀取
- public static boolean isExternalStorageReadable() {
- // 取得目前外部儲存設備的狀態
- String state = Environment.getExternalStorageState();
-
- // 判斷是否可讀取
- if (Environment.MEDIA_MOUNTED.equals(state) ||
- Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
- return true;
- }
-
- return false;
- }
-
- // 建立並傳回在公用相簿下參數指定的路徑
- public static File getPublicAlbumStorageDir(String albumName) {
- // 取得公用的照片路徑
- File pictures = Environment.getExternalStoragePublicDirectory(
- Environment.DIRECTORY_PICTURES);
- // 準備在照片路徑下建立一個指定的路徑
- File file = new File(pictures, albumName);
-
- // 如果建立路徑不成功
- if (!file.mkdirs()) {
- Log.e("getAlbumStorageDir", "Directory not created");
- }
-
- return file;
- }
-
- // 建立並傳回在應用程式專用相簿下參數指定的路徑
- public static File getAlbumStorageDir(Context context, String albumName) {
- // 取得應用程式專用的照片路徑
- File pictures = context.getExternalFilesDir(
- Environment.DIRECTORY_PICTURES);
- // 準備在照片路徑下建立一個指定的路徑
- File file = new File(pictures, albumName);
-
- // 如果建立路徑不成功
- if (!file.mkdirs()) {
- Log.e("getAlbumStorageDir", "Directory not created");
- }
-
- return file;
- }
-
- // 建立並傳回外部儲存媒體參數指定的路徑
- public static File getExternalStorageDir(String dir) {
- File result = new File(
- Environment.getExternalStorageDirectory(), dir);
-
- if (!isExternalStorageWritable()) {
- return null;
- }
-
- if (!result.exists() && !result.mkdirs()) {
- return null;
- }
-
- return result;
- }
-
- // 讀取指定的照片檔案名稱設定給ImageView元件
- public static void fileToImageView(String fileName, ImageView imageView) {
- if (new File(fileName).exists()) {
- Bitmap bitmap = BitmapFactory.decodeFile(fileName);
- imageView.setImageBitmap(bitmap);
- }
- else {
- Log.e("fileToImageView", fileName + " not found.");
- }
- }
-
- // 產生唯一的檔案名稱
- public static String getUniqueFileName() {
- // 使用年月日_時分秒格式為檔案名稱
- SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
- return sdf.format(new Date());
- }
-
-}
diff --git a/examples/0401/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/Item.java b/examples/0401/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/Item.java
deleted file mode 100755
index 0161619..0000000
--- a/examples/0401/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/Item.java
+++ /dev/null
@@ -1,136 +0,0 @@
-package net.macdidi.myandroidtutorial;
-
-import java.util.Date;
-import java.util.Locale;
-
-public class Item implements java.io.Serializable {
-
- // 編號、日期時間、顏色、標題、內容、檔案名稱、經緯度、修改、已選擇
- private long id;
- private long datetime;
- private Colors color;
- private String title;
- private String content;
- private String fileName;
- private double latitude;
- private double longitude;
- private long lastModify;
- private boolean selected;
-
- public Item() {
- title = "";
- content = "";
- color = Colors.LIGHTGREY;
- }
-
- public Item(long id, long datetime, Colors color, String title,
- String content, String fileName, double latitude, double longitude,
- long lastModify) {
- this.id = id;
- this.datetime = datetime;
- this.color = color;
- this.title = title;
- this.content = content;
- this.fileName = fileName;
- this.latitude = latitude;
- this.longitude = longitude;
- this.lastModify = lastModify;
- }
-
- public long getId() {
- return id;
- }
-
- public void setId(long id) {
- this.id = id;
- }
-
- public long getDatetime() {
- return datetime;
- }
-
- public String getLocaleDatetime() {
- return String.format(Locale.getDefault(), "%tF % 0) {
- // 照片檔案物件
- File file = configFileName("P", ".jpg");
-
- // 如果照片檔案存在
- if (file.exists()) {
- // 顯示照片元件
- picture.setVisibility(View.VISIBLE);
- // 設定照片
- FileUtil.fileToImageView(file.getAbsolutePath(), picture);
- }
- }
- }
-
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- if (resultCode == Activity.RESULT_OK) {
- switch (requestCode) {
- // 照像
- case START_CAMERA:
- // 設定照片檔案名稱
- item.setFileName(fileName);
- break;
- // 錄音
- case START_RECORD:
- // 設定錄音檔案名稱
- item.setFileName(fileName);
- break;
- case START_LOCATION:
- break;
- case START_ALARM:
- break;
- case START_COLOR:
- int colorId = data.getIntExtra(
- "colorId", Colors.LIGHTGREY.parseColor());
- item.setColor(getColors(colorId));
- break;
- }
- }
- }
-
- public static Colors getColors(int color) {
- Colors result = Colors.LIGHTGREY;
-
- if (color == Colors.BLUE.parseColor()) {
- result = Colors.BLUE;
- }
- else if (color == Colors.PURPLE.parseColor()) {
- result = Colors.PURPLE;
- }
- else if (color == Colors.GREEN.parseColor()) {
- result = Colors.GREEN;
- }
- else if (color == Colors.ORANGE.parseColor()) {
- result = Colors.ORANGE;
- }
- else if (color == Colors.RED.parseColor()) {
- result = Colors.RED;
- }
-
- return result;
- }
-
- private void processViews() {
- title_text = (EditText) findViewById(R.id.title_text);
- content_text = (EditText) findViewById(R.id.content_text);
- picture = (ImageView) findViewById(R.id.picture);
- }
-
- public void onSubmit(View view) {
- if (view.getId() == R.id.ok_teim) {
- String titleText = title_text.getText().toString();
- String contentText = content_text.getText().toString();
-
- item.setTitle(titleText);
- item.setContent(contentText);
-
- if (getIntent().getAction().equals(
- "net.macdidi.myandroidtutorial.EDIT_ITEM")) {
- item.setLastModify(new Date().getTime());
- }
- else {
- item.setDatetime(new Date().getTime());
- SharedPreferences sharedPreferences =
- PreferenceManager.getDefaultSharedPreferences(this);
- int color = sharedPreferences.getInt("DEFAULT_COLOR", -1);
- item.setColor(getColors(color));
- }
-
- Intent result = getIntent();
- result.putExtra("net.macdidi.myandroidtutorial.Item", item);
- setResult(Activity.RESULT_OK, result);
- }
-
- finish();
- }
-
- public void clickFunction(View view) {
- int id = view.getId();
-
- switch (id) {
- case R.id.take_picture:
- // 啟動相機元件用的Intent物件
- Intent intentCamera =
- new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
-
- // 照片檔案名稱
- File pictureFile = configFileName("P", ".jpg");
- Uri uri = Uri.fromFile(pictureFile);
- // 設定檔案名稱
- intentCamera.putExtra(MediaStore.EXTRA_OUTPUT, uri);
- // 啟動相機元件
- startActivityForResult(intentCamera, START_CAMERA);
- break;
- case R.id.record_sound:
- // 錄音檔案名稱
- final File recordFile = configFileName("R", ".mp3");
-
- if (recordFile.exists()) {
- // 詢問播放還是重新錄製的對話框
- AlertDialog.Builder d = new AlertDialog.Builder(this);
-
- d.setTitle(R.string.title_record)
- .setCancelable(true);
- d.setPositiveButton(R.string.record_play,
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- // 播放
- Intent playIntent = new Intent(
- ItemActivity.this, PlayActivity.class);
- playIntent.putExtra("fileName",
- recordFile.getAbsolutePath());
- startActivity(playIntent);
- }
- });
- d.setNegativeButton(R.string.record_new,
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- goToRecord(recordFile);
- }
- });
-
- // 顯示對話框
- d.show();
- }
- else {
- goToRecord(recordFile);
- }
-
- break;
- case R.id.set_location:
- break;
- case R.id.set_alarm:
- break;
- case R.id.select_color:
- startActivityForResult(
- new Intent(this, ColorActivity.class), START_COLOR);
- break;
- }
-
- }
-
- private void goToRecord(File recordFile) {
- // 錄音
- Intent recordIntent = new Intent(this, RecordActivity.class);
- recordIntent.putExtra("fileName", recordFile.getAbsolutePath());
- startActivityForResult(recordIntent, START_RECORD);
- }
-
- private File configFileName(String prefix, String extension) {
- // 如果記事資料已經有檔案名稱
- if (item.getFileName() != null && item.getFileName().length() > 0) {
- fileName = item.getFileName();
- }
- // 產生檔案名稱
- else {
- fileName = FileUtil.getUniqueFileName();
- }
-
- return new File(FileUtil.getExternalStorageDir(FileUtil.APP_DIR),
- prefix + fileName + extension);
- }
-
-}
diff --git a/examples/0401/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/ItemAdapter.java b/examples/0401/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/ItemAdapter.java
deleted file mode 100755
index d6c08f9..0000000
--- a/examples/0401/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/ItemAdapter.java
+++ /dev/null
@@ -1,80 +0,0 @@
-package net.macdidi.myandroidtutorial;
-
-import java.util.List;
-
-import android.content.Context;
-import android.graphics.drawable.GradientDrawable;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ArrayAdapter;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.RelativeLayout;
-import android.widget.TextView;
-
-public class ItemAdapter extends ArrayAdapter- {
-
- // 畫面資源編號
- private int resource;
- // 包裝的記事資料
- private List
- items;
-
- public ItemAdapter(Context context, int resource, List
- items) {
- super(context, resource, items);
- this.resource = resource;
- this.items = items;
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- LinearLayout itemView;
- // 讀取目前位置的記事物件
- final Item item = getItem(position);
-
- if (convertView == null) {
- // 建立項目畫面元件
- itemView = new LinearLayout(getContext());
- String inflater = Context.LAYOUT_INFLATER_SERVICE;
- LayoutInflater li = (LayoutInflater)
- getContext().getSystemService(inflater);
- li.inflate(resource, itemView, true);
- }
- else {
- itemView = (LinearLayout) convertView;
- }
-
- // 讀取記事顏色、已選擇、標題與日期時間元件
- RelativeLayout typeColor = (RelativeLayout) itemView.findViewById(R.id.type_color);
- ImageView selectedItem = (ImageView) itemView.findViewById(R.id.selected_item);
- TextView titleView = (TextView) itemView.findViewById(R.id.title_text);
- TextView dateView = (TextView) itemView.findViewById(R.id.date_text);
-
- // 設定記事顏色
- GradientDrawable background = (GradientDrawable)typeColor.getBackground();
- background.setColor(item.getColor().parseColor());
-
- // 設定標題與日期時間
- titleView.setText(item.getTitle());
- dateView.setText(item.getLocaleDatetime());
-
- // 設定是否已選擇
- selectedItem.setVisibility(item.isSelected() ? View.VISIBLE : View.INVISIBLE);
-
- return itemView;
- }
-
- // 設定指定編號的記事資料
- public void set(int index, Item item) {
- if (index >= 0 && index < items.size()) {
- items.set(index, item);
- notifyDataSetChanged();
- }
- }
-
- // 讀取指定編號的記事資料
- public Item get(int index) {
- return items.get(index);
- }
-
-}
diff --git a/examples/0401/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/ItemDAO.java b/examples/0401/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/ItemDAO.java
deleted file mode 100644
index 3ac59c0..0000000
--- a/examples/0401/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/ItemDAO.java
+++ /dev/null
@@ -1,196 +0,0 @@
-package net.macdidi.myandroidtutorial;
-
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
-
-// 資料功能類別
-public class ItemDAO {
- // 表格名稱
- public static final String TABLE_NAME = "item";
-
- // 編號表格欄位名稱,固定不變
- public static final String KEY_ID = "_id";
-
- // 其它表格欄位名稱
- public static final String DATETIME_COLUMN = "datetime";
- public static final String COLOR_COLUMN = "color";
- public static final String TITLE_COLUMN = "title";
- public static final String CONTENT_COLUMN = "content";
- public static final String FILENAME_COLUMN = "filename";
- public static final String LATITUDE_COLUMN = "latitude";
- public static final String LONGITUDE_COLUMN = "longitude";
- public static final String LASTMODIFY_COLUMN = "lastmodify";
-
- // 使用上面宣告的變數建立表格的SQL指令
- public static final String CREATE_TABLE =
- "CREATE TABLE " + TABLE_NAME + " (" +
- KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
- DATETIME_COLUMN + " INTEGER NOT NULL, " +
- COLOR_COLUMN + " INTEGER NOT NULL, " +
- TITLE_COLUMN + " TEXT NOT NULL, " +
- CONTENT_COLUMN + " TEXT NOT NULL, " +
- FILENAME_COLUMN + " TEXT, " +
- LATITUDE_COLUMN + " REAL, " +
- LONGITUDE_COLUMN + " REAL, " +
- LASTMODIFY_COLUMN + " INTEGER)";
-
- // 資料庫物件
- private SQLiteDatabase db;
-
- // 建構子,一般的應用都不需要修改
- public ItemDAO(Context context) {
- db = MyDBHelper.getDatabase(context);
- }
-
- // 關閉資料庫,一般的應用都不需要修改
- public void close() {
- db.close();
- }
-
- // 新增參數指定的物件
- public Item insert(Item item) {
- // 建立準備新增資料的ContentValues物件
- ContentValues cv = new ContentValues();
-
- // 加入ContentValues物件包裝的新增資料
- // 第一個參數是欄位名稱, 第二個參數是欄位的資料
- cv.put(DATETIME_COLUMN, item.getDatetime());
- cv.put(COLOR_COLUMN, item.getColor().parseColor());
- cv.put(TITLE_COLUMN, item.getTitle());
- cv.put(CONTENT_COLUMN, item.getContent());
- cv.put(FILENAME_COLUMN, item.getFileName());
- cv.put(LATITUDE_COLUMN, item.getLatitude());
- cv.put(LONGITUDE_COLUMN, item.getLongitude());
- cv.put(LASTMODIFY_COLUMN, item.getLastModify());
-
- // 新增一筆資料並取得編號
- // 第一個參數是表格名稱
- // 第二個參數是沒有指定欄位值的預設值
- // 第三個參數是包裝新增資料的ContentValues物件
- long id = db.insert(TABLE_NAME, null, cv);
-
- // 設定編號
- item.setId(id);
- // 回傳結果
- return item;
- }
-
- // 修改參數指定的物件
- public boolean update(Item item) {
- // 建立準備修改資料的ContentValues物件
- ContentValues cv = new ContentValues();
-
- // 加入ContentValues物件包裝的修改資料
- // 第一個參數是欄位名稱, 第二個參數是欄位的資料
- cv.put(DATETIME_COLUMN, item.getDatetime());
- cv.put(COLOR_COLUMN, item.getColor().parseColor());
- cv.put(TITLE_COLUMN, item.getTitle());
- cv.put(CONTENT_COLUMN, item.getContent());
- cv.put(FILENAME_COLUMN, item.getFileName());
- cv.put(LATITUDE_COLUMN, item.getLatitude());
- cv.put(LONGITUDE_COLUMN, item.getLongitude());
- cv.put(LASTMODIFY_COLUMN, item.getLastModify());
-
- // 設定修改資料的條件為編號
- // 格式為「欄位名稱=資料」
- String where = KEY_ID + "=" + item.getId();
-
- // 執行修改資料並回傳修改的資料數量是否成功
- return db.update(TABLE_NAME, cv, where, null) > 0;
- }
-
- // 刪除參數指定編號的資料
- public boolean delete(long id){
- // 設定條件為編號,格式為「欄位名稱=資料」
- String where = KEY_ID + "=" + id;
- // 刪除指定編號資料並回傳刪除是否成功
- return db.delete(TABLE_NAME, where , null) > 0;
- }
-
- // 讀取所有記事資料
- public List
- getAll() {
- List
- result = new ArrayList<>();
- Cursor cursor = db.query(
- TABLE_NAME, null, null, null, null, null, null, null);
-
- while (cursor.moveToNext()) {
- result.add(getRecord(cursor));
- }
-
- cursor.close();
- return result;
- }
-
- // 取得指定編號的資料物件
- public Item get(long id) {
- // 準備回傳結果用的物件
- Item item = null;
- // 使用編號為查詢條件
- String where = KEY_ID + "=" + id;
- // 執行查詢
- Cursor result = db.query(
- TABLE_NAME, null, where, null, null, null, null, null);
-
- // 如果有查詢結果
- if (result.moveToFirst()) {
- // 讀取包裝一筆資料的物件
- item = getRecord(result);
- }
-
- // 關閉Cursor物件
- result.close();
- // 回傳結果
- return item;
- }
-
- // 把Cursor目前的資料包裝為物件
- public Item getRecord(Cursor cursor) {
- // 準備回傳結果用的物件
- Item result = new Item();
-
- result.setId(cursor.getLong(0));
- result.setDatetime(cursor.getLong(1));
- result.setColor(ItemActivity.getColors(cursor.getInt(2)));
- result.setTitle(cursor.getString(3));
- result.setContent(cursor.getString(4));
- result.setFileName(cursor.getString(5));
- result.setLatitude(cursor.getDouble(6));
- result.setLongitude(cursor.getDouble(7));
- result.setLastModify(cursor.getLong(8));
-
- // 回傳結果
- return result;
- }
-
- // 取得資料數量
- public int getCount() {
- int result = 0;
- Cursor cursor = db.rawQuery("SELECT COUNT(*) FROM " + TABLE_NAME, null);
-
- if (cursor.moveToNext()) {
- result = cursor.getInt(0);
- }
-
- return result;
- }
-
- // 建立範例資料
- public void sample() {
- Item item = new Item(0, new Date().getTime(), Colors.RED, "關於Android Tutorial的事情.", "Hello content", "", 0, 0, 0);
- Item item2 = new Item(0, new Date().getTime(), Colors.BLUE, "一隻非常可愛的小狗狗!", "她的名字叫「大熱狗」,又叫\n作「奶嘴」,是一隻非常可愛\n的小狗。", "", 25.04719, 121.516981, 0);
- Item item3 = new Item(0, new Date().getTime(), Colors.GREEN, "一首非常好聽的音樂!", "Hello content", "", 0, 0, 0);
- Item item4 = new Item(0, new Date().getTime(), Colors.ORANGE, "儲存在資料庫的資料", "Hello content", "", 0, 0, 0);
-
- insert(item);
- insert(item2);
- insert(item3);
- insert(item4);
- }
-
-}
diff --git a/examples/0401/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/MainActivity.java b/examples/0401/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/MainActivity.java
deleted file mode 100755
index 95b8a02..0000000
--- a/examples/0401/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/MainActivity.java
+++ /dev/null
@@ -1,244 +0,0 @@
-package net.macdidi.myandroidtutorial;
-
-import java.util.List;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.os.Bundle;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.View.OnLongClickListener;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemClickListener;
-import android.widget.AdapterView.OnItemLongClickListener;
-import android.widget.ListView;
-import android.widget.TextView;
-
-public class MainActivity extends Activity {
-
- private ListView item_list;
- private TextView show_app_name;
-
- private ItemAdapter itemAdapter;
- private List
- items;
-
- private MenuItem add_item, search_item, revert_item, share_item, delete_item;
-
- private int selectedCount = 0;
-
- private ItemDAO itemDAO;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
-
- processViews();
- processControllers();
-
- itemDAO = new ItemDAO(getApplicationContext());
-
- if (itemDAO.getCount() == 0) {
- itemDAO.sample();
- }
-
- items = itemDAO.getAll();
-
- itemAdapter = new ItemAdapter(this, R.layout.single_item, items);
- item_list.setAdapter(itemAdapter);
- }
-
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- if (resultCode == Activity.RESULT_OK) {
- Item item = (Item) data.getExtras().getSerializable(
- "net.macdidi.myandroidtutorial.Item");
-
- if (requestCode == 0) {
- item = itemDAO.insert(item);
- items.add(item);
- itemAdapter.notifyDataSetChanged();
- }
- else if (requestCode == 1) {
- int position = data.getIntExtra("position", -1);
-
- if (position != -1) {
- itemDAO.update(item);
- items.set(position, item);
- itemAdapter.notifyDataSetChanged();
- }
- }
- }
- }
-
- private void processViews() {
- item_list = (ListView)findViewById(R.id.item_list);
- show_app_name = (TextView) findViewById(R.id.show_app_name);
- }
-
- private void processControllers() {
-
- OnItemClickListener itemListener = new OnItemClickListener() {
- @Override
- public void onItemClick(AdapterView> parent, View view,
- int position, long id) {
- Item item = itemAdapter.getItem(position);
-
- if (selectedCount > 0) {
- processMenu(item);
- itemAdapter.set(position, item);
- }
- else {
- Intent intent = new Intent(
- "net.macdidi.myandroidtutorial.EDIT_ITEM");
- intent.putExtra("position", position);
- intent.putExtra("net.macdidi.myandroidtutorial.Item", item);
- startActivityForResult(intent, 1);
- }
- }
- };
-
- item_list.setOnItemClickListener(itemListener);
-
- OnItemLongClickListener itemLongListener = new OnItemLongClickListener() {
- @Override
- public boolean onItemLongClick(AdapterView> parent, View view,
- int position, long id) {
- Item item = itemAdapter.getItem(position);
- processMenu(item);
- itemAdapter.set(position, item);
- return true;
- }
- };
-
- item_list.setOnItemLongClickListener(itemLongListener);
-
- OnLongClickListener listener = new OnLongClickListener() {
-
- @Override
- public boolean onLongClick(View view) {
- AlertDialog.Builder dialog =
- new AlertDialog.Builder(MainActivity.this);
- dialog.setTitle(R.string.app_name)
- .setMessage(R.string.about)
- .show();
- return false;
- }
-
- };
-
- show_app_name.setOnLongClickListener(listener);
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- MenuInflater menuInflater = getMenuInflater();
- menuInflater.inflate(R.menu.main_menu, menu);
-
- add_item = menu.findItem(R.id.add_item);
- search_item = menu.findItem(R.id.search_item);
- revert_item = menu.findItem(R.id.revert_item);
- share_item = menu.findItem(R.id.share_item);
- delete_item = menu.findItem(R.id.delete_item);
-
- processMenu(null);
-
- return true;
- }
-
- public void clickMenuItem(MenuItem item) {
- int itemId = item.getItemId();
-
- switch (itemId) {
- case R.id.search_item:
- break;
- case R.id.add_item:
- Intent intent = new Intent("net.macdidi.myandroidtutorial.ADD_ITEM");
- startActivityForResult(intent, 0);
- break;
- case R.id.revert_item:
- for (int i = 0; i < itemAdapter.getCount(); i++) {
- Item ri = itemAdapter.getItem(i);
-
- if (ri.isSelected()) {
- ri.setSelected(false);
- itemAdapter.set(i, ri);
- }
- }
-
- selectedCount = 0;
- processMenu(null);
-
- break;
- case R.id.delete_item:
- if (selectedCount == 0) {
- break;
- }
-
- AlertDialog.Builder d = new AlertDialog.Builder(this);
- String message = getString(R.string.delete_item);
- d.setTitle(R.string.delete)
- .setMessage(String.format(message, selectedCount));
- d.setPositiveButton(android.R.string.yes,
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- int index = itemAdapter.getCount() - 1;
-
- while (index > -1) {
- Item item = itemAdapter.get(index);
-
- if (item.isSelected()) {
- itemAdapter.remove(item);
- itemDAO.delete(item.getId());
- }
-
- index--;
- }
-
- itemAdapter.notifyDataSetChanged();
- }
- });
- d.setNegativeButton(android.R.string.no, null);
- d.show();
-
- break;
- case R.id.googleplus_item:
- break;
- case R.id.facebook_item:
- break;
- }
- }
-
- public void clickPreferences(MenuItem item) {
- startActivity(new Intent(this, PrefActivity.class));
- }
-
- private void processMenu(Item item) {
- if (item != null) {
- item.setSelected(!item.isSelected());
-
- if (item.isSelected()) {
- selectedCount++;
- }
- else {
- selectedCount--;
- }
- }
-
- add_item.setVisible(selectedCount == 0);
- search_item.setVisible(selectedCount == 0);
- revert_item.setVisible(selectedCount > 0);
- share_item.setVisible(selectedCount > 0);
- delete_item.setVisible(selectedCount > 0);
- }
-
- public void aboutApp(View view) {
- Intent intent = new Intent(this, AboutActivity.class);
- startActivity(intent);
- }
-}
diff --git a/examples/0401/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/MyDBHelper.java b/examples/0401/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/MyDBHelper.java
deleted file mode 100644
index bfd1b06..0000000
--- a/examples/0401/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/MyDBHelper.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package net.macdidi.myandroidtutorial;
-
-import android.content.Context;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteDatabase.CursorFactory;
-import android.database.sqlite.SQLiteOpenHelper;
-
-public class MyDBHelper extends SQLiteOpenHelper {
-
- // 資料庫名稱
- public static final String DATABASE_NAME = "mydata.db";
- // 資料庫版本,資料結構改變的時候要更改這個數字,通常是加一
- public static final int VERSION = 1;
- // 資料庫物件,固定的欄位變數
- private static SQLiteDatabase database;
-
- // 建構子,在一般的應用都不需要修改
- public MyDBHelper(Context context, String name, CursorFactory factory,
- int version) {
- super(context, name, factory, version);
- }
-
- // 需要資料庫的元件呼叫這個方法,這個方法在一般的應用都不需要修改
- public static SQLiteDatabase getDatabase(Context context) {
- if (database == null || !database.isOpen()) {
- database = new MyDBHelper(context, DATABASE_NAME,
- null, VERSION).getWritableDatabase();
- }
-
- return database;
- }
-
- @Override
- public void onCreate(SQLiteDatabase db) {
- // 建立應用程式需要的表格
- db.execSQL(ItemDAO.CREATE_TABLE);
- }
-
- @Override
- public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
- // 刪除原有的表格
- db.execSQL("DROP TABLE IF EXISTS " + ItemDAO.TABLE_NAME);
- // 呼叫onCreate建立新版的表格
- onCreate(db);
- }
-
-}
diff --git a/examples/0401/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/PlayActivity.java b/examples/0401/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/PlayActivity.java
deleted file mode 100755
index dc07a90..0000000
--- a/examples/0401/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/PlayActivity.java
+++ /dev/null
@@ -1,148 +0,0 @@
-package net.macdidi.myandroidtutorial;
-
-import java.io.IOException;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.media.MediaPlayer;
-import android.media.MediaPlayer.OnCompletionListener;
-import android.net.Uri;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.View;
-import android.widget.SeekBar;
-
-public class PlayActivity extends Activity {
-
- private SeekBar control;
- private MediaPlayer mediaPlayer;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_play);
-
- processViews();
- processControllers();
-
- Intent intent = getIntent();
- String fileName = intent.getStringExtra("fileName");
-
- // 建立指定資源的MediaPlayer物件
- Uri uri = Uri.parse(fileName);
- mediaPlayer = MediaPlayer.create(this, uri);
- // 註冊播放完畢監聽事件
- mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
- @Override
- public void onCompletion(MediaPlayer player) {
- // 切換按鈕為可播放
- clickStop(null);
- }
- });
-
- // 設定SeekBar元件的最大值為音樂的總時間(毫秒)
- control.setMax(mediaPlayer.getDuration());
- }
-
- @Override
- protected void onPause() {
- mediaPlayer.stop();
- super.onPause();
- }
-
- public void onSubmit(View view) {
- if (view.getId() == R.id.ok_add_teim) {
-
- }
-
- finish();
- }
-
- private void processViews() {
- control = (SeekBar) findViewById(R.id.control);
- }
-
- private void processControllers() {
- // 註冊SeekBar元件進度改變事件
- control.setOnSeekBarChangeListener(
- new SeekBar.OnSeekBarChangeListener() {
- @Override
- public void onProgressChanged(SeekBar seekBar,
- int progress, boolean fromUser) {
- // 一定要判斷是使用者的操作,因為播放過程也會更改進度
- if (fromUser) {
- // 移動音樂到指定的進度
- mediaPlayer.seekTo(progress);
- }
- }
-
- @Override
- public void onStartTrackingTouch(SeekBar seekBar) {}
-
- @Override
- public void onStopTrackingTouch(SeekBar seekBar) {}
- });
- }
-
- public void clickPlay(View view) {
- // 開始播放
- mediaPlayer.start();
- // 建立並執行顯示播放進度的AsyncTask物件
- new MyPlayTask().execute();
- }
-
- public void clickPause(View view) {
- // 暫停播放
- mediaPlayer.pause();
- }
-
- public void clickStop(View view) {
- // 停止播放
- mediaPlayer.stop();
-
- try {
- // 重新設定
- mediaPlayer.prepare();
- }
- catch (IOException e) {
- Log.d("PlayActivity", e.toString());
- }
-
- // 回到開始的位置
- mediaPlayer.seekTo(0);
- control.setProgress(0);
- }
-
- // 播放完成監聽類別
- private class MyCompletion implements OnCompletionListener {
- @Override
- public void onCompletion(MediaPlayer player) {
- // 清除MediaPlayer物件
- player.release();
- }
- }
-
- // 在播放過程中顯示播放進度
- private class MyPlayTask extends AsyncTask
{
-
- @Override
- protected Void doInBackground(Void... args) {
- while (mediaPlayer.isPlaying()) {
- // 設定播放進度
- control.setProgress(mediaPlayer.getCurrentPosition());
-
- try {
- Thread.sleep(1000);
- }
- catch (InterruptedException e) {
- Log.d("PlayActivity", e.toString());
- }
- }
-
- return null;
- }
-
- }
-
-}
diff --git a/examples/0401/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/PrefActivity.java b/examples/0401/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/PrefActivity.java
deleted file mode 100644
index aa37810..0000000
--- a/examples/0401/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/PrefActivity.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package net.macdidi.myandroidtutorial;
-
-import android.content.SharedPreferences;
-import android.os.Bundle;
-import android.preference.Preference;
-import android.preference.PreferenceActivity;
-import android.preference.PreferenceManager;
-
-public class PrefActivity extends PreferenceActivity {
-
- private SharedPreferences sharedPreferences;
- private Preference defaultColor;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- // 指定使用的設定畫面配置資源
- addPreferencesFromResource(R.xml.mypreference);
- defaultColor = (Preference)findPreference("DEFAULT_COLOR");
- // 建立SharedPreferences物件
- sharedPreferences =
- PreferenceManager.getDefaultSharedPreferences(this);
- }
-
- @Override
- protected void onResume() {
- super.onResume();
- // 讀取設定的預設顏色
- int color = sharedPreferences.getInt("DEFAULT_COLOR", -1);
-
- if (color != -1) {
- // 設定顏色說明
- defaultColor.setSummary(getString(R.string.default_color_summary) +
- ": " + ItemActivity.getColors(color));
- }
- }
-
-}
diff --git a/examples/0401/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/RecordActivity.java b/examples/0401/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/RecordActivity.java
deleted file mode 100755
index 95558a8..0000000
--- a/examples/0401/MyAndroidTutorial/src/net/macdidi/myandroidtutorial/RecordActivity.java
+++ /dev/null
@@ -1,180 +0,0 @@
-package net.macdidi.myandroidtutorial;
-
-import java.io.IOException;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.media.MediaRecorder;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.View;
-import android.widget.ImageButton;
-import android.widget.ProgressBar;
-
-public class RecordActivity extends Activity {
-
- private ImageButton record_button;
- private boolean isRecording = false;
- private ProgressBar record_volumn;
-
- private MyRecoder myRecoder;
-
- private String fileName;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_record);
-
- processViews();
-
- // 讀取檔案名稱
- Intent intent = getIntent();
- fileName = intent.getStringExtra("fileName");
- }
-
- public void onSubmit(View view) {
- if (isRecording) {
- // 停止錄音
- myRecoder.stop();
- }
-
- // 確定
- if (view.getId() == R.id.record_ok) {
- Intent result = getIntent();
- setResult(Activity.RESULT_OK, result);
- }
-
- finish();
- }
-
- private void processViews() {
- record_button = (ImageButton) findViewById(R.id.record_button);
- record_volumn = (ProgressBar) findViewById(R.id.record_volumn);
- // 隱藏狀態列ProgressBar
- setProgressBarIndeterminateVisibility(false);
- }
-
- public void clickRecord(View view) {
- // 切換
- isRecording = !isRecording;
-
- // 開始錄音
- if (isRecording) {
- // 設定按鈕圖示為錄音中
- record_button.setImageResource(R.drawable.record_red_icon);
- // 建立錄音物件
- myRecoder = new MyRecoder(fileName);
- // 開始錄音
- myRecoder.start();
- // 建立並執行顯示麥克風音量的AsyncTask物件
- new MicLevelTask().execute();
- }
- // 停止錄音
- else {
- // 設定按鈕圖示為停止錄音
- record_button.setImageResource(R.drawable.record_dark_icon);
- // 麥克風音量歸零
- record_volumn.setProgress(0);
- // 停止錄音
- myRecoder.stop();
- }
- }
-
- // 在錄音過程中顯示麥克風音量
- private class MicLevelTask extends AsyncTask {
- @Override
- protected Void doInBackground(Void... args) {
- while (isRecording) {
- publishProgress();
-
- try {
- Thread.sleep(200);
- }
- catch (InterruptedException e) {
- Log.d("RecordActivity", e.toString());
- }
- }
-
- return null;
- }
-
- @Override
- protected void onProgressUpdate(Void... values) {
- record_volumn.setProgress((int) myRecoder.getAmplitudeEMA());
- }
-
- }
-
- // 執行錄音並且可以取得麥克風音量的錄音物件
- private class MyRecoder {
-
- private static final double EMA_FILTER = 0.6;
- private MediaRecorder recorder = null;
- private double mEMA = 0.0;
- private String output;
-
- // 建立錄音物件,參數為錄音儲存的位置與檔名
- MyRecoder(String output) {
- this.output = output;
- }
-
- // 開始錄音
- public void start() {
- if (recorder == null) {
- // 建立錄音用的MediaRecorder物件
- recorder = new MediaRecorder();
- // 設定錄音來源為麥克風,必須在setOutputFormat方法之前呼叫
- recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
- // 設定輸出格式為3GP壓縮格式,必須在setAudioSource方法之後,
- // 在prepare方法之前呼叫
- recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
- // 設定錄音的編碼方式,必須在setOutputFormat方法之後,
- // 在prepare方法之前呼叫
- recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
- // 設定輸出的檔案名稱,必須在setOutputFormat方法之後,
- // 在prepare方法之前呼叫
- recorder.setOutputFile(output);
-
- try {
- // 準備執行錄音工作,必須在所有設定之後呼叫
- recorder.prepare();
- }
- catch (IOException e) {
- Log.d("RecordActivity", e.toString());
- }
-
- // 開始錄音
- recorder.start();
- mEMA = 0.0;
- }
- }
-
- // 停止錄音
- public void stop() {
- if (recorder != null) {
- // 停止錄音
- recorder.stop();
- // 清除錄音資源
- recorder.release();
- recorder = null;
- }
- }
-
- public double getAmplitude() {
- if (recorder != null)
- return (recorder.getMaxAmplitude() / 2700.0);
- else
- return 0;
- }
-
- // 取得麥克風音量
- public double getAmplitudeEMA() {
- double amp = getAmplitude();
- mEMA = EMA_FILTER * amp + (1.0 - EMA_FILTER) * mEMA;
- return mEMA;
- }
- }
-
-}
diff --git a/examples/0402/MyAndroidTutorial/.gitignore b/examples/0402/MyAndroidTutorial/.gitignore
new file mode 100644
index 0000000..afbdab3
--- /dev/null
+++ b/examples/0402/MyAndroidTutorial/.gitignore
@@ -0,0 +1,6 @@
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
diff --git a/examples/0402/MyAndroidTutorial/.idea/.name b/examples/0402/MyAndroidTutorial/.idea/.name
new file mode 100644
index 0000000..5bb7a85
--- /dev/null
+++ b/examples/0402/MyAndroidTutorial/.idea/.name
@@ -0,0 +1 @@
+MyAndroidTutorial
\ No newline at end of file
diff --git a/examples/0402/MyAndroidTutorial/.idea/compiler.xml b/examples/0402/MyAndroidTutorial/.idea/compiler.xml
new file mode 100644
index 0000000..217af47
--- /dev/null
+++ b/examples/0402/MyAndroidTutorial/.idea/compiler.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0402/MyAndroidTutorial/.idea/copyright/profiles_settings.xml b/examples/0402/MyAndroidTutorial/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..e7bedf3
--- /dev/null
+++ b/examples/0402/MyAndroidTutorial/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/examples/0402/MyAndroidTutorial/.idea/encodings.xml b/examples/0402/MyAndroidTutorial/.idea/encodings.xml
new file mode 100644
index 0000000..e206d70
--- /dev/null
+++ b/examples/0402/MyAndroidTutorial/.idea/encodings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/examples/0402/MyAndroidTutorial/.idea/gradle.xml b/examples/0402/MyAndroidTutorial/.idea/gradle.xml
new file mode 100644
index 0000000..fe865d3
--- /dev/null
+++ b/examples/0402/MyAndroidTutorial/.idea/gradle.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0402/MyAndroidTutorial/.idea/misc.xml b/examples/0402/MyAndroidTutorial/.idea/misc.xml
new file mode 100644
index 0000000..9076de5
--- /dev/null
+++ b/examples/0402/MyAndroidTutorial/.idea/misc.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0402/MyAndroidTutorial/.idea/modules.xml b/examples/0402/MyAndroidTutorial/.idea/modules.xml
new file mode 100644
index 0000000..327df67
--- /dev/null
+++ b/examples/0402/MyAndroidTutorial/.idea/modules.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0402/MyAndroidTutorial/.idea/scopes/scope_settings.xml b/examples/0402/MyAndroidTutorial/.idea/scopes/scope_settings.xml
new file mode 100644
index 0000000..922003b
--- /dev/null
+++ b/examples/0402/MyAndroidTutorial/.idea/scopes/scope_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0402/MyAndroidTutorial/.idea/vcs.xml b/examples/0402/MyAndroidTutorial/.idea/vcs.xml
new file mode 100644
index 0000000..def6a6a
--- /dev/null
+++ b/examples/0402/MyAndroidTutorial/.idea/vcs.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/examples/0402/MyAndroidTutorial/MyAndroidTutorial.iml b/examples/0402/MyAndroidTutorial/MyAndroidTutorial.iml
new file mode 100644
index 0000000..0bb6048
--- /dev/null
+++ b/examples/0402/MyAndroidTutorial/MyAndroidTutorial.iml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0402/MyAndroidTutorial/app/.gitignore b/examples/0402/MyAndroidTutorial/app/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/examples/0402/MyAndroidTutorial/app/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/examples/0402/MyAndroidTutorial/app/app.iml b/examples/0402/MyAndroidTutorial/app/app.iml
new file mode 100644
index 0000000..b767e16
--- /dev/null
+++ b/examples/0402/MyAndroidTutorial/app/app.iml
@@ -0,0 +1,113 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0402/MyAndroidTutorial/app/build.gradle b/examples/0402/MyAndroidTutorial/app/build.gradle
new file mode 100644
index 0000000..e1475ee
--- /dev/null
+++ b/examples/0402/MyAndroidTutorial/app/build.gradle
@@ -0,0 +1,26 @@
+apply plugin: 'com.android.application'
+
+android {
+ compileSdkVersion 21
+ buildToolsVersion "21.1.2"
+
+ defaultConfig {
+ applicationId "net.macdidi.myandroidtutorial"
+ minSdkVersion 15
+ targetSdkVersion 21
+ versionCode 1
+ versionName "1.0"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ compile fileTree(dir: 'libs', include: ['*.jar'])
+ compile 'com.android.support:appcompat-v7:22.0.0'
+ compile 'com.google.android.gms:play-services:7.0.0'
+}
diff --git a/examples/0402/MyAndroidTutorial/app/proguard-rules.pro b/examples/0402/MyAndroidTutorial/app/proguard-rules.pro
new file mode 100644
index 0000000..b5fa7ec
--- /dev/null
+++ b/examples/0402/MyAndroidTutorial/app/proguard-rules.pro
@@ -0,0 +1,17 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /Users/macdidi5/Library/Android/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
diff --git a/examples/0402/MyAndroidTutorial/app/src/androidTest/java/net/macdidi/myandroidtutorial/ApplicationTest.java b/examples/0402/MyAndroidTutorial/app/src/androidTest/java/net/macdidi/myandroidtutorial/ApplicationTest.java
new file mode 100644
index 0000000..2cb214e
--- /dev/null
+++ b/examples/0402/MyAndroidTutorial/app/src/androidTest/java/net/macdidi/myandroidtutorial/ApplicationTest.java
@@ -0,0 +1,13 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Application;
+import android.test.ApplicationTestCase;
+
+/**
+ * Testing Fundamentals
+ */
+public class ApplicationTest extends ApplicationTestCase {
+ public ApplicationTest() {
+ super(Application.class);
+ }
+}
\ No newline at end of file
diff --git a/examples/0402/MyAndroidTutorial/app/src/debug/res/values/google_maps_api.xml b/examples/0402/MyAndroidTutorial/app/src/debug/res/values/google_maps_api.xml
new file mode 100644
index 0000000..7341c8d
--- /dev/null
+++ b/examples/0402/MyAndroidTutorial/app/src/debug/res/values/google_maps_api.xml
@@ -0,0 +1,18 @@
+
+
+
+ AIzaSyCZg9YWlfokPA96VxWGYr6u4C12jL16VhM
+
+
diff --git a/examples/0402/MyAndroidTutorial/app/src/main/AndroidManifest.xml b/examples/0402/MyAndroidTutorial/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..1a59a4f
--- /dev/null
+++ b/examples/0402/MyAndroidTutorial/app/src/main/AndroidManifest.xml
@@ -0,0 +1,93 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0402/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/AboutActivity.java b/examples/0402/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/AboutActivity.java
new file mode 100644
index 0000000..42dddeb
--- /dev/null
+++ b/examples/0402/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/AboutActivity.java
@@ -0,0 +1,24 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.view.Window;
+
+public class AboutActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ // 取消元件的應用程式標題
+ requestWindowFeature(Window.FEATURE_NO_TITLE);
+ setContentView(R.layout.activity_about);
+ }
+
+ // 結束按鈕
+ public void clickOk(View view) {
+ // 呼叫這個方法結束Activity元件
+ finish();
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0402/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ColorActivity.java b/examples/0402/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ColorActivity.java
new file mode 100644
index 0000000..182cd55
--- /dev/null
+++ b/examples/0402/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ColorActivity.java
@@ -0,0 +1,75 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.LinearLayout;
+
+public class ColorActivity extends Activity {
+
+ private LinearLayout color_gallery;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_color);
+
+ processViews();
+
+ ColorListener listener = new ColorListener();
+
+ for (Colors c : Colors.values()) {
+ Button button = new Button(this);
+ button.setId(c.parseColor());
+ LinearLayout.LayoutParams layout =
+ new LinearLayout.LayoutParams(128, 128);
+ layout.setMargins(6, 6, 6, 6);
+ button.setLayoutParams(layout);
+ button.setBackgroundColor(c.parseColor());
+
+ button.setOnClickListener(listener);
+
+ color_gallery.addView(button);
+ }
+ }
+
+ private void processViews() {
+ color_gallery = (LinearLayout) findViewById(R.id.color_gallery);
+ }
+
+ private class ColorListener implements OnClickListener {
+
+ @Override
+ public void onClick(View view) {
+ String action = ColorActivity.this.getIntent().getAction();
+
+ // 經由設定元件啟動
+ if (action != null &&
+ action.equals("net.macdidi.myandroidtutorial.CHOOSE_COLOR")) {
+ // 建立SharedPreferences物件
+ SharedPreferences.Editor editor =
+ PreferenceManager.getDefaultSharedPreferences(
+ ColorActivity.this).edit();
+ // 儲存預設顏色
+ editor.putInt("DEFAULT_COLOR", view.getId());
+ // 寫入設定值
+ editor.commit();
+ finish();
+ }
+ // 經由新增或修改記事的元件啟動
+ else {
+ Intent result = getIntent();
+ result.putExtra("colorId", view.getId());
+ setResult(Activity.RESULT_OK, result);
+ finish();
+ }
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0402/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Colors.java b/examples/0402/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Colors.java
new file mode 100644
index 0000000..1462149
--- /dev/null
+++ b/examples/0402/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Colors.java
@@ -0,0 +1,24 @@
+package net.macdidi.myandroidtutorial;
+
+import android.graphics.Color;
+
+public enum Colors {
+
+ LIGHTGREY("#D3D3D3"), BLUE("#33B5E5"), PURPLE("#AA66CC"),
+ GREEN("#99CC00"), ORANGE("#FFBB33"), RED("#FF4444");
+
+ private String code;
+
+ private Colors(String code) {
+ this.code = code;
+ }
+
+ public String getCode() {
+ return code;
+ }
+
+ public int parseColor() {
+ return Color.parseColor(code);
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0402/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/FileUtil.java b/examples/0402/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/FileUtil.java
new file mode 100644
index 0000000..1fb41be
--- /dev/null
+++ b/examples/0402/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/FileUtil.java
@@ -0,0 +1,112 @@
+package net.macdidi.myandroidtutorial;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.os.Environment;
+import android.util.Log;
+import android.widget.ImageView;
+
+import java.io.File;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+public class FileUtil {
+
+ // 應用程式儲存檔案的目錄
+ public static final String APP_DIR = "androidtutorial";
+
+ // 外部儲存設備是否可寫入
+ public static boolean isExternalStorageWritable() {
+ // 取得目前外部儲存設備的狀態
+ String state = Environment.getExternalStorageState();
+
+ // 判斷是否可寫入
+ if (Environment.MEDIA_MOUNTED.equals(state)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ // 外部儲存設備是否可讀取
+ public static boolean isExternalStorageReadable() {
+ // 取得目前外部儲存設備的狀態
+ String state = Environment.getExternalStorageState();
+
+ // 判斷是否可讀取
+ if (Environment.MEDIA_MOUNTED.equals(state) ||
+ Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ // 建立並傳回在公用相簿下參數指定的路徑
+ public static File getPublicAlbumStorageDir(String albumName) {
+ // 取得公用的照片路徑
+ File pictures = Environment.getExternalStoragePublicDirectory(
+ Environment.DIRECTORY_PICTURES);
+ // 準備在照片路徑下建立一個指定的路徑
+ File file = new File(pictures, albumName);
+
+ // 如果建立路徑不成功
+ if (!file.mkdirs()) {
+ Log.e("getAlbumStorageDir", "Directory not created");
+ }
+
+ return file;
+ }
+
+ // 建立並傳回在應用程式專用相簿下參數指定的路徑
+ public static File getAlbumStorageDir(Context context, String albumName) {
+ // 取得應用程式專用的照片路徑
+ File pictures = context.getExternalFilesDir(
+ Environment.DIRECTORY_PICTURES);
+ // 準備在照片路徑下建立一個指定的路徑
+ File file = new File(pictures, albumName);
+
+ // 如果建立路徑不成功
+ if (!file.mkdirs()) {
+ Log.e("getAlbumStorageDir", "Directory not created");
+ }
+
+ return file;
+ }
+
+ // 建立並傳回外部儲存媒體參數指定的路徑
+ public static File getExternalStorageDir(String dir) {
+ File result = new File(
+ Environment.getExternalStorageDirectory(), dir);
+
+ if (!isExternalStorageWritable()) {
+ return null;
+ }
+
+ if (!result.exists() && !result.mkdirs()) {
+ return null;
+ }
+
+ return result;
+ }
+
+ // 讀取指定的照片檔案名稱設定給ImageView元件
+ public static void fileToImageView(String fileName, ImageView imageView) {
+ if (new File(fileName).exists()) {
+ Bitmap bitmap = BitmapFactory.decodeFile(fileName);
+ imageView.setImageBitmap(bitmap);
+ }
+ else {
+ Log.e("fileToImageView", fileName + " not found.");
+ }
+ }
+
+ // 產生唯一的檔案名稱
+ public static String getUniqueFileName() {
+ // 使用年月日_時分秒格式為檔案名稱
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
+ return sdf.format(new Date());
+ }
+
+}
diff --git a/examples/0402/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Item.java b/examples/0402/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Item.java
new file mode 100644
index 0000000..d65ad74
--- /dev/null
+++ b/examples/0402/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Item.java
@@ -0,0 +1,146 @@
+package net.macdidi.myandroidtutorial;
+
+import java.util.Date;
+import java.util.Locale;
+
+public class Item implements java.io.Serializable {
+
+ // 編號、日期時間、顏色、標題、內容、檔案名稱、經緯度、修改、已選擇
+ private long id;
+ private long datetime;
+ private Colors color;
+ private String title;
+ private String content;
+ private String fileName;
+ private String recFileName;
+ private double latitude;
+ private double longitude;
+ private long lastModify;
+ private boolean selected;
+
+ public Item() {
+ title = "";
+ content = "";
+ color = Colors.LIGHTGREY;
+ }
+
+ public Item(long id, long datetime, Colors color, String title,
+ String content, String fileName, String recFileName,
+ double latitude, double longitude, long lastModify) {
+ this.id = id;
+ this.datetime = datetime;
+ this.color = color;
+ this.title = title;
+ this.content = content;
+ this.fileName = fileName;
+ // 錄音檔案名稱
+ this.recFileName = recFileName;
+ this.latitude = latitude;
+ this.longitude = longitude;
+ this.lastModify = lastModify;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public long getDatetime() {
+ return datetime;
+ }
+
+ // 裝置區域的日期時間
+ public String getLocaleDatetime() {
+ return String.format(Locale.getDefault(), "%tF % 0) {
+ // 照片檔案物件
+ File file = configFileName("P", ".jpg");
+
+ // 如果照片檔案存在
+ if (file.exists()) {
+ // 顯示照片元件
+ picture.setVisibility(View.VISIBLE);
+ // 設定照片
+ FileUtil.fileToImageView(file.getAbsolutePath(), picture);
+ }
+ }
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (resultCode == Activity.RESULT_OK) {
+ switch (requestCode) {
+ // 照像
+ case START_CAMERA:
+ // 設定照片檔案名稱
+ item.setFileName(fileName);
+ break;
+ case START_RECORD:
+ // 設定錄音檔案名稱
+ item.setRecFileName(recFileName);
+ break;
+ case START_LOCATION:
+ break;
+ case START_ALARM:
+ break;
+ // 設定顏色
+ case START_COLOR:
+ int colorId = data.getIntExtra(
+ "colorId", Colors.LIGHTGREY.parseColor());
+ item.setColor(getColors(colorId));
+ break;
+ }
+ }
+ }
+
+ public static Colors getColors(int color) {
+ Colors result = Colors.LIGHTGREY;
+
+ if (color == Colors.BLUE.parseColor()) {
+ result = Colors.BLUE;
+ }
+ else if (color == Colors.PURPLE.parseColor()) {
+ result = Colors.PURPLE;
+ }
+ else if (color == Colors.GREEN.parseColor()) {
+ result = Colors.GREEN;
+ }
+ else if (color == Colors.ORANGE.parseColor()) {
+ result = Colors.ORANGE;
+ }
+ else if (color == Colors.RED.parseColor()) {
+ result = Colors.RED;
+ }
+
+ return result;
+ }
+
+ private void processViews() {
+ title_text = (EditText) findViewById(R.id.title_text);
+ content_text = (EditText) findViewById(R.id.content_text);
+ // 取得顯示照片的ImageView元件
+ picture = (ImageView) findViewById(R.id.picture);
+ }
+
+ // 點擊確定與取消按鈕都會呼叫這個方法
+ public void onSubmit(View view) {
+
+ if (view.getId() == R.id.ok_teim) {
+ String titleText = title_text.getText().toString();
+ String contentText = content_text.getText().toString();
+
+ item.setTitle(titleText);
+ item.setContent(contentText);
+
+ if (getIntent().getAction().equals(
+ "net.macdidi.myandroidtutorial.EDIT_ITEM")) {
+ item.setLastModify(new Date().getTime());
+ }
+ // 新增記事
+ else {
+ item.setDatetime(new Date().getTime());
+ // 建立SharedPreferences物件
+ SharedPreferences sharedPreferences =
+ PreferenceManager.getDefaultSharedPreferences(this);
+ // 讀取設定的預設顏色
+ int color = sharedPreferences.getInt("DEFAULT_COLOR", -1);
+ item.setColor(getColors(color));
+ }
+
+ Intent result = getIntent();
+ result.putExtra("net.macdidi.myandroidtutorial.Item", item);
+ setResult(Activity.RESULT_OK, result);
+ }
+
+ // 結束
+ finish();
+ }
+
+ public void clickFunction(View view) {
+ int id = view.getId();
+
+ switch (id) {
+ case R.id.take_picture:
+ // 啟動相機元件用的Intent物件
+ Intent intentCamera =
+ new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
+
+ // 照片檔案名稱
+ File pictureFile = configFileName("P", ".jpg");
+ Uri uri = Uri.fromFile(pictureFile);
+ // 設定檔案名稱
+ intentCamera.putExtra(MediaStore.EXTRA_OUTPUT, uri);
+ // 啟動相機元件
+ startActivityForResult(intentCamera, START_CAMERA);
+ break;
+ case R.id.record_sound:
+ // 錄音檔案名稱
+ final File recordFile = configRecFileName("R", ".mp3");
+
+ // 如果已經有錄音檔,詢問播放或重新錄製
+ if (recordFile.exists()) {
+ // 詢問播放還是重新錄製的對話框
+ AlertDialog.Builder d = new AlertDialog.Builder(this);
+
+ d.setTitle(R.string.title_record)
+ .setCancelable(false);
+ d.setPositiveButton(R.string.record_play,
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ // 播放
+ Intent playIntent = new Intent(
+ ItemActivity.this, PlayActivity.class);
+ playIntent.putExtra("fileName",
+ recordFile.getAbsolutePath());
+ startActivity(playIntent);
+ }
+ });
+ d.setNeutralButton(R.string.record_new,
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ goToRecord(recordFile);
+ }
+ });
+ d.setNegativeButton(android.R.string.cancel, null);
+
+ // 顯示對話框
+ d.show();
+ }
+ // 如果沒有錄音檔,啟動錄音元件
+ else {
+ goToRecord(recordFile);
+ }
+
+ break;
+ case R.id.set_location:
+ // 啟動地圖元件用的Intent物件
+ Intent intentMap = new Intent(this, MapsActivity.class);
+ // 啟動地圖元件
+ startActivityForResult(intentMap, START_LOCATION);
+ break;
+ case R.id.set_alarm:
+ break;
+ case R.id.select_color:
+ // 啟動設定顏色的Activity元件
+ startActivityForResult(
+ new Intent(this, ColorActivity.class), START_COLOR);
+ break;
+ }
+
+ }
+
+ private void goToRecord(File recordFile) {
+ // 錄音
+ Intent recordIntent = new Intent(this, RecordActivity.class);
+ recordIntent.putExtra("fileName", recordFile.getAbsolutePath());
+ startActivityForResult(recordIntent, START_RECORD);
+ }
+
+ private File configFileName(String prefix, String extension) {
+ // 如果記事資料已經有檔案名稱
+ if (item.getFileName() != null && item.getFileName().length() > 0) {
+ fileName = item.getFileName();
+ }
+ // 產生檔案名稱
+ else {
+ fileName = FileUtil.getUniqueFileName();
+ }
+
+ return new File(FileUtil.getExternalStorageDir(FileUtil.APP_DIR),
+ prefix + fileName + extension);
+ }
+
+ private File configRecFileName(String prefix, String extension) {
+ // 如果記事資料已經有檔案名稱
+ if (item.getRecFileName() != null && item.getRecFileName().length() > 0) {
+ recFileName = item.getRecFileName();
+ }
+ // 產生檔案名稱
+ else {
+ recFileName = FileUtil.getUniqueFileName();
+ }
+
+ return new File(FileUtil.getExternalStorageDir(FileUtil.APP_DIR),
+ prefix + recFileName + extension);
+ }
+
+}
diff --git a/examples/0402/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemAdapter.java b/examples/0402/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemAdapter.java
new file mode 100644
index 0000000..85b40ba
--- /dev/null
+++ b/examples/0402/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemAdapter.java
@@ -0,0 +1,80 @@
+package net.macdidi.myandroidtutorial;
+
+import android.content.Context;
+import android.graphics.drawable.GradientDrawable;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+import java.util.List;
+
+public class ItemAdapter extends ArrayAdapter- {
+
+ // 畫面資源編號
+ private int resource;
+ // 包裝的記事資料
+ private List
- items;
+
+ public ItemAdapter(Context context, int resource, List
- items) {
+ super(context, resource, items);
+ this.resource = resource;
+ this.items = items;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ LinearLayout itemView;
+ // 讀取目前位置的記事物件
+ final Item item = getItem(position);
+
+ if (convertView == null) {
+ // 建立項目畫面元件
+ itemView = new LinearLayout(getContext());
+ String inflater = Context.LAYOUT_INFLATER_SERVICE;
+ LayoutInflater li = (LayoutInflater)
+ getContext().getSystemService(inflater);
+ li.inflate(resource, itemView, true);
+ }
+ else {
+ itemView = (LinearLayout) convertView;
+ }
+
+ // 讀取記事顏色、已選擇、標題與日期時間元件
+ RelativeLayout typeColor = (RelativeLayout) itemView.findViewById(R.id.type_color);
+ ImageView selectedItem = (ImageView) itemView.findViewById(R.id.selected_item);
+ TextView titleView = (TextView) itemView.findViewById(R.id.title_text);
+ TextView dateView = (TextView) itemView.findViewById(R.id.date_text);
+
+ // 設定記事顏色
+ GradientDrawable background = (GradientDrawable)typeColor.getBackground();
+ background.setColor(item.getColor().parseColor());
+
+ // 設定標題與日期時間
+ titleView.setText(item.getTitle());
+ dateView.setText(item.getLocaleDatetime());
+
+ // 設定是否已選擇
+ selectedItem.setVisibility(item.isSelected() ? View.VISIBLE : View.INVISIBLE);
+
+ return itemView;
+ }
+
+ // 設定指定編號的記事資料
+ public void set(int index, Item item) {
+ if (index >= 0 && index < items.size()) {
+ items.set(index, item);
+ notifyDataSetChanged();
+ }
+ }
+
+ // 讀取指定編號的記事資料
+ public Item get(int index) {
+ return items.get(index);
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0402/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemDAO.java b/examples/0402/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemDAO.java
new file mode 100644
index 0000000..ac5a57a
--- /dev/null
+++ b/examples/0402/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemDAO.java
@@ -0,0 +1,201 @@
+package net.macdidi.myandroidtutorial;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+// 資料功能類別
+public class ItemDAO {
+ // 表格名稱
+ public static final String TABLE_NAME = "item";
+
+ // 編號表格欄位名稱,固定不變
+ public static final String KEY_ID = "_id";
+
+ // 其它表格欄位名稱
+ public static final String DATETIME_COLUMN = "datetime";
+ public static final String COLOR_COLUMN = "color";
+ public static final String TITLE_COLUMN = "title";
+ public static final String CONTENT_COLUMN = "content";
+ public static final String FILENAME_COLUMN = "filename";
+ public static final String RECFILENAME_COLUMN = "recfilename";
+ public static final String LATITUDE_COLUMN = "latitude";
+ public static final String LONGITUDE_COLUMN = "longitude";
+ public static final String LASTMODIFY_COLUMN = "lastmodify";
+
+ // 使用上面宣告的變數建立表格的SQL指令
+ public static final String CREATE_TABLE =
+ "CREATE TABLE " + TABLE_NAME + " (" +
+ KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
+ DATETIME_COLUMN + " INTEGER NOT NULL, " +
+ COLOR_COLUMN + " INTEGER NOT NULL, " +
+ TITLE_COLUMN + " TEXT NOT NULL, " +
+ CONTENT_COLUMN + " TEXT NOT NULL, " +
+ FILENAME_COLUMN + " TEXT, " +
+ RECFILENAME_COLUMN + " TEXT, " +
+ LATITUDE_COLUMN + " REAL, " +
+ LONGITUDE_COLUMN + " REAL, " +
+ LASTMODIFY_COLUMN + " INTEGER)";
+
+ // 資料庫物件
+ private SQLiteDatabase db;
+
+ // 建構子,一般的應用都不需要修改
+ public ItemDAO(Context context) {
+ db = MyDBHelper.getDatabase(context);
+ }
+
+ // 關閉資料庫,一般的應用都不需要修改
+ public void close() {
+ db.close();
+ }
+
+ // 新增參數指定的物件
+ public Item insert(Item item) {
+ // 建立準備新增資料的ContentValues物件
+ ContentValues cv = new ContentValues();
+
+ // 加入ContentValues物件包裝的新增資料
+ // 第一個參數是欄位名稱, 第二個參數是欄位的資料
+ cv.put(DATETIME_COLUMN, item.getDatetime());
+ cv.put(COLOR_COLUMN, item.getColor().parseColor());
+ cv.put(TITLE_COLUMN, item.getTitle());
+ cv.put(CONTENT_COLUMN, item.getContent());
+ cv.put(FILENAME_COLUMN, item.getFileName());
+ cv.put(RECFILENAME_COLUMN, item.getRecFileName());
+ cv.put(LATITUDE_COLUMN, item.getLatitude());
+ cv.put(LONGITUDE_COLUMN, item.getLongitude());
+ cv.put(LASTMODIFY_COLUMN, item.getLastModify());
+
+ // 新增一筆資料並取得編號
+ // 第一個參數是表格名稱
+ // 第二個參數是沒有指定欄位值的預設值
+ // 第三個參數是包裝新增資料的ContentValues物件
+ long id = db.insert(TABLE_NAME, null, cv);
+
+ // 設定編號
+ item.setId(id);
+ // 回傳結果
+ return item;
+ }
+
+ // 修改參數指定的物件
+ public boolean update(Item item) {
+ // 建立準備修改資料的ContentValues物件
+ ContentValues cv = new ContentValues();
+
+ // 加入ContentValues物件包裝的修改資料
+ // 第一個參數是欄位名稱, 第二個參數是欄位的資料
+ cv.put(DATETIME_COLUMN, item.getDatetime());
+ cv.put(COLOR_COLUMN, item.getColor().parseColor());
+ cv.put(TITLE_COLUMN, item.getTitle());
+ cv.put(CONTENT_COLUMN, item.getContent());
+ cv.put(FILENAME_COLUMN, item.getFileName());
+ cv.put(RECFILENAME_COLUMN, item.getRecFileName());
+ cv.put(LATITUDE_COLUMN, item.getLatitude());
+ cv.put(LONGITUDE_COLUMN, item.getLongitude());
+ cv.put(LASTMODIFY_COLUMN, item.getLastModify());
+
+ // 設定修改資料的條件為編號
+ // 格式為「欄位名稱=資料」
+ String where = KEY_ID + "=" + item.getId();
+
+ // 執行修改資料並回傳修改的資料數量是否成功
+ return db.update(TABLE_NAME, cv, where, null) > 0;
+ }
+
+ // 刪除參數指定編號的資料
+ public boolean delete(long id){
+ // 設定條件為編號,格式為「欄位名稱=資料」
+ String where = KEY_ID + "=" + id;
+ // 刪除指定編號資料並回傳刪除是否成功
+ return db.delete(TABLE_NAME, where , null) > 0;
+ }
+
+ // 讀取所有記事資料
+ public List
- getAll() {
+ List
- result = new ArrayList<>();
+ Cursor cursor = db.query(
+ TABLE_NAME, null, null, null, null, null, null, null);
+
+ while (cursor.moveToNext()) {
+ result.add(getRecord(cursor));
+ }
+
+ cursor.close();
+ return result;
+ }
+
+ // 取得指定編號的資料物件
+ public Item get(long id) {
+ // 準備回傳結果用的物件
+ Item item = null;
+ // 使用編號為查詢條件
+ String where = KEY_ID + "=" + id;
+ // 執行查詢
+ Cursor result = db.query(
+ TABLE_NAME, null, where, null, null, null, null, null);
+
+ // 如果有查詢結果
+ if (result.moveToFirst()) {
+ // 讀取包裝一筆資料的物件
+ item = getRecord(result);
+ }
+
+ // 關閉Cursor物件
+ result.close();
+ // 回傳結果
+ return item;
+ }
+
+ // 把Cursor目前的資料包裝為物件
+ public Item getRecord(Cursor cursor) {
+ // 準備回傳結果用的物件
+ Item result = new Item();
+
+ result.setId(cursor.getLong(0));
+ result.setDatetime(cursor.getLong(1));
+ result.setColor(ItemActivity.getColors(cursor.getInt(2)));
+ result.setTitle(cursor.getString(3));
+ result.setContent(cursor.getString(4));
+ result.setFileName(cursor.getString(5));
+ result.setRecFileName(cursor.getString(6));
+ result.setLatitude(cursor.getDouble(7));
+ result.setLongitude(cursor.getDouble(8));
+ result.setLastModify(cursor.getLong(9));
+
+ // 回傳結果
+ return result;
+ }
+
+ // 取得資料數量
+ public int getCount() {
+ int result = 0;
+ Cursor cursor = db.rawQuery("SELECT COUNT(*) FROM " + TABLE_NAME, null);
+
+ if (cursor.moveToNext()) {
+ result = cursor.getInt(0);
+ }
+
+ return result;
+ }
+
+ // 建立範例資料
+ public void sample() {
+ Item item = new Item(0, new Date().getTime(), Colors.RED, "關於Android Tutorial的事情.", "Hello content", "", "", 0, 0, 0);
+ Item item2 = new Item(0, new Date().getTime(), Colors.BLUE, "一隻非常可愛的小狗狗!", "她的名字叫「大熱狗」,又叫\n作「奶嘴」,是一隻非常可愛\n的小狗。", "", "", 25.04719, 121.516981, 0);
+ Item item3 = new Item(0, new Date().getTime(), Colors.GREEN, "一首非常好聽的音樂!", "Hello content", "", "", 0, 0, 0);
+ Item item4 = new Item(0, new Date().getTime(), Colors.ORANGE, "儲存在資料庫的資料", "Hello content", "", "", 0, 0, 0);
+
+ insert(item);
+ insert(item2);
+ insert(item3);
+ insert(item4);
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0402/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MainActivity.java b/examples/0402/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MainActivity.java
new file mode 100644
index 0000000..2a30f6a
--- /dev/null
+++ b/examples/0402/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MainActivity.java
@@ -0,0 +1,302 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.v7.app.ActionBarActivity;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import java.util.List;
+
+public class MainActivity extends ActionBarActivity {
+ private ListView item_list;
+ private TextView show_app_name;
+
+ // ListView使用的自定Adapter物件
+ private ItemAdapter itemAdapter;
+ // 儲存所有記事本的List物件
+ private List
- items;
+
+ // 選單項目物件
+ private MenuItem add_item, search_item, revert_item, share_item, delete_item;
+
+ // 已選擇項目數量
+ private int selectedCount = 0;
+
+ // 宣告資料庫功能類別欄位變數
+ private ItemDAO itemDAO;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ processViews();
+ processControllers();
+
+ // 建立資料庫物件
+ itemDAO = new ItemDAO(getApplicationContext());
+
+ // 如果資料庫是空的,就建立一些範例資料
+ // 這是為了方便測試用的,完成應用程式以後可以拿掉
+ if (itemDAO.getCount() == 0) {
+ itemDAO.sample();
+ }
+
+ // 取得所有記事資料
+ items = itemDAO.getAll();
+
+ itemAdapter = new ItemAdapter(this, R.layout.single_item, items);
+ item_list.setAdapter(itemAdapter);
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (resultCode == Activity.RESULT_OK) {
+ Item item = (Item) data.getExtras().getSerializable(
+ "net.macdidi.myandroidtutorial.Item");
+
+ if (requestCode == 0) {
+ // 新增記事資料到資料庫
+ item = itemDAO.insert(item);
+
+ items.add(item);
+ itemAdapter.notifyDataSetChanged();
+ }
+ else if (requestCode == 1) {
+ int position = data.getIntExtra("position", -1);
+
+ if (position != -1) {
+ // 修改資料庫中的記事資料
+ itemDAO.update(item);
+
+ items.set(position, item);
+ itemAdapter.notifyDataSetChanged();
+ }
+ }
+ }
+ }
+
+ private void processViews() {
+ item_list = (ListView)findViewById(R.id.item_list);
+ show_app_name = (TextView) findViewById(R.id.show_app_name);
+ }
+
+ private void processControllers() {
+
+ // 建立選單項目點擊監聽物件
+ AdapterView.OnItemClickListener itemListener = new AdapterView.OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView> parent, View view,
+ int position, long id) {
+ // 讀取選擇的記事物件
+ Item item = itemAdapter.getItem(position);
+
+ // 如果已經有勾選的項目
+ if (selectedCount > 0) {
+ // 處理是否顯示已選擇項目
+ processMenu(item);
+ // 重新設定記事項目
+ itemAdapter.set(position, item);
+ }
+ else {
+ Intent intent = new Intent(
+ "net.macdidi.myandroidtutorial.EDIT_ITEM");
+
+ // 設定記事編號與記事物件
+ intent.putExtra("position", position);
+ intent.putExtra("net.macdidi.myandroidtutorial.Item", item);
+
+ startActivityForResult(intent, 1);
+ }
+ }
+ };
+
+ // 註冊選單項目點擊監聽物件
+ item_list.setOnItemClickListener(itemListener);
+
+ // 建立記事項目長按監聽物件
+ AdapterView.OnItemLongClickListener itemLongListener = new AdapterView.OnItemLongClickListener() {
+ @Override
+ public boolean onItemLongClick(AdapterView> parent, View view,
+ int position, long id) {
+ // 讀取選擇的記事物件
+ Item item = itemAdapter.getItem(position);
+ // 處理是否顯示已選擇項目
+ processMenu(item);
+ // 重新設定記事項目
+ itemAdapter.set(position, item);
+ return true;
+ }
+ };
+
+ // 註冊記事項目長按監聽物件
+ item_list.setOnItemLongClickListener(itemLongListener);
+
+ // 建立長按監聽物件
+ View.OnLongClickListener listener = new View.OnLongClickListener() {
+
+ @Override
+ public boolean onLongClick(View view) {
+ AlertDialog.Builder dialog =
+ new AlertDialog.Builder(MainActivity.this);
+ dialog.setTitle(R.string.app_name)
+ .setMessage(R.string.about)
+ .show();
+ return false;
+ }
+
+ };
+
+ // 註冊長按監聽物件
+ show_app_name.setOnLongClickListener(listener);
+ }
+
+ // 處理是否顯示已選擇項目
+ private void processMenu(Item item) {
+ // 如果需要設定記事項目
+ if (item != null) {
+ // 設定已勾選的狀態
+ item.setSelected(!item.isSelected());
+
+ // 計算已勾選數量
+ if (item.isSelected()) {
+ selectedCount++;
+ }
+ else {
+ selectedCount--;
+ }
+ }
+
+ // 根據選擇的狀況,設定是否顯示選單項目
+ add_item.setVisible(selectedCount == 0);
+ search_item.setVisible(selectedCount == 0);
+ revert_item.setVisible(selectedCount > 0);
+ share_item.setVisible(selectedCount > 0);
+ delete_item.setVisible(selectedCount > 0);
+ }
+
+ // 載入選單資源
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ MenuInflater menuInflater = getMenuInflater();
+ menuInflater.inflate(R.menu.menu_main, menu);
+
+ // 取得選單項目物件
+ add_item = menu.findItem(R.id.add_item);
+ search_item = menu.findItem(R.id.search_item);
+ revert_item = menu.findItem(R.id.revert_item);
+ share_item = menu.findItem(R.id.share_item);
+ delete_item = menu.findItem(R.id.delete_item);
+
+ // 設定選單項目
+ processMenu(null);
+
+ return true;
+ }
+
+ // 使用者選擇所有的選單項目都會呼叫這個方法
+ public void clickMenuItem(MenuItem item) {
+ // 使用參數取得使用者選擇的選單項目元件編號
+ int itemId = item.getItemId();
+
+ // 判斷該執行什麼工作,目前還沒有加入需要執行的工作
+ switch (itemId) {
+ case R.id.search_item:
+ break;
+ // 使用者選擇新增選單項目
+ case R.id.add_item:
+ // 使用Action名稱建立啟動另一個Activity元件需要的Intent物件
+ Intent intent = new Intent("net.macdidi.myandroidtutorial.ADD_ITEM");
+ // 呼叫「startActivityForResult」,,第二個參數「0」表示執行新增
+ startActivityForResult(intent, 0);
+ break;
+ // 取消所有已勾選的項目
+ case R.id.revert_item:
+ for (int i = 0; i < itemAdapter.getCount(); i++) {
+ Item ri = itemAdapter.getItem(i);
+
+ if (ri.isSelected()) {
+ ri.setSelected(false);
+ itemAdapter.set(i, ri);
+ }
+ }
+
+ selectedCount = 0;
+ processMenu(null);
+
+ break;
+ // 刪除
+ case R.id.delete_item:
+ if (selectedCount == 0) {
+ break;
+ }
+
+ AlertDialog.Builder d = new AlertDialog.Builder(this);
+ String message = getString(R.string.delete_item);
+ d.setTitle(R.string.delete)
+ .setMessage(String.format(message, selectedCount));
+ d.setPositiveButton(android.R.string.yes,
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ // 取得最後一個元素的編號
+ int index = itemAdapter.getCount() - 1;
+
+ while (index > -1) {
+ Item item = itemAdapter.get(index);
+
+ if (item.isSelected()) {
+ itemAdapter.remove(item);
+ // 刪除資料庫中的記事資料
+ itemDAO.delete(item.getId());
+ }
+
+ index--;
+ }
+
+ itemAdapter.notifyDataSetChanged();
+ selectedCount = 0;
+ processMenu(null);
+ }
+ });
+ d.setNegativeButton(android.R.string.no, null);
+ d.show();
+
+ break;
+ case R.id.googleplus_item:
+ break;
+ case R.id.facebook_item:
+ break;
+ }
+
+ }
+
+ // 方法名稱與onClick的設定一樣,參數的型態是android.view.View
+ public void aboutApp(View view) {
+ // 建立啟動另一個Activity元件需要的Intent物件
+ // 建構式的第一個參數:「this」
+ // 建構式的第二個參數:「Activity元件類別名稱.class」
+ Intent intent = new Intent(this, AboutActivity.class);
+ // 呼叫「startActivity」,參數為一個建立好的Intent物件
+ // 這行敘述執行以後,如果沒有任何錯誤,就會啟動指定的元件
+ startActivity(intent);
+ }
+
+ // 設定
+ public void clickPreferences(MenuItem item) {
+ // 啟動設定元件
+ startActivity(new Intent(this, PrefActivity.class));
+ }
+
+}
+
+
diff --git a/examples/0402/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MapsActivity.java b/examples/0402/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MapsActivity.java
new file mode 100644
index 0000000..775305a
--- /dev/null
+++ b/examples/0402/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MapsActivity.java
@@ -0,0 +1,83 @@
+package net.macdidi.myandroidtutorial;
+
+import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
+
+import com.google.android.gms.maps.CameraUpdateFactory;
+import com.google.android.gms.maps.GoogleMap;
+import com.google.android.gms.maps.SupportMapFragment;
+import com.google.android.gms.maps.model.BitmapDescriptor;
+import com.google.android.gms.maps.model.BitmapDescriptorFactory;
+import com.google.android.gms.maps.model.CameraPosition;
+import com.google.android.gms.maps.model.LatLng;
+import com.google.android.gms.maps.model.MarkerOptions;
+
+public class MapsActivity extends FragmentActivity {
+
+ private GoogleMap mMap;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_maps);
+ setUpMapIfNeeded();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ setUpMapIfNeeded();
+ }
+
+ private void setUpMapIfNeeded() {
+ if (mMap == null) {
+ mMap = ((SupportMapFragment) getSupportFragmentManager().
+ findFragmentById(R.id.map)).getMap();
+
+ if (mMap != null) {
+ setUpMap();
+ }
+ }
+ }
+
+ private void setUpMap() {
+ // 刪除原來預設的內容
+ //mMap.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker"));
+
+ // 建立位置的座標物件
+ LatLng place = new LatLng(25.033408, 121.564099);
+ // 移動地圖
+ moveMap(place);
+
+ // 加入地圖標記
+ addMarker(place, "Hello!", " Google Maps v2!");
+ }
+
+ // 移動地圖到參數指定的位置
+ private void moveMap(LatLng place) {
+ // 建立地圖攝影機的位置物件
+ CameraPosition cameraPosition =
+ new CameraPosition.Builder()
+ .target(place)
+ .zoom(17)
+ .build();
+
+ // 使用動畫的效果移動地圖
+ mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
+ }
+
+ // 在地圖加入指定位置與標題的標記
+ private void addMarker(LatLng place, String title, String snippet) {
+ BitmapDescriptor icon =
+ BitmapDescriptorFactory.fromResource(R.drawable.ic_launcher);
+
+ MarkerOptions markerOptions = new MarkerOptions();
+ markerOptions.position(place)
+ .title(title)
+ .snippet(snippet)
+ .icon(icon);
+
+ mMap.addMarker(markerOptions);
+ }
+
+}
diff --git a/examples/0402/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MyDBHelper.java b/examples/0402/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MyDBHelper.java
new file mode 100644
index 0000000..b8b77d6
--- /dev/null
+++ b/examples/0402/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MyDBHelper.java
@@ -0,0 +1,47 @@
+package net.macdidi.myandroidtutorial;
+
+import android.content.Context;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteDatabase.CursorFactory;
+import android.database.sqlite.SQLiteOpenHelper;
+
+public class MyDBHelper extends SQLiteOpenHelper {
+
+ // 資料庫名稱
+ public static final String DATABASE_NAME = "mydata.db";
+ // 資料庫版本,資料結構改變的時候要更改這個數字,通常是加一
+ public static final int VERSION = 2;
+ // 資料庫物件,固定的欄位變數
+ private static SQLiteDatabase database;
+
+ // 建構子,在一般的應用都不需要修改
+ public MyDBHelper(Context context, String name, CursorFactory factory,
+ int version) {
+ super(context, name, factory, version);
+ }
+
+ // 需要資料庫的元件呼叫這個方法,這個方法在一般的應用都不需要修改
+ public static SQLiteDatabase getDatabase(Context context) {
+ if (database == null || !database.isOpen()) {
+ database = new MyDBHelper(context, DATABASE_NAME,
+ null, VERSION).getWritableDatabase();
+ }
+
+ return database;
+ }
+
+ @Override
+ public void onCreate(SQLiteDatabase db) {
+ // 建立應用程式需要的表格
+ db.execSQL(ItemDAO.CREATE_TABLE);
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ // 刪除原有的表格
+ db.execSQL("DROP TABLE IF EXISTS " + ItemDAO.TABLE_NAME);
+ // 呼叫onCreate建立新版的表格
+ onCreate(db);
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0402/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PlayActivity.java b/examples/0402/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PlayActivity.java
new file mode 100644
index 0000000..5cfb523
--- /dev/null
+++ b/examples/0402/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PlayActivity.java
@@ -0,0 +1,64 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.media.MediaPlayer;
+import android.net.Uri;
+import android.os.Bundle;
+import android.view.View;
+
+public class PlayActivity extends Activity {
+
+ private MediaPlayer mediaPlayer;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_play);
+
+ Intent intent = getIntent();
+ String fileName = intent.getStringExtra("fileName");
+
+ // 建立指定資源的MediaPlayer物件
+ Uri uri = Uri.parse(fileName);
+ mediaPlayer = MediaPlayer.create(this, uri);
+ }
+
+ @Override
+ protected void onStop() {
+ if (mediaPlayer.isPlaying()) {
+ // 停止播放
+ mediaPlayer.stop();
+ }
+
+ // 清除MediaPlayer物件
+ mediaPlayer.release();
+ super.onStop();
+ }
+
+ public void onSubmit(View view) {
+ // 結束Activity元件
+ finish();
+ }
+
+ public void clickPlay(View view) {
+ // 開始播放
+ mediaPlayer.start();
+ }
+
+ public void clickPause(View view) {
+ // 暫停播放
+ mediaPlayer.pause();
+ }
+
+ public void clickStop(View view) {
+ // 停止播放
+ if (mediaPlayer.isPlaying()) {
+ mediaPlayer.stop();
+ }
+
+ // 回到開始的位置
+ mediaPlayer.seekTo(0);
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0402/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PrefActivity.java b/examples/0402/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PrefActivity.java
new file mode 100644
index 0000000..b2dcc4a
--- /dev/null
+++ b/examples/0402/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PrefActivity.java
@@ -0,0 +1,38 @@
+package net.macdidi.myandroidtutorial;
+
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceManager;
+
+public class PrefActivity extends PreferenceActivity {
+
+ private SharedPreferences sharedPreferences;
+ private Preference defaultColor;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ // 指定使用的設定畫面配置資源
+ addPreferencesFromResource(R.xml.mypreference);
+ defaultColor = (Preference)findPreference("DEFAULT_COLOR");
+ // 建立SharedPreferences物件
+ sharedPreferences =
+ PreferenceManager.getDefaultSharedPreferences(this);
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ // 讀取設定的預設顏色
+ int color = sharedPreferences.getInt("DEFAULT_COLOR", -1);
+
+ if (color != -1) {
+ // 設定顏色說明
+ defaultColor.setSummary(getString(R.string.default_color_summary) +
+ ": " + ItemActivity.getColors(color));
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0402/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/RecordActivity.java b/examples/0402/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/RecordActivity.java
new file mode 100644
index 0000000..62b5e93
--- /dev/null
+++ b/examples/0402/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/RecordActivity.java
@@ -0,0 +1,180 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.media.MediaRecorder;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.widget.ImageButton;
+import android.widget.ProgressBar;
+
+import java.io.IOException;
+
+public class RecordActivity extends Activity {
+
+ private ImageButton record_button;
+ private boolean isRecording = false;
+ private ProgressBar record_volumn;
+
+ private MyRecoder myRecoder;
+
+ private String fileName;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_record);
+
+ processViews();
+
+ // 讀取檔案名稱
+ Intent intent = getIntent();
+ fileName = intent.getStringExtra("fileName");
+ }
+
+ public void onSubmit(View view) {
+ if (isRecording) {
+ // 停止錄音
+ myRecoder.stop();
+ }
+
+ // 確定
+ if (view.getId() == R.id.record_ok) {
+ Intent result = getIntent();
+ setResult(Activity.RESULT_OK, result);
+ }
+
+ finish();
+ }
+
+ private void processViews() {
+ record_button = (ImageButton) findViewById(R.id.record_button);
+ record_volumn = (ProgressBar) findViewById(R.id.record_volumn);
+ // 隱藏狀態列ProgressBar
+ setProgressBarIndeterminateVisibility(false);
+ }
+
+ public void clickRecord(View view) {
+ // 切換
+ isRecording = !isRecording;
+
+ // 開始錄音
+ if (isRecording) {
+ // 設定按鈕圖示為錄音中
+ record_button.setImageResource(R.drawable.record_red_icon);
+ // 建立錄音物件
+ myRecoder = new MyRecoder(fileName);
+ // 開始錄音
+ myRecoder.start();
+ // 建立並執行顯示麥克風音量的AsyncTask物件
+ new MicLevelTask().execute();
+ }
+ // 停止錄音
+ else {
+ // 設定按鈕圖示為停止錄音
+ record_button.setImageResource(R.drawable.record_dark_icon);
+ // 麥克風音量歸零
+ record_volumn.setProgress(0);
+ // 停止錄音
+ myRecoder.stop();
+ }
+ }
+
+ // 在錄音過程中顯示麥克風音量
+ private class MicLevelTask extends AsyncTask
{
+ @Override
+ protected Void doInBackground(Void... args) {
+ while (isRecording) {
+ publishProgress();
+
+ try {
+ Thread.sleep(200);
+ }
+ catch (InterruptedException e) {
+ Log.d("RecordActivity", e.toString());
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ protected void onProgressUpdate(Void... values) {
+ record_volumn.setProgress((int) myRecoder.getAmplitudeEMA());
+ }
+
+ }
+
+ // 執行錄音並且可以取得麥克風音量的錄音物件
+ private class MyRecoder {
+
+ private static final double EMA_FILTER = 0.6;
+ private MediaRecorder recorder = null;
+ private double mEMA = 0.0;
+ private String output;
+
+ // 建立錄音物件,參數為錄音儲存的位置與檔名
+ MyRecoder(String output) {
+ this.output = output;
+ }
+
+ // 開始錄音
+ public void start() {
+ if (recorder == null) {
+ // 建立錄音用的MediaRecorder物件
+ recorder = new MediaRecorder();
+ // 設定錄音來源為麥克風,必須在setOutputFormat方法之前呼叫
+ recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
+ // 設定輸出格式為3GP壓縮格式,必須在setAudioSource方法之後,
+ // 在prepare方法之前呼叫
+ recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
+ // 設定錄音的編碼方式,必須在setOutputFormat方法之後,
+ // 在prepare方法之前呼叫
+ recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
+ // 設定輸出的檔案名稱,必須在setOutputFormat方法之後,
+ // 在prepare方法之前呼叫
+ recorder.setOutputFile(output);
+
+ try {
+ // 準備執行錄音工作,必須在所有設定之後呼叫
+ recorder.prepare();
+ }
+ catch (IOException e) {
+ Log.d("RecordActivity", e.toString());
+ }
+
+ // 開始錄音
+ recorder.start();
+ mEMA = 0.0;
+ }
+ }
+
+ // 停止錄音
+ public void stop() {
+ if (recorder != null) {
+ // 停止錄音
+ recorder.stop();
+ // 清除錄音資源
+ recorder.release();
+ recorder = null;
+ }
+ }
+
+ public double getAmplitude() {
+ if (recorder != null)
+ return (recorder.getMaxAmplitude() / 2700.0);
+ else
+ return 0;
+ }
+
+ // 取得麥克風音量
+ public double getAmplitudeEMA() {
+ double amp = getAmplitude();
+ mEMA = EMA_FILTER * amp + (1.0 - EMA_FILTER) * mEMA;
+ return mEMA;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0401/MyAndroidTutorial/res/drawable-hdpi/ic_launcher.png b/examples/0402/MyAndroidTutorial/app/src/main/res/drawable-hdpi/ic_launcher.png
old mode 100755
new mode 100644
similarity index 100%
rename from examples/0401/MyAndroidTutorial/res/drawable-hdpi/ic_launcher.png
rename to examples/0402/MyAndroidTutorial/app/src/main/res/drawable-hdpi/ic_launcher.png
diff --git a/examples/0401/MyAndroidTutorial/res/drawable-mdpi/ic_launcher.png b/examples/0402/MyAndroidTutorial/app/src/main/res/drawable-mdpi/ic_launcher.png
old mode 100755
new mode 100644
similarity index 100%
rename from examples/0401/MyAndroidTutorial/res/drawable-mdpi/ic_launcher.png
rename to examples/0402/MyAndroidTutorial/app/src/main/res/drawable-mdpi/ic_launcher.png
diff --git a/examples/0401/MyAndroidTutorial/res/drawable-xhdpi/ic_launcher.png b/examples/0402/MyAndroidTutorial/app/src/main/res/drawable-xhdpi/ic_launcher.png
old mode 100755
new mode 100644
similarity index 100%
rename from examples/0401/MyAndroidTutorial/res/drawable-xhdpi/ic_launcher.png
rename to examples/0402/MyAndroidTutorial/app/src/main/res/drawable-xhdpi/ic_launcher.png
diff --git a/examples/0402/MyAndroidTutorial/app/src/main/res/drawable-xxhdpi/ic_launcher.png b/examples/0402/MyAndroidTutorial/app/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..4df1894
Binary files /dev/null and b/examples/0402/MyAndroidTutorial/app/src/main/res/drawable-xxhdpi/ic_launcher.png differ
diff --git a/examples/0401/MyAndroidTutorial/res/drawable/alarm_icon.png b/examples/0402/MyAndroidTutorial/app/src/main/res/drawable/alarm_icon.png
old mode 100755
new mode 100644
similarity index 100%
rename from examples/0401/MyAndroidTutorial/res/drawable/alarm_icon.png
rename to examples/0402/MyAndroidTutorial/app/src/main/res/drawable/alarm_icon.png
diff --git a/examples/0402/MyAndroidTutorial/app/src/main/res/drawable/item_drawable.xml b/examples/0402/MyAndroidTutorial/app/src/main/res/drawable/item_drawable.xml
new file mode 100644
index 0000000..37607e2
--- /dev/null
+++ b/examples/0402/MyAndroidTutorial/app/src/main/res/drawable/item_drawable.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0401/MyAndroidTutorial/res/drawable/location_icon.png b/examples/0402/MyAndroidTutorial/app/src/main/res/drawable/location_icon.png
old mode 100755
new mode 100644
similarity index 100%
rename from examples/0401/MyAndroidTutorial/res/drawable/location_icon.png
rename to examples/0402/MyAndroidTutorial/app/src/main/res/drawable/location_icon.png
diff --git a/examples/0402/MyAndroidTutorial/app/src/main/res/drawable/pause_icon.png b/examples/0402/MyAndroidTutorial/app/src/main/res/drawable/pause_icon.png
new file mode 100755
index 0000000..a5aee6f
Binary files /dev/null and b/examples/0402/MyAndroidTutorial/app/src/main/res/drawable/pause_icon.png differ
diff --git a/examples/0402/MyAndroidTutorial/app/src/main/res/drawable/play_icon.png b/examples/0402/MyAndroidTutorial/app/src/main/res/drawable/play_icon.png
new file mode 100755
index 0000000..6a40cd5
Binary files /dev/null and b/examples/0402/MyAndroidTutorial/app/src/main/res/drawable/play_icon.png differ
diff --git a/examples/0402/MyAndroidTutorial/app/src/main/res/drawable/record_dark_icon.png b/examples/0402/MyAndroidTutorial/app/src/main/res/drawable/record_dark_icon.png
new file mode 100755
index 0000000..bcf83ca
Binary files /dev/null and b/examples/0402/MyAndroidTutorial/app/src/main/res/drawable/record_dark_icon.png differ
diff --git a/examples/0402/MyAndroidTutorial/app/src/main/res/drawable/record_red_icon.png b/examples/0402/MyAndroidTutorial/app/src/main/res/drawable/record_red_icon.png
new file mode 100755
index 0000000..2b44af0
Binary files /dev/null and b/examples/0402/MyAndroidTutorial/app/src/main/res/drawable/record_red_icon.png differ
diff --git a/examples/0401/MyAndroidTutorial/res/drawable/record_sound_icon.png b/examples/0402/MyAndroidTutorial/app/src/main/res/drawable/record_sound_icon.png
similarity index 100%
rename from examples/0401/MyAndroidTutorial/res/drawable/record_sound_icon.png
rename to examples/0402/MyAndroidTutorial/app/src/main/res/drawable/record_sound_icon.png
diff --git a/examples/0402/MyAndroidTutorial/app/src/main/res/drawable/retangle_drawable.xml b/examples/0402/MyAndroidTutorial/app/src/main/res/drawable/retangle_drawable.xml
new file mode 100644
index 0000000..51d1e84
--- /dev/null
+++ b/examples/0402/MyAndroidTutorial/app/src/main/res/drawable/retangle_drawable.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0401/MyAndroidTutorial/res/drawable/select_color_icon.png b/examples/0402/MyAndroidTutorial/app/src/main/res/drawable/select_color_icon.png
old mode 100755
new mode 100644
similarity index 100%
rename from examples/0401/MyAndroidTutorial/res/drawable/select_color_icon.png
rename to examples/0402/MyAndroidTutorial/app/src/main/res/drawable/select_color_icon.png
diff --git a/examples/0401/MyAndroidTutorial/res/drawable/selected_icon.png b/examples/0402/MyAndroidTutorial/app/src/main/res/drawable/selected_icon.png
similarity index 100%
rename from examples/0401/MyAndroidTutorial/res/drawable/selected_icon.png
rename to examples/0402/MyAndroidTutorial/app/src/main/res/drawable/selected_icon.png
diff --git a/examples/0402/MyAndroidTutorial/app/src/main/res/drawable/stop_icon.png b/examples/0402/MyAndroidTutorial/app/src/main/res/drawable/stop_icon.png
new file mode 100755
index 0000000..20df415
Binary files /dev/null and b/examples/0402/MyAndroidTutorial/app/src/main/res/drawable/stop_icon.png differ
diff --git a/examples/0401/MyAndroidTutorial/res/drawable/take_picture_icon.png b/examples/0402/MyAndroidTutorial/app/src/main/res/drawable/take_picture_icon.png
old mode 100755
new mode 100644
similarity index 100%
rename from examples/0401/MyAndroidTutorial/res/drawable/take_picture_icon.png
rename to examples/0402/MyAndroidTutorial/app/src/main/res/drawable/take_picture_icon.png
diff --git a/examples/0402/MyAndroidTutorial/app/src/main/res/layout/activity_about.xml b/examples/0402/MyAndroidTutorial/app/src/main/res/layout/activity_about.xml
new file mode 100644
index 0000000..8e78611
--- /dev/null
+++ b/examples/0402/MyAndroidTutorial/app/src/main/res/layout/activity_about.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0402/MyAndroidTutorial/app/src/main/res/layout/activity_color.xml b/examples/0402/MyAndroidTutorial/app/src/main/res/layout/activity_color.xml
new file mode 100644
index 0000000..d25bbc5
--- /dev/null
+++ b/examples/0402/MyAndroidTutorial/app/src/main/res/layout/activity_color.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
diff --git a/examples/0402/MyAndroidTutorial/app/src/main/res/layout/activity_item.xml b/examples/0402/MyAndroidTutorial/app/src/main/res/layout/activity_item.xml
new file mode 100644
index 0000000..4ec4362
--- /dev/null
+++ b/examples/0402/MyAndroidTutorial/app/src/main/res/layout/activity_item.xml
@@ -0,0 +1,125 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0402/MyAndroidTutorial/app/src/main/res/layout/activity_main.xml b/examples/0402/MyAndroidTutorial/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..121511b
--- /dev/null
+++ b/examples/0402/MyAndroidTutorial/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
diff --git a/examples/0402/MyAndroidTutorial/app/src/main/res/layout/activity_maps.xml b/examples/0402/MyAndroidTutorial/app/src/main/res/layout/activity_maps.xml
new file mode 100644
index 0000000..5de477b
--- /dev/null
+++ b/examples/0402/MyAndroidTutorial/app/src/main/res/layout/activity_maps.xml
@@ -0,0 +1,7 @@
+
diff --git a/examples/0402/MyAndroidTutorial/app/src/main/res/layout/activity_play.xml b/examples/0402/MyAndroidTutorial/app/src/main/res/layout/activity_play.xml
new file mode 100644
index 0000000..52db308
--- /dev/null
+++ b/examples/0402/MyAndroidTutorial/app/src/main/res/layout/activity_play.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0402/MyAndroidTutorial/app/src/main/res/layout/activity_record.xml b/examples/0402/MyAndroidTutorial/app/src/main/res/layout/activity_record.xml
new file mode 100644
index 0000000..63d9e36
--- /dev/null
+++ b/examples/0402/MyAndroidTutorial/app/src/main/res/layout/activity_record.xml
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0402/MyAndroidTutorial/app/src/main/res/layout/single_item.xml b/examples/0402/MyAndroidTutorial/app/src/main/res/layout/single_item.xml
new file mode 100644
index 0000000..40ddbc9
--- /dev/null
+++ b/examples/0402/MyAndroidTutorial/app/src/main/res/layout/single_item.xml
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0402/MyAndroidTutorial/app/src/main/res/menu/menu_about.xml b/examples/0402/MyAndroidTutorial/app/src/main/res/menu/menu_about.xml
new file mode 100644
index 0000000..d481100
--- /dev/null
+++ b/examples/0402/MyAndroidTutorial/app/src/main/res/menu/menu_about.xml
@@ -0,0 +1,7 @@
+
+
+
diff --git a/examples/0402/MyAndroidTutorial/app/src/main/res/menu/menu_color.xml b/examples/0402/MyAndroidTutorial/app/src/main/res/menu/menu_color.xml
new file mode 100644
index 0000000..8ff243b
--- /dev/null
+++ b/examples/0402/MyAndroidTutorial/app/src/main/res/menu/menu_color.xml
@@ -0,0 +1,7 @@
+
+
+
diff --git a/examples/0402/MyAndroidTutorial/app/src/main/res/menu/menu_item.xml b/examples/0402/MyAndroidTutorial/app/src/main/res/menu/menu_item.xml
new file mode 100644
index 0000000..cd2c9e4
--- /dev/null
+++ b/examples/0402/MyAndroidTutorial/app/src/main/res/menu/menu_item.xml
@@ -0,0 +1,7 @@
+
+
+
diff --git a/examples/0402/MyAndroidTutorial/app/src/main/res/menu/menu_main.xml b/examples/0402/MyAndroidTutorial/app/src/main/res/menu/menu_main.xml
new file mode 100644
index 0000000..0203cfa
--- /dev/null
+++ b/examples/0402/MyAndroidTutorial/app/src/main/res/menu/menu_main.xml
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
diff --git a/examples/0402/MyAndroidTutorial/app/src/main/res/values-en/strings.xml b/examples/0402/MyAndroidTutorial/app/src/main/res/values-en/strings.xml
new file mode 100644
index 0000000..c532533
--- /dev/null
+++ b/examples/0402/MyAndroidTutorial/app/src/main/res/values-en/strings.xml
@@ -0,0 +1,12 @@
+
+
+
+ MyAndroidTutorial
+ Hello world!
+ Settings
+
+ Title
+ Enter title
+ Content
+ Enter content
+
diff --git a/examples/0402/MyAndroidTutorial/app/src/main/res/values-w820dp/dimens.xml b/examples/0402/MyAndroidTutorial/app/src/main/res/values-w820dp/dimens.xml
new file mode 100644
index 0000000..63fc816
--- /dev/null
+++ b/examples/0402/MyAndroidTutorial/app/src/main/res/values-w820dp/dimens.xml
@@ -0,0 +1,6 @@
+
+
+ 64dp
+
diff --git a/examples/0402/MyAndroidTutorial/app/src/main/res/values/colors.xml b/examples/0402/MyAndroidTutorial/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..6b13c1d
--- /dev/null
+++ b/examples/0402/MyAndroidTutorial/app/src/main/res/values/colors.xml
@@ -0,0 +1,7 @@
+
+
+ #CCCCCC
+ #AAAAAA
+ #DD999999
+ #111111
+
\ No newline at end of file
diff --git a/examples/0402/MyAndroidTutorial/app/src/main/res/values/dimens.xml b/examples/0402/MyAndroidTutorial/app/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..02898ec
--- /dev/null
+++ b/examples/0402/MyAndroidTutorial/app/src/main/res/values/dimens.xml
@@ -0,0 +1,9 @@
+
+
+ 16dp
+ 16dp
+
+ 6dp
+ 24sp
+ 2dp
+
diff --git a/examples/0402/MyAndroidTutorial/app/src/main/res/values/strings.xml b/examples/0402/MyAndroidTutorial/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..8939b0d
--- /dev/null
+++ b/examples/0402/MyAndroidTutorial/app/src/main/res/values/strings.xml
@@ -0,0 +1,46 @@
+
+
+
+ MyAndroidTutorial
+ Hello world!
+ Settings
+ 標題
+ 輸入標題
+ 內容
+ 輸入內容
+ 這是Android Tutorial應用程式
+ AboutActivity
+ 版本:AndroidTutorial_0.2.4
+ ItemActivity
+ ColorActivity
+ 刪除
+ 確定要刪除 %1$d 個項目?
+ 預設的顏色
+ 新增記事的預設顏色
+
+ 預設提醒時間
+ 在指定的時間之前通知
+
+
+ - 五分鐘
+ - 十分鐘
+ - 二十分鐘
+ - 三十分鐘
+ - 六十分鐘
+
+
+
+ - 5
+ - 10
+ - 20
+ - 30
+ - 60
+
+
+ 語音備忘
+ 播放語音備忘
+ 播放
+ 重新錄製
+ Map
+
+
diff --git a/examples/0402/MyAndroidTutorial/app/src/main/res/values/styles.xml b/examples/0402/MyAndroidTutorial/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..766ab99
--- /dev/null
+++ b/examples/0402/MyAndroidTutorial/app/src/main/res/values/styles.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
diff --git a/examples/0402/MyAndroidTutorial/app/src/main/res/xml/mypreference.xml b/examples/0402/MyAndroidTutorial/app/src/main/res/xml/mypreference.xml
new file mode 100644
index 0000000..33e714c
--- /dev/null
+++ b/examples/0402/MyAndroidTutorial/app/src/main/res/xml/mypreference.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0402/MyAndroidTutorial/app/src/release/res/values/google_maps_api.xml b/examples/0402/MyAndroidTutorial/app/src/release/res/values/google_maps_api.xml
new file mode 100644
index 0000000..c4e2431
--- /dev/null
+++ b/examples/0402/MyAndroidTutorial/app/src/release/res/values/google_maps_api.xml
@@ -0,0 +1,18 @@
+
+
+
+ YOUR_KEY_HERE
+
+
diff --git a/examples/0402/MyAndroidTutorial/build.gradle b/examples/0402/MyAndroidTutorial/build.gradle
new file mode 100644
index 0000000..6356aab
--- /dev/null
+++ b/examples/0402/MyAndroidTutorial/build.gradle
@@ -0,0 +1,19 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+ repositories {
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:1.0.0'
+
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+}
+
+allprojects {
+ repositories {
+ jcenter()
+ }
+}
diff --git a/examples/0402/MyAndroidTutorial/gradle.properties b/examples/0402/MyAndroidTutorial/gradle.properties
new file mode 100644
index 0000000..1d3591c
--- /dev/null
+++ b/examples/0402/MyAndroidTutorial/gradle.properties
@@ -0,0 +1,18 @@
+# Project-wide Gradle settings.
+
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+# Default value: -Xmx10248m -XX:MaxPermSize=256m
+# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
+
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
\ No newline at end of file
diff --git a/examples/0402/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.jar b/examples/0402/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
Binary files /dev/null and b/examples/0402/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/examples/0402/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.properties b/examples/0402/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..0c71e76
--- /dev/null
+++ b/examples/0402/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
diff --git a/examples/0402/MyAndroidTutorial/gradlew b/examples/0402/MyAndroidTutorial/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/examples/0402/MyAndroidTutorial/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/examples/0402/MyAndroidTutorial/gradlew.bat b/examples/0402/MyAndroidTutorial/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/examples/0402/MyAndroidTutorial/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/examples/0402/MyAndroidTutorial/settings.gradle b/examples/0402/MyAndroidTutorial/settings.gradle
new file mode 100644
index 0000000..e7b4def
--- /dev/null
+++ b/examples/0402/MyAndroidTutorial/settings.gradle
@@ -0,0 +1 @@
+include ':app'
diff --git a/examples/0403/MyAndroidTutorial/.gitignore b/examples/0403/MyAndroidTutorial/.gitignore
new file mode 100644
index 0000000..afbdab3
--- /dev/null
+++ b/examples/0403/MyAndroidTutorial/.gitignore
@@ -0,0 +1,6 @@
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
diff --git a/examples/0403/MyAndroidTutorial/.idea/.name b/examples/0403/MyAndroidTutorial/.idea/.name
new file mode 100644
index 0000000..5bb7a85
--- /dev/null
+++ b/examples/0403/MyAndroidTutorial/.idea/.name
@@ -0,0 +1 @@
+MyAndroidTutorial
\ No newline at end of file
diff --git a/examples/0403/MyAndroidTutorial/.idea/compiler.xml b/examples/0403/MyAndroidTutorial/.idea/compiler.xml
new file mode 100644
index 0000000..217af47
--- /dev/null
+++ b/examples/0403/MyAndroidTutorial/.idea/compiler.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0403/MyAndroidTutorial/.idea/copyright/profiles_settings.xml b/examples/0403/MyAndroidTutorial/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..e7bedf3
--- /dev/null
+++ b/examples/0403/MyAndroidTutorial/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/examples/0403/MyAndroidTutorial/.idea/encodings.xml b/examples/0403/MyAndroidTutorial/.idea/encodings.xml
new file mode 100644
index 0000000..e206d70
--- /dev/null
+++ b/examples/0403/MyAndroidTutorial/.idea/encodings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/examples/0403/MyAndroidTutorial/.idea/gradle.xml b/examples/0403/MyAndroidTutorial/.idea/gradle.xml
new file mode 100644
index 0000000..fe865d3
--- /dev/null
+++ b/examples/0403/MyAndroidTutorial/.idea/gradle.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0403/MyAndroidTutorial/.idea/misc.xml b/examples/0403/MyAndroidTutorial/.idea/misc.xml
new file mode 100644
index 0000000..9076de5
--- /dev/null
+++ b/examples/0403/MyAndroidTutorial/.idea/misc.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0403/MyAndroidTutorial/.idea/modules.xml b/examples/0403/MyAndroidTutorial/.idea/modules.xml
new file mode 100644
index 0000000..327df67
--- /dev/null
+++ b/examples/0403/MyAndroidTutorial/.idea/modules.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0403/MyAndroidTutorial/.idea/scopes/scope_settings.xml b/examples/0403/MyAndroidTutorial/.idea/scopes/scope_settings.xml
new file mode 100644
index 0000000..922003b
--- /dev/null
+++ b/examples/0403/MyAndroidTutorial/.idea/scopes/scope_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0403/MyAndroidTutorial/.idea/vcs.xml b/examples/0403/MyAndroidTutorial/.idea/vcs.xml
new file mode 100644
index 0000000..def6a6a
--- /dev/null
+++ b/examples/0403/MyAndroidTutorial/.idea/vcs.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/examples/0403/MyAndroidTutorial/MyAndroidTutorial.iml b/examples/0403/MyAndroidTutorial/MyAndroidTutorial.iml
new file mode 100644
index 0000000..0bb6048
--- /dev/null
+++ b/examples/0403/MyAndroidTutorial/MyAndroidTutorial.iml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0403/MyAndroidTutorial/app/.gitignore b/examples/0403/MyAndroidTutorial/app/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/examples/0403/MyAndroidTutorial/app/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/examples/0403/MyAndroidTutorial/app/app.iml b/examples/0403/MyAndroidTutorial/app/app.iml
new file mode 100644
index 0000000..b767e16
--- /dev/null
+++ b/examples/0403/MyAndroidTutorial/app/app.iml
@@ -0,0 +1,113 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0403/MyAndroidTutorial/app/build.gradle b/examples/0403/MyAndroidTutorial/app/build.gradle
new file mode 100644
index 0000000..e1475ee
--- /dev/null
+++ b/examples/0403/MyAndroidTutorial/app/build.gradle
@@ -0,0 +1,26 @@
+apply plugin: 'com.android.application'
+
+android {
+ compileSdkVersion 21
+ buildToolsVersion "21.1.2"
+
+ defaultConfig {
+ applicationId "net.macdidi.myandroidtutorial"
+ minSdkVersion 15
+ targetSdkVersion 21
+ versionCode 1
+ versionName "1.0"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ compile fileTree(dir: 'libs', include: ['*.jar'])
+ compile 'com.android.support:appcompat-v7:22.0.0'
+ compile 'com.google.android.gms:play-services:7.0.0'
+}
diff --git a/examples/0403/MyAndroidTutorial/app/proguard-rules.pro b/examples/0403/MyAndroidTutorial/app/proguard-rules.pro
new file mode 100644
index 0000000..b5fa7ec
--- /dev/null
+++ b/examples/0403/MyAndroidTutorial/app/proguard-rules.pro
@@ -0,0 +1,17 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /Users/macdidi5/Library/Android/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
diff --git a/examples/0403/MyAndroidTutorial/app/src/androidTest/java/net/macdidi/myandroidtutorial/ApplicationTest.java b/examples/0403/MyAndroidTutorial/app/src/androidTest/java/net/macdidi/myandroidtutorial/ApplicationTest.java
new file mode 100644
index 0000000..2cb214e
--- /dev/null
+++ b/examples/0403/MyAndroidTutorial/app/src/androidTest/java/net/macdidi/myandroidtutorial/ApplicationTest.java
@@ -0,0 +1,13 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Application;
+import android.test.ApplicationTestCase;
+
+/**
+ * Testing Fundamentals
+ */
+public class ApplicationTest extends ApplicationTestCase {
+ public ApplicationTest() {
+ super(Application.class);
+ }
+}
\ No newline at end of file
diff --git a/examples/0403/MyAndroidTutorial/app/src/debug/res/values/google_maps_api.xml b/examples/0403/MyAndroidTutorial/app/src/debug/res/values/google_maps_api.xml
new file mode 100644
index 0000000..7341c8d
--- /dev/null
+++ b/examples/0403/MyAndroidTutorial/app/src/debug/res/values/google_maps_api.xml
@@ -0,0 +1,18 @@
+
+
+
+ AIzaSyCZg9YWlfokPA96VxWGYr6u4C12jL16VhM
+
+
diff --git a/examples/0403/MyAndroidTutorial/app/src/main/AndroidManifest.xml b/examples/0403/MyAndroidTutorial/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..1a59a4f
--- /dev/null
+++ b/examples/0403/MyAndroidTutorial/app/src/main/AndroidManifest.xml
@@ -0,0 +1,93 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0403/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/AboutActivity.java b/examples/0403/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/AboutActivity.java
new file mode 100644
index 0000000..42dddeb
--- /dev/null
+++ b/examples/0403/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/AboutActivity.java
@@ -0,0 +1,24 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.view.Window;
+
+public class AboutActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ // 取消元件的應用程式標題
+ requestWindowFeature(Window.FEATURE_NO_TITLE);
+ setContentView(R.layout.activity_about);
+ }
+
+ // 結束按鈕
+ public void clickOk(View view) {
+ // 呼叫這個方法結束Activity元件
+ finish();
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0403/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ColorActivity.java b/examples/0403/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ColorActivity.java
new file mode 100644
index 0000000..182cd55
--- /dev/null
+++ b/examples/0403/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ColorActivity.java
@@ -0,0 +1,75 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.LinearLayout;
+
+public class ColorActivity extends Activity {
+
+ private LinearLayout color_gallery;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_color);
+
+ processViews();
+
+ ColorListener listener = new ColorListener();
+
+ for (Colors c : Colors.values()) {
+ Button button = new Button(this);
+ button.setId(c.parseColor());
+ LinearLayout.LayoutParams layout =
+ new LinearLayout.LayoutParams(128, 128);
+ layout.setMargins(6, 6, 6, 6);
+ button.setLayoutParams(layout);
+ button.setBackgroundColor(c.parseColor());
+
+ button.setOnClickListener(listener);
+
+ color_gallery.addView(button);
+ }
+ }
+
+ private void processViews() {
+ color_gallery = (LinearLayout) findViewById(R.id.color_gallery);
+ }
+
+ private class ColorListener implements OnClickListener {
+
+ @Override
+ public void onClick(View view) {
+ String action = ColorActivity.this.getIntent().getAction();
+
+ // 經由設定元件啟動
+ if (action != null &&
+ action.equals("net.macdidi.myandroidtutorial.CHOOSE_COLOR")) {
+ // 建立SharedPreferences物件
+ SharedPreferences.Editor editor =
+ PreferenceManager.getDefaultSharedPreferences(
+ ColorActivity.this).edit();
+ // 儲存預設顏色
+ editor.putInt("DEFAULT_COLOR", view.getId());
+ // 寫入設定值
+ editor.commit();
+ finish();
+ }
+ // 經由新增或修改記事的元件啟動
+ else {
+ Intent result = getIntent();
+ result.putExtra("colorId", view.getId());
+ setResult(Activity.RESULT_OK, result);
+ finish();
+ }
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0403/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Colors.java b/examples/0403/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Colors.java
new file mode 100644
index 0000000..1462149
--- /dev/null
+++ b/examples/0403/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Colors.java
@@ -0,0 +1,24 @@
+package net.macdidi.myandroidtutorial;
+
+import android.graphics.Color;
+
+public enum Colors {
+
+ LIGHTGREY("#D3D3D3"), BLUE("#33B5E5"), PURPLE("#AA66CC"),
+ GREEN("#99CC00"), ORANGE("#FFBB33"), RED("#FF4444");
+
+ private String code;
+
+ private Colors(String code) {
+ this.code = code;
+ }
+
+ public String getCode() {
+ return code;
+ }
+
+ public int parseColor() {
+ return Color.parseColor(code);
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0403/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/FileUtil.java b/examples/0403/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/FileUtil.java
new file mode 100644
index 0000000..1fb41be
--- /dev/null
+++ b/examples/0403/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/FileUtil.java
@@ -0,0 +1,112 @@
+package net.macdidi.myandroidtutorial;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.os.Environment;
+import android.util.Log;
+import android.widget.ImageView;
+
+import java.io.File;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+public class FileUtil {
+
+ // 應用程式儲存檔案的目錄
+ public static final String APP_DIR = "androidtutorial";
+
+ // 外部儲存設備是否可寫入
+ public static boolean isExternalStorageWritable() {
+ // 取得目前外部儲存設備的狀態
+ String state = Environment.getExternalStorageState();
+
+ // 判斷是否可寫入
+ if (Environment.MEDIA_MOUNTED.equals(state)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ // 外部儲存設備是否可讀取
+ public static boolean isExternalStorageReadable() {
+ // 取得目前外部儲存設備的狀態
+ String state = Environment.getExternalStorageState();
+
+ // 判斷是否可讀取
+ if (Environment.MEDIA_MOUNTED.equals(state) ||
+ Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ // 建立並傳回在公用相簿下參數指定的路徑
+ public static File getPublicAlbumStorageDir(String albumName) {
+ // 取得公用的照片路徑
+ File pictures = Environment.getExternalStoragePublicDirectory(
+ Environment.DIRECTORY_PICTURES);
+ // 準備在照片路徑下建立一個指定的路徑
+ File file = new File(pictures, albumName);
+
+ // 如果建立路徑不成功
+ if (!file.mkdirs()) {
+ Log.e("getAlbumStorageDir", "Directory not created");
+ }
+
+ return file;
+ }
+
+ // 建立並傳回在應用程式專用相簿下參數指定的路徑
+ public static File getAlbumStorageDir(Context context, String albumName) {
+ // 取得應用程式專用的照片路徑
+ File pictures = context.getExternalFilesDir(
+ Environment.DIRECTORY_PICTURES);
+ // 準備在照片路徑下建立一個指定的路徑
+ File file = new File(pictures, albumName);
+
+ // 如果建立路徑不成功
+ if (!file.mkdirs()) {
+ Log.e("getAlbumStorageDir", "Directory not created");
+ }
+
+ return file;
+ }
+
+ // 建立並傳回外部儲存媒體參數指定的路徑
+ public static File getExternalStorageDir(String dir) {
+ File result = new File(
+ Environment.getExternalStorageDirectory(), dir);
+
+ if (!isExternalStorageWritable()) {
+ return null;
+ }
+
+ if (!result.exists() && !result.mkdirs()) {
+ return null;
+ }
+
+ return result;
+ }
+
+ // 讀取指定的照片檔案名稱設定給ImageView元件
+ public static void fileToImageView(String fileName, ImageView imageView) {
+ if (new File(fileName).exists()) {
+ Bitmap bitmap = BitmapFactory.decodeFile(fileName);
+ imageView.setImageBitmap(bitmap);
+ }
+ else {
+ Log.e("fileToImageView", fileName + " not found.");
+ }
+ }
+
+ // 產生唯一的檔案名稱
+ public static String getUniqueFileName() {
+ // 使用年月日_時分秒格式為檔案名稱
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
+ return sdf.format(new Date());
+ }
+
+}
diff --git a/examples/0403/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Item.java b/examples/0403/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Item.java
new file mode 100644
index 0000000..9e9c977
--- /dev/null
+++ b/examples/0403/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Item.java
@@ -0,0 +1,145 @@
+package net.macdidi.myandroidtutorial;
+
+import java.util.Date;
+import java.util.Locale;
+
+public class Item implements java.io.Serializable {
+
+ // 編號、日期時間、顏色、標題、內容、檔案名稱、經緯度、修改、已選擇
+ private long id;
+ private long datetime;
+ private Colors color;
+ private String title;
+ private String content;
+ private String fileName;
+ private String recFileName;
+ private double latitude;
+ private double longitude;
+ private long lastModify;
+ private boolean selected;
+
+ public Item() {
+ title = "";
+ content = "";
+ color = Colors.LIGHTGREY;
+ }
+
+ public Item(long id, long datetime, Colors color, String title,
+ String content, String fileName, String recFileName,
+ double latitude, double longitude, long lastModify) {
+ this.id = id;
+ this.datetime = datetime;
+ this.color = color;
+ this.title = title;
+ this.content = content;
+ this.fileName = fileName;
+ this.recFileName = recFileName;
+ this.latitude = latitude;
+ this.longitude = longitude;
+ this.lastModify = lastModify;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public long getDatetime() {
+ return datetime;
+ }
+
+ // 裝置區域的日期時間
+ public String getLocaleDatetime() {
+ return String.format(Locale.getDefault(), "%tF % 0) {
+ // 照片檔案物件
+ File file = configFileName("P", ".jpg");
+
+ // 如果照片檔案存在
+ if (file.exists()) {
+ // 顯示照片元件
+ picture.setVisibility(View.VISIBLE);
+ // 設定照片
+ FileUtil.fileToImageView(file.getAbsolutePath(), picture);
+ }
+ }
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (resultCode == Activity.RESULT_OK) {
+ switch (requestCode) {
+ // 照像
+ case START_CAMERA:
+ // 設定照片檔案名稱
+ item.setFileName(fileName);
+ break;
+ case START_RECORD:
+ // 設定錄音檔案名稱
+ item.setRecFileName(recFileName);
+ break;
+ case START_LOCATION:
+ // 讀取與設定座標
+ double lat = data.getDoubleExtra("lat", 0.0);
+ double lng = data.getDoubleExtra("lng", 0.0);
+ item.setLatitude(lat);
+ item.setLongitude(lng);
+ break;
+ case START_ALARM:
+ break;
+ // 設定顏色
+ case START_COLOR:
+ int colorId = data.getIntExtra(
+ "colorId", Colors.LIGHTGREY.parseColor());
+ item.setColor(getColors(colorId));
+ break;
+ }
+ }
+ }
+
+ public static Colors getColors(int color) {
+ Colors result = Colors.LIGHTGREY;
+
+ if (color == Colors.BLUE.parseColor()) {
+ result = Colors.BLUE;
+ }
+ else if (color == Colors.PURPLE.parseColor()) {
+ result = Colors.PURPLE;
+ }
+ else if (color == Colors.GREEN.parseColor()) {
+ result = Colors.GREEN;
+ }
+ else if (color == Colors.ORANGE.parseColor()) {
+ result = Colors.ORANGE;
+ }
+ else if (color == Colors.RED.parseColor()) {
+ result = Colors.RED;
+ }
+
+ return result;
+ }
+
+ private void processViews() {
+ title_text = (EditText) findViewById(R.id.title_text);
+ content_text = (EditText) findViewById(R.id.content_text);
+ // 取得顯示照片的ImageView元件
+ picture = (ImageView) findViewById(R.id.picture);
+ }
+
+ // 點擊確定與取消按鈕都會呼叫這個方法
+ public void onSubmit(View view) {
+
+ if (view.getId() == R.id.ok_teim) {
+ String titleText = title_text.getText().toString();
+ String contentText = content_text.getText().toString();
+
+ item.setTitle(titleText);
+ item.setContent(contentText);
+
+ if (getIntent().getAction().equals(
+ "net.macdidi.myandroidtutorial.EDIT_ITEM")) {
+ item.setLastModify(new Date().getTime());
+ }
+ // 新增記事
+ else {
+ item.setDatetime(new Date().getTime());
+ // 建立SharedPreferences物件
+ SharedPreferences sharedPreferences =
+ PreferenceManager.getDefaultSharedPreferences(this);
+ // 讀取設定的預設顏色
+ int color = sharedPreferences.getInt("DEFAULT_COLOR", -1);
+ item.setColor(getColors(color));
+ }
+
+ Intent result = getIntent();
+ result.putExtra("net.macdidi.myandroidtutorial.Item", item);
+ setResult(Activity.RESULT_OK, result);
+ }
+
+ // 結束
+ finish();
+ }
+
+ public void clickFunction(View view) {
+ int id = view.getId();
+
+ switch (id) {
+ case R.id.take_picture:
+ // 啟動相機元件用的Intent物件
+ Intent intentCamera =
+ new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
+
+ // 照片檔案名稱
+ File pictureFile = configFileName("P", ".jpg");
+ Uri uri = Uri.fromFile(pictureFile);
+ // 設定檔案名稱
+ intentCamera.putExtra(MediaStore.EXTRA_OUTPUT, uri);
+ // 啟動相機元件
+ startActivityForResult(intentCamera, START_CAMERA);
+ break;
+ case R.id.record_sound:
+ // 錄音檔案名稱
+ final File recordFile = configRecFileName("R", ".mp3");
+
+ // 如果已經有錄音檔,詢問播放或重新錄製
+ if (recordFile.exists()) {
+ // 詢問播放還是重新錄製的對話框
+ AlertDialog.Builder d = new AlertDialog.Builder(this);
+
+ d.setTitle(R.string.title_record)
+ .setCancelable(false);
+ d.setPositiveButton(R.string.record_play,
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ // 播放
+ Intent playIntent = new Intent(
+ ItemActivity.this, PlayActivity.class);
+ playIntent.putExtra("fileName",
+ recordFile.getAbsolutePath());
+ startActivity(playIntent);
+ }
+ });
+ d.setNeutralButton(R.string.record_new,
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ goToRecord(recordFile);
+ }
+ });
+ d.setNegativeButton(android.R.string.cancel, null);
+
+ // 顯示對話框
+ d.show();
+ }
+ // 如果沒有錄音檔,啟動錄音元件
+ else {
+ goToRecord(recordFile);
+ }
+
+ break;
+ case R.id.set_location:
+ // 啟動地圖元件用的Intent物件
+ Intent intentMap = new Intent(this, MapsActivity.class);
+
+ // 設定儲存的座標
+ intentMap.putExtra("lat", item.getLatitude());
+ intentMap.putExtra("lng", item.getLongitude());
+ intentMap.putExtra("title", item.getTitle());
+ intentMap.putExtra("datetime", item.getLocaleDatetime());
+
+ // 啟動地圖元件
+ startActivityForResult(intentMap, START_LOCATION);
+ break;
+ case R.id.set_alarm:
+ break;
+ case R.id.select_color:
+ // 啟動設定顏色的Activity元件
+ startActivityForResult(
+ new Intent(this, ColorActivity.class), START_COLOR);
+ break;
+ }
+
+ }
+
+ private void goToRecord(File recordFile) {
+ // 錄音
+ Intent recordIntent = new Intent(this, RecordActivity.class);
+ recordIntent.putExtra("fileName", recordFile.getAbsolutePath());
+ startActivityForResult(recordIntent, START_RECORD);
+ }
+
+ private File configFileName(String prefix, String extension) {
+ // 如果記事資料已經有檔案名稱
+ if (item.getFileName() != null && item.getFileName().length() > 0) {
+ fileName = item.getFileName();
+ }
+ // 產生檔案名稱
+ else {
+ fileName = FileUtil.getUniqueFileName();
+ }
+
+ return new File(FileUtil.getExternalStorageDir(FileUtil.APP_DIR),
+ prefix + fileName + extension);
+ }
+
+ private File configRecFileName(String prefix, String extension) {
+ // 如果記事資料已經有檔案名稱
+ if (item.getRecFileName() != null && item.getRecFileName().length() > 0) {
+ recFileName = item.getRecFileName();
+ }
+ // 產生檔案名稱
+ else {
+ recFileName = FileUtil.getUniqueFileName();
+ }
+
+ return new File(FileUtil.getExternalStorageDir(FileUtil.APP_DIR),
+ prefix + recFileName + extension);
+ }
+
+}
diff --git a/examples/0403/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemAdapter.java b/examples/0403/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemAdapter.java
new file mode 100644
index 0000000..85b40ba
--- /dev/null
+++ b/examples/0403/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemAdapter.java
@@ -0,0 +1,80 @@
+package net.macdidi.myandroidtutorial;
+
+import android.content.Context;
+import android.graphics.drawable.GradientDrawable;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+import java.util.List;
+
+public class ItemAdapter extends ArrayAdapter- {
+
+ // 畫面資源編號
+ private int resource;
+ // 包裝的記事資料
+ private List
- items;
+
+ public ItemAdapter(Context context, int resource, List
- items) {
+ super(context, resource, items);
+ this.resource = resource;
+ this.items = items;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ LinearLayout itemView;
+ // 讀取目前位置的記事物件
+ final Item item = getItem(position);
+
+ if (convertView == null) {
+ // 建立項目畫面元件
+ itemView = new LinearLayout(getContext());
+ String inflater = Context.LAYOUT_INFLATER_SERVICE;
+ LayoutInflater li = (LayoutInflater)
+ getContext().getSystemService(inflater);
+ li.inflate(resource, itemView, true);
+ }
+ else {
+ itemView = (LinearLayout) convertView;
+ }
+
+ // 讀取記事顏色、已選擇、標題與日期時間元件
+ RelativeLayout typeColor = (RelativeLayout) itemView.findViewById(R.id.type_color);
+ ImageView selectedItem = (ImageView) itemView.findViewById(R.id.selected_item);
+ TextView titleView = (TextView) itemView.findViewById(R.id.title_text);
+ TextView dateView = (TextView) itemView.findViewById(R.id.date_text);
+
+ // 設定記事顏色
+ GradientDrawable background = (GradientDrawable)typeColor.getBackground();
+ background.setColor(item.getColor().parseColor());
+
+ // 設定標題與日期時間
+ titleView.setText(item.getTitle());
+ dateView.setText(item.getLocaleDatetime());
+
+ // 設定是否已選擇
+ selectedItem.setVisibility(item.isSelected() ? View.VISIBLE : View.INVISIBLE);
+
+ return itemView;
+ }
+
+ // 設定指定編號的記事資料
+ public void set(int index, Item item) {
+ if (index >= 0 && index < items.size()) {
+ items.set(index, item);
+ notifyDataSetChanged();
+ }
+ }
+
+ // 讀取指定編號的記事資料
+ public Item get(int index) {
+ return items.get(index);
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0403/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemDAO.java b/examples/0403/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemDAO.java
new file mode 100644
index 0000000..ac5a57a
--- /dev/null
+++ b/examples/0403/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemDAO.java
@@ -0,0 +1,201 @@
+package net.macdidi.myandroidtutorial;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+// 資料功能類別
+public class ItemDAO {
+ // 表格名稱
+ public static final String TABLE_NAME = "item";
+
+ // 編號表格欄位名稱,固定不變
+ public static final String KEY_ID = "_id";
+
+ // 其它表格欄位名稱
+ public static final String DATETIME_COLUMN = "datetime";
+ public static final String COLOR_COLUMN = "color";
+ public static final String TITLE_COLUMN = "title";
+ public static final String CONTENT_COLUMN = "content";
+ public static final String FILENAME_COLUMN = "filename";
+ public static final String RECFILENAME_COLUMN = "recfilename";
+ public static final String LATITUDE_COLUMN = "latitude";
+ public static final String LONGITUDE_COLUMN = "longitude";
+ public static final String LASTMODIFY_COLUMN = "lastmodify";
+
+ // 使用上面宣告的變數建立表格的SQL指令
+ public static final String CREATE_TABLE =
+ "CREATE TABLE " + TABLE_NAME + " (" +
+ KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
+ DATETIME_COLUMN + " INTEGER NOT NULL, " +
+ COLOR_COLUMN + " INTEGER NOT NULL, " +
+ TITLE_COLUMN + " TEXT NOT NULL, " +
+ CONTENT_COLUMN + " TEXT NOT NULL, " +
+ FILENAME_COLUMN + " TEXT, " +
+ RECFILENAME_COLUMN + " TEXT, " +
+ LATITUDE_COLUMN + " REAL, " +
+ LONGITUDE_COLUMN + " REAL, " +
+ LASTMODIFY_COLUMN + " INTEGER)";
+
+ // 資料庫物件
+ private SQLiteDatabase db;
+
+ // 建構子,一般的應用都不需要修改
+ public ItemDAO(Context context) {
+ db = MyDBHelper.getDatabase(context);
+ }
+
+ // 關閉資料庫,一般的應用都不需要修改
+ public void close() {
+ db.close();
+ }
+
+ // 新增參數指定的物件
+ public Item insert(Item item) {
+ // 建立準備新增資料的ContentValues物件
+ ContentValues cv = new ContentValues();
+
+ // 加入ContentValues物件包裝的新增資料
+ // 第一個參數是欄位名稱, 第二個參數是欄位的資料
+ cv.put(DATETIME_COLUMN, item.getDatetime());
+ cv.put(COLOR_COLUMN, item.getColor().parseColor());
+ cv.put(TITLE_COLUMN, item.getTitle());
+ cv.put(CONTENT_COLUMN, item.getContent());
+ cv.put(FILENAME_COLUMN, item.getFileName());
+ cv.put(RECFILENAME_COLUMN, item.getRecFileName());
+ cv.put(LATITUDE_COLUMN, item.getLatitude());
+ cv.put(LONGITUDE_COLUMN, item.getLongitude());
+ cv.put(LASTMODIFY_COLUMN, item.getLastModify());
+
+ // 新增一筆資料並取得編號
+ // 第一個參數是表格名稱
+ // 第二個參數是沒有指定欄位值的預設值
+ // 第三個參數是包裝新增資料的ContentValues物件
+ long id = db.insert(TABLE_NAME, null, cv);
+
+ // 設定編號
+ item.setId(id);
+ // 回傳結果
+ return item;
+ }
+
+ // 修改參數指定的物件
+ public boolean update(Item item) {
+ // 建立準備修改資料的ContentValues物件
+ ContentValues cv = new ContentValues();
+
+ // 加入ContentValues物件包裝的修改資料
+ // 第一個參數是欄位名稱, 第二個參數是欄位的資料
+ cv.put(DATETIME_COLUMN, item.getDatetime());
+ cv.put(COLOR_COLUMN, item.getColor().parseColor());
+ cv.put(TITLE_COLUMN, item.getTitle());
+ cv.put(CONTENT_COLUMN, item.getContent());
+ cv.put(FILENAME_COLUMN, item.getFileName());
+ cv.put(RECFILENAME_COLUMN, item.getRecFileName());
+ cv.put(LATITUDE_COLUMN, item.getLatitude());
+ cv.put(LONGITUDE_COLUMN, item.getLongitude());
+ cv.put(LASTMODIFY_COLUMN, item.getLastModify());
+
+ // 設定修改資料的條件為編號
+ // 格式為「欄位名稱=資料」
+ String where = KEY_ID + "=" + item.getId();
+
+ // 執行修改資料並回傳修改的資料數量是否成功
+ return db.update(TABLE_NAME, cv, where, null) > 0;
+ }
+
+ // 刪除參數指定編號的資料
+ public boolean delete(long id){
+ // 設定條件為編號,格式為「欄位名稱=資料」
+ String where = KEY_ID + "=" + id;
+ // 刪除指定編號資料並回傳刪除是否成功
+ return db.delete(TABLE_NAME, where , null) > 0;
+ }
+
+ // 讀取所有記事資料
+ public List
- getAll() {
+ List
- result = new ArrayList<>();
+ Cursor cursor = db.query(
+ TABLE_NAME, null, null, null, null, null, null, null);
+
+ while (cursor.moveToNext()) {
+ result.add(getRecord(cursor));
+ }
+
+ cursor.close();
+ return result;
+ }
+
+ // 取得指定編號的資料物件
+ public Item get(long id) {
+ // 準備回傳結果用的物件
+ Item item = null;
+ // 使用編號為查詢條件
+ String where = KEY_ID + "=" + id;
+ // 執行查詢
+ Cursor result = db.query(
+ TABLE_NAME, null, where, null, null, null, null, null);
+
+ // 如果有查詢結果
+ if (result.moveToFirst()) {
+ // 讀取包裝一筆資料的物件
+ item = getRecord(result);
+ }
+
+ // 關閉Cursor物件
+ result.close();
+ // 回傳結果
+ return item;
+ }
+
+ // 把Cursor目前的資料包裝為物件
+ public Item getRecord(Cursor cursor) {
+ // 準備回傳結果用的物件
+ Item result = new Item();
+
+ result.setId(cursor.getLong(0));
+ result.setDatetime(cursor.getLong(1));
+ result.setColor(ItemActivity.getColors(cursor.getInt(2)));
+ result.setTitle(cursor.getString(3));
+ result.setContent(cursor.getString(4));
+ result.setFileName(cursor.getString(5));
+ result.setRecFileName(cursor.getString(6));
+ result.setLatitude(cursor.getDouble(7));
+ result.setLongitude(cursor.getDouble(8));
+ result.setLastModify(cursor.getLong(9));
+
+ // 回傳結果
+ return result;
+ }
+
+ // 取得資料數量
+ public int getCount() {
+ int result = 0;
+ Cursor cursor = db.rawQuery("SELECT COUNT(*) FROM " + TABLE_NAME, null);
+
+ if (cursor.moveToNext()) {
+ result = cursor.getInt(0);
+ }
+
+ return result;
+ }
+
+ // 建立範例資料
+ public void sample() {
+ Item item = new Item(0, new Date().getTime(), Colors.RED, "關於Android Tutorial的事情.", "Hello content", "", "", 0, 0, 0);
+ Item item2 = new Item(0, new Date().getTime(), Colors.BLUE, "一隻非常可愛的小狗狗!", "她的名字叫「大熱狗」,又叫\n作「奶嘴」,是一隻非常可愛\n的小狗。", "", "", 25.04719, 121.516981, 0);
+ Item item3 = new Item(0, new Date().getTime(), Colors.GREEN, "一首非常好聽的音樂!", "Hello content", "", "", 0, 0, 0);
+ Item item4 = new Item(0, new Date().getTime(), Colors.ORANGE, "儲存在資料庫的資料", "Hello content", "", "", 0, 0, 0);
+
+ insert(item);
+ insert(item2);
+ insert(item3);
+ insert(item4);
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0403/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MainActivity.java b/examples/0403/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MainActivity.java
new file mode 100644
index 0000000..2a30f6a
--- /dev/null
+++ b/examples/0403/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MainActivity.java
@@ -0,0 +1,302 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.v7.app.ActionBarActivity;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import java.util.List;
+
+public class MainActivity extends ActionBarActivity {
+ private ListView item_list;
+ private TextView show_app_name;
+
+ // ListView使用的自定Adapter物件
+ private ItemAdapter itemAdapter;
+ // 儲存所有記事本的List物件
+ private List
- items;
+
+ // 選單項目物件
+ private MenuItem add_item, search_item, revert_item, share_item, delete_item;
+
+ // 已選擇項目數量
+ private int selectedCount = 0;
+
+ // 宣告資料庫功能類別欄位變數
+ private ItemDAO itemDAO;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ processViews();
+ processControllers();
+
+ // 建立資料庫物件
+ itemDAO = new ItemDAO(getApplicationContext());
+
+ // 如果資料庫是空的,就建立一些範例資料
+ // 這是為了方便測試用的,完成應用程式以後可以拿掉
+ if (itemDAO.getCount() == 0) {
+ itemDAO.sample();
+ }
+
+ // 取得所有記事資料
+ items = itemDAO.getAll();
+
+ itemAdapter = new ItemAdapter(this, R.layout.single_item, items);
+ item_list.setAdapter(itemAdapter);
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (resultCode == Activity.RESULT_OK) {
+ Item item = (Item) data.getExtras().getSerializable(
+ "net.macdidi.myandroidtutorial.Item");
+
+ if (requestCode == 0) {
+ // 新增記事資料到資料庫
+ item = itemDAO.insert(item);
+
+ items.add(item);
+ itemAdapter.notifyDataSetChanged();
+ }
+ else if (requestCode == 1) {
+ int position = data.getIntExtra("position", -1);
+
+ if (position != -1) {
+ // 修改資料庫中的記事資料
+ itemDAO.update(item);
+
+ items.set(position, item);
+ itemAdapter.notifyDataSetChanged();
+ }
+ }
+ }
+ }
+
+ private void processViews() {
+ item_list = (ListView)findViewById(R.id.item_list);
+ show_app_name = (TextView) findViewById(R.id.show_app_name);
+ }
+
+ private void processControllers() {
+
+ // 建立選單項目點擊監聽物件
+ AdapterView.OnItemClickListener itemListener = new AdapterView.OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView> parent, View view,
+ int position, long id) {
+ // 讀取選擇的記事物件
+ Item item = itemAdapter.getItem(position);
+
+ // 如果已經有勾選的項目
+ if (selectedCount > 0) {
+ // 處理是否顯示已選擇項目
+ processMenu(item);
+ // 重新設定記事項目
+ itemAdapter.set(position, item);
+ }
+ else {
+ Intent intent = new Intent(
+ "net.macdidi.myandroidtutorial.EDIT_ITEM");
+
+ // 設定記事編號與記事物件
+ intent.putExtra("position", position);
+ intent.putExtra("net.macdidi.myandroidtutorial.Item", item);
+
+ startActivityForResult(intent, 1);
+ }
+ }
+ };
+
+ // 註冊選單項目點擊監聽物件
+ item_list.setOnItemClickListener(itemListener);
+
+ // 建立記事項目長按監聽物件
+ AdapterView.OnItemLongClickListener itemLongListener = new AdapterView.OnItemLongClickListener() {
+ @Override
+ public boolean onItemLongClick(AdapterView> parent, View view,
+ int position, long id) {
+ // 讀取選擇的記事物件
+ Item item = itemAdapter.getItem(position);
+ // 處理是否顯示已選擇項目
+ processMenu(item);
+ // 重新設定記事項目
+ itemAdapter.set(position, item);
+ return true;
+ }
+ };
+
+ // 註冊記事項目長按監聽物件
+ item_list.setOnItemLongClickListener(itemLongListener);
+
+ // 建立長按監聽物件
+ View.OnLongClickListener listener = new View.OnLongClickListener() {
+
+ @Override
+ public boolean onLongClick(View view) {
+ AlertDialog.Builder dialog =
+ new AlertDialog.Builder(MainActivity.this);
+ dialog.setTitle(R.string.app_name)
+ .setMessage(R.string.about)
+ .show();
+ return false;
+ }
+
+ };
+
+ // 註冊長按監聽物件
+ show_app_name.setOnLongClickListener(listener);
+ }
+
+ // 處理是否顯示已選擇項目
+ private void processMenu(Item item) {
+ // 如果需要設定記事項目
+ if (item != null) {
+ // 設定已勾選的狀態
+ item.setSelected(!item.isSelected());
+
+ // 計算已勾選數量
+ if (item.isSelected()) {
+ selectedCount++;
+ }
+ else {
+ selectedCount--;
+ }
+ }
+
+ // 根據選擇的狀況,設定是否顯示選單項目
+ add_item.setVisible(selectedCount == 0);
+ search_item.setVisible(selectedCount == 0);
+ revert_item.setVisible(selectedCount > 0);
+ share_item.setVisible(selectedCount > 0);
+ delete_item.setVisible(selectedCount > 0);
+ }
+
+ // 載入選單資源
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ MenuInflater menuInflater = getMenuInflater();
+ menuInflater.inflate(R.menu.menu_main, menu);
+
+ // 取得選單項目物件
+ add_item = menu.findItem(R.id.add_item);
+ search_item = menu.findItem(R.id.search_item);
+ revert_item = menu.findItem(R.id.revert_item);
+ share_item = menu.findItem(R.id.share_item);
+ delete_item = menu.findItem(R.id.delete_item);
+
+ // 設定選單項目
+ processMenu(null);
+
+ return true;
+ }
+
+ // 使用者選擇所有的選單項目都會呼叫這個方法
+ public void clickMenuItem(MenuItem item) {
+ // 使用參數取得使用者選擇的選單項目元件編號
+ int itemId = item.getItemId();
+
+ // 判斷該執行什麼工作,目前還沒有加入需要執行的工作
+ switch (itemId) {
+ case R.id.search_item:
+ break;
+ // 使用者選擇新增選單項目
+ case R.id.add_item:
+ // 使用Action名稱建立啟動另一個Activity元件需要的Intent物件
+ Intent intent = new Intent("net.macdidi.myandroidtutorial.ADD_ITEM");
+ // 呼叫「startActivityForResult」,,第二個參數「0」表示執行新增
+ startActivityForResult(intent, 0);
+ break;
+ // 取消所有已勾選的項目
+ case R.id.revert_item:
+ for (int i = 0; i < itemAdapter.getCount(); i++) {
+ Item ri = itemAdapter.getItem(i);
+
+ if (ri.isSelected()) {
+ ri.setSelected(false);
+ itemAdapter.set(i, ri);
+ }
+ }
+
+ selectedCount = 0;
+ processMenu(null);
+
+ break;
+ // 刪除
+ case R.id.delete_item:
+ if (selectedCount == 0) {
+ break;
+ }
+
+ AlertDialog.Builder d = new AlertDialog.Builder(this);
+ String message = getString(R.string.delete_item);
+ d.setTitle(R.string.delete)
+ .setMessage(String.format(message, selectedCount));
+ d.setPositiveButton(android.R.string.yes,
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ // 取得最後一個元素的編號
+ int index = itemAdapter.getCount() - 1;
+
+ while (index > -1) {
+ Item item = itemAdapter.get(index);
+
+ if (item.isSelected()) {
+ itemAdapter.remove(item);
+ // 刪除資料庫中的記事資料
+ itemDAO.delete(item.getId());
+ }
+
+ index--;
+ }
+
+ itemAdapter.notifyDataSetChanged();
+ selectedCount = 0;
+ processMenu(null);
+ }
+ });
+ d.setNegativeButton(android.R.string.no, null);
+ d.show();
+
+ break;
+ case R.id.googleplus_item:
+ break;
+ case R.id.facebook_item:
+ break;
+ }
+
+ }
+
+ // 方法名稱與onClick的設定一樣,參數的型態是android.view.View
+ public void aboutApp(View view) {
+ // 建立啟動另一個Activity元件需要的Intent物件
+ // 建構式的第一個參數:「this」
+ // 建構式的第二個參數:「Activity元件類別名稱.class」
+ Intent intent = new Intent(this, AboutActivity.class);
+ // 呼叫「startActivity」,參數為一個建立好的Intent物件
+ // 這行敘述執行以後,如果沒有任何錯誤,就會啟動指定的元件
+ startActivity(intent);
+ }
+
+ // 設定
+ public void clickPreferences(MenuItem item) {
+ // 啟動設定元件
+ startActivity(new Intent(this, PrefActivity.class));
+ }
+
+}
+
+
diff --git a/examples/0403/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MapsActivity.java b/examples/0403/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MapsActivity.java
new file mode 100644
index 0000000..abab911
--- /dev/null
+++ b/examples/0403/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MapsActivity.java
@@ -0,0 +1,338 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.location.Location;
+import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
+import android.widget.Toast;
+
+import com.google.android.gms.common.ConnectionResult;
+import com.google.android.gms.common.api.GoogleApiClient;
+import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
+import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
+
+import com.google.android.gms.location.LocationListener;
+import com.google.android.gms.location.LocationRequest;
+import com.google.android.gms.location.LocationServices;
+
+import com.google.android.gms.maps.CameraUpdateFactory;
+import com.google.android.gms.maps.GoogleMap;
+import com.google.android.gms.maps.SupportMapFragment;
+import com.google.android.gms.maps.model.BitmapDescriptor;
+import com.google.android.gms.maps.model.BitmapDescriptorFactory;
+import com.google.android.gms.maps.model.CameraPosition;
+import com.google.android.gms.maps.model.LatLng;
+import com.google.android.gms.maps.model.Marker;
+import com.google.android.gms.maps.model.MarkerOptions;
+
+public class MapsActivity extends FragmentActivity
+ implements ConnectionCallbacks,
+ OnConnectionFailedListener,
+ LocationListener {
+
+ private GoogleMap mMap;
+
+ // Google API用戶端物件
+ private GoogleApiClient googleApiClient;
+
+ // Location請求物件
+ private LocationRequest locationRequest;
+
+ // 記錄目前最新的位置
+ private Location currentLocation;
+
+ // 顯示目前與儲存位置的標記物件
+ private Marker currentMarker, itemMarker;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_maps);
+ setUpMapIfNeeded();
+
+ // 建立Google API用戶端物件
+ configGoogleApiClient();
+
+ // 建立Location請求物件
+ configLocationRequest();
+
+ // 讀取記事儲存的座標
+ Intent intent = getIntent();
+ double lat = intent.getDoubleExtra("lat", 0.0);
+ double lng = intent.getDoubleExtra("lng", 0.0);
+
+ // 如果記事已經儲存座標
+ if (lat != 0.0 && lng != 0.0) {
+ // 建立座標物件
+ LatLng itemPlace = new LatLng(lat, lng);
+ // 加入地圖標記
+ addMarker(itemPlace, intent.getStringExtra("title"),
+ intent.getStringExtra("datetime"));
+ // 移動地圖
+ moveMap(itemPlace);
+ }
+ else {
+ // 連線到Google API用戶端
+ if (!googleApiClient.isConnected()) {
+ googleApiClient.connect();
+ }
+ }
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ setUpMapIfNeeded();
+
+ // 連線到Google API用戶端
+ if (!googleApiClient.isConnected() && currentMarker != null) {
+ googleApiClient.connect();
+ }
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+
+ // 移除位置請求服務
+ if (googleApiClient.isConnected()) {
+ LocationServices.FusedLocationApi.removeLocationUpdates(
+ googleApiClient, this);
+ }
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+
+ // 移除Google API用戶端連線
+ if (googleApiClient.isConnected()) {
+ googleApiClient.disconnect();
+ }
+ }
+
+ // 建立Google API用戶端物件
+ private synchronized void configGoogleApiClient() {
+ googleApiClient = new GoogleApiClient.Builder(this)
+ .addConnectionCallbacks(this)
+ .addOnConnectionFailedListener(this)
+ .addApi(LocationServices.API)
+ .build();
+ }
+
+ // 建立Location請求物件
+ private void configLocationRequest() {
+ locationRequest = new LocationRequest();
+ // 設定讀取位置資訊的間隔時間為一秒(1000ms)
+ locationRequest.setInterval(1000);
+ // 設定讀取位置資訊最快的間隔時間為一秒(1000ms)
+ locationRequest.setFastestInterval(1000);
+ // 設定優先讀取高精確度的位置資訊(GPS)
+ locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
+ }
+
+ private void setUpMapIfNeeded() {
+ if (mMap == null) {
+ mMap = ((SupportMapFragment) getSupportFragmentManager().
+ findFragmentById(R.id.map)).getMap();
+
+ if (mMap != null) {
+ // 移除地圖設定
+ //setUpMap();
+ processController();
+ }
+ }
+ }
+
+ // 移除地圖設定方法
+ private void setUpMap() {
+ // 建立位置的座標物件
+ LatLng place = new LatLng(25.033408, 121.564099);
+ // 移動地圖
+ moveMap(place);
+
+ // 加入地圖標記
+ addMarker(place, "Hello!", " Google Maps v2!");
+ }
+
+ private void processController() {
+ // 對話框按鈕事件
+ final DialogInterface.OnClickListener listener =
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ switch (which) {
+ // 更新位置資訊
+ case DialogInterface.BUTTON_POSITIVE:
+ // 連線到Google API用戶端
+ if (!googleApiClient.isConnected()) {
+ googleApiClient.connect();
+ }
+ break;
+ // 清除位置資訊
+ case DialogInterface.BUTTON_NEUTRAL:
+ Intent result = new Intent();
+ result.putExtra("lat", 0);
+ result.putExtra("lng", 0);
+ setResult(Activity.RESULT_OK, result);
+ finish();
+ break;
+ // 取消
+ case DialogInterface.BUTTON_NEGATIVE:
+ break;
+ }
+ }
+ };
+
+ // 標記訊息框點擊事件
+ mMap.setOnInfoWindowClickListener(new GoogleMap.OnInfoWindowClickListener() {
+ @Override
+ public void onInfoWindowClick(Marker marker) {
+ // 如果是記事儲存的標記
+ if (marker.equals(itemMarker)) {
+ AlertDialog.Builder ab = new AlertDialog.Builder(MapsActivity.this);
+
+ ab.setTitle(R.string.title_update_location)
+ .setMessage(R.string.message_update_location)
+ .setCancelable(true);
+
+ ab.setPositiveButton(R.string.update, listener);
+ ab.setNeutralButton(R.string.clear, listener);
+ ab.setNegativeButton(android.R.string.cancel, listener);
+
+ ab.show();
+ }
+ }
+ });
+
+ // 標記點擊事件
+ mMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
+ @Override
+ public boolean onMarkerClick(Marker marker) {
+ // 如果是目前位置標記
+ if (marker.equals(currentMarker)) {
+ AlertDialog.Builder ab = new AlertDialog.Builder(MapsActivity.this);
+
+ ab.setTitle(R.string.title_current_location)
+ .setMessage(R.string.message_current_location)
+ .setCancelable(true);
+
+ ab.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ Intent result = new Intent();
+ result.putExtra("lat", currentLocation.getLatitude());
+ result.putExtra("lng", currentLocation.getLongitude());
+ setResult(Activity.RESULT_OK, result);
+ finish();
+ }
+ });
+ ab.setNegativeButton(android.R.string.cancel, null);
+
+ ab.show();
+
+ return true;
+ }
+
+ return false;
+ }
+ });
+ }
+
+ // 移動地圖到參數指定的位置
+ private void moveMap(LatLng place) {
+ // 建立地圖攝影機的位置物件
+ CameraPosition cameraPosition =
+ new CameraPosition.Builder()
+ .target(place)
+ .zoom(17)
+ .build();
+
+ // 使用動畫的效果移動地圖
+ mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition),
+ new GoogleMap.CancelableCallback() {
+ @Override
+ public void onFinish() {
+ if (itemMarker != null) {
+ itemMarker.showInfoWindow();
+ }
+ }
+
+ @Override
+ public void onCancel() {
+
+ }
+ });
+ }
+
+ // 在地圖加入指定位置與標題的標記
+ private void addMarker(LatLng place, String title, String snippet) {
+ BitmapDescriptor icon =
+ BitmapDescriptorFactory.fromResource(R.drawable.ic_launcher);
+
+ MarkerOptions markerOptions = new MarkerOptions();
+ markerOptions.position(place)
+ .title(title)
+ .snippet(snippet)
+ .icon(icon);
+
+ // 加入並設定記事儲存的位置標記
+ itemMarker = mMap.addMarker(markerOptions);
+ }
+
+ // ConnectionCallbacks
+ @Override
+ public void onConnected(Bundle bundle) {
+ // 已經連線到Google Services
+ // 啟動位置更新服務
+ // 位置資訊更新的時候,應用程式會自動呼叫LocationListener.onLocationChanged
+ LocationServices.FusedLocationApi.requestLocationUpdates(
+ googleApiClient, locationRequest, MapsActivity.this);
+ }
+
+ // ConnectionCallbacks
+ @Override
+ public void onConnectionSuspended(int i) {
+ // Google Services連線中斷
+ // int參數是連線中斷的代號
+ }
+
+ // OnConnectionFailedListener
+ @Override
+ public void onConnectionFailed(ConnectionResult connectionResult) {
+ // Google Services連線失敗
+ // ConnectionResult參數是連線失敗的資訊
+ int errorCode = connectionResult.getErrorCode();
+
+ // 裝置沒有安裝Google Play服務
+ if (errorCode == ConnectionResult.SERVICE_MISSING) {
+ Toast.makeText(this, R.string.google_play_service_missing,
+ Toast.LENGTH_LONG).show();
+ }
+ }
+
+ // LocationListener
+ @Override
+ public void onLocationChanged(Location location) {
+ // 位置改變
+ // Location參數是目前的位置
+ currentLocation = location;
+ LatLng latLng = new LatLng(
+ location.getLatitude(), location.getLongitude());
+
+ // 設定目前位置的標記
+ if (currentMarker == null) {
+ currentMarker = mMap.addMarker(new MarkerOptions().position(latLng));
+ }
+ else {
+ currentMarker.setPosition(latLng);
+ }
+
+ // 移動地圖到目前的位置
+ moveMap(latLng);
+ }
+
+}
diff --git a/examples/0403/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MyDBHelper.java b/examples/0403/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MyDBHelper.java
new file mode 100644
index 0000000..b8b77d6
--- /dev/null
+++ b/examples/0403/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MyDBHelper.java
@@ -0,0 +1,47 @@
+package net.macdidi.myandroidtutorial;
+
+import android.content.Context;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteDatabase.CursorFactory;
+import android.database.sqlite.SQLiteOpenHelper;
+
+public class MyDBHelper extends SQLiteOpenHelper {
+
+ // 資料庫名稱
+ public static final String DATABASE_NAME = "mydata.db";
+ // 資料庫版本,資料結構改變的時候要更改這個數字,通常是加一
+ public static final int VERSION = 2;
+ // 資料庫物件,固定的欄位變數
+ private static SQLiteDatabase database;
+
+ // 建構子,在一般的應用都不需要修改
+ public MyDBHelper(Context context, String name, CursorFactory factory,
+ int version) {
+ super(context, name, factory, version);
+ }
+
+ // 需要資料庫的元件呼叫這個方法,這個方法在一般的應用都不需要修改
+ public static SQLiteDatabase getDatabase(Context context) {
+ if (database == null || !database.isOpen()) {
+ database = new MyDBHelper(context, DATABASE_NAME,
+ null, VERSION).getWritableDatabase();
+ }
+
+ return database;
+ }
+
+ @Override
+ public void onCreate(SQLiteDatabase db) {
+ // 建立應用程式需要的表格
+ db.execSQL(ItemDAO.CREATE_TABLE);
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ // 刪除原有的表格
+ db.execSQL("DROP TABLE IF EXISTS " + ItemDAO.TABLE_NAME);
+ // 呼叫onCreate建立新版的表格
+ onCreate(db);
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0403/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PlayActivity.java b/examples/0403/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PlayActivity.java
new file mode 100644
index 0000000..5cfb523
--- /dev/null
+++ b/examples/0403/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PlayActivity.java
@@ -0,0 +1,64 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.media.MediaPlayer;
+import android.net.Uri;
+import android.os.Bundle;
+import android.view.View;
+
+public class PlayActivity extends Activity {
+
+ private MediaPlayer mediaPlayer;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_play);
+
+ Intent intent = getIntent();
+ String fileName = intent.getStringExtra("fileName");
+
+ // 建立指定資源的MediaPlayer物件
+ Uri uri = Uri.parse(fileName);
+ mediaPlayer = MediaPlayer.create(this, uri);
+ }
+
+ @Override
+ protected void onStop() {
+ if (mediaPlayer.isPlaying()) {
+ // 停止播放
+ mediaPlayer.stop();
+ }
+
+ // 清除MediaPlayer物件
+ mediaPlayer.release();
+ super.onStop();
+ }
+
+ public void onSubmit(View view) {
+ // 結束Activity元件
+ finish();
+ }
+
+ public void clickPlay(View view) {
+ // 開始播放
+ mediaPlayer.start();
+ }
+
+ public void clickPause(View view) {
+ // 暫停播放
+ mediaPlayer.pause();
+ }
+
+ public void clickStop(View view) {
+ // 停止播放
+ if (mediaPlayer.isPlaying()) {
+ mediaPlayer.stop();
+ }
+
+ // 回到開始的位置
+ mediaPlayer.seekTo(0);
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0403/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PrefActivity.java b/examples/0403/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PrefActivity.java
new file mode 100644
index 0000000..b2dcc4a
--- /dev/null
+++ b/examples/0403/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PrefActivity.java
@@ -0,0 +1,38 @@
+package net.macdidi.myandroidtutorial;
+
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceManager;
+
+public class PrefActivity extends PreferenceActivity {
+
+ private SharedPreferences sharedPreferences;
+ private Preference defaultColor;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ // 指定使用的設定畫面配置資源
+ addPreferencesFromResource(R.xml.mypreference);
+ defaultColor = (Preference)findPreference("DEFAULT_COLOR");
+ // 建立SharedPreferences物件
+ sharedPreferences =
+ PreferenceManager.getDefaultSharedPreferences(this);
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ // 讀取設定的預設顏色
+ int color = sharedPreferences.getInt("DEFAULT_COLOR", -1);
+
+ if (color != -1) {
+ // 設定顏色說明
+ defaultColor.setSummary(getString(R.string.default_color_summary) +
+ ": " + ItemActivity.getColors(color));
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0403/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/RecordActivity.java b/examples/0403/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/RecordActivity.java
new file mode 100644
index 0000000..62b5e93
--- /dev/null
+++ b/examples/0403/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/RecordActivity.java
@@ -0,0 +1,180 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.media.MediaRecorder;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.widget.ImageButton;
+import android.widget.ProgressBar;
+
+import java.io.IOException;
+
+public class RecordActivity extends Activity {
+
+ private ImageButton record_button;
+ private boolean isRecording = false;
+ private ProgressBar record_volumn;
+
+ private MyRecoder myRecoder;
+
+ private String fileName;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_record);
+
+ processViews();
+
+ // 讀取檔案名稱
+ Intent intent = getIntent();
+ fileName = intent.getStringExtra("fileName");
+ }
+
+ public void onSubmit(View view) {
+ if (isRecording) {
+ // 停止錄音
+ myRecoder.stop();
+ }
+
+ // 確定
+ if (view.getId() == R.id.record_ok) {
+ Intent result = getIntent();
+ setResult(Activity.RESULT_OK, result);
+ }
+
+ finish();
+ }
+
+ private void processViews() {
+ record_button = (ImageButton) findViewById(R.id.record_button);
+ record_volumn = (ProgressBar) findViewById(R.id.record_volumn);
+ // 隱藏狀態列ProgressBar
+ setProgressBarIndeterminateVisibility(false);
+ }
+
+ public void clickRecord(View view) {
+ // 切換
+ isRecording = !isRecording;
+
+ // 開始錄音
+ if (isRecording) {
+ // 設定按鈕圖示為錄音中
+ record_button.setImageResource(R.drawable.record_red_icon);
+ // 建立錄音物件
+ myRecoder = new MyRecoder(fileName);
+ // 開始錄音
+ myRecoder.start();
+ // 建立並執行顯示麥克風音量的AsyncTask物件
+ new MicLevelTask().execute();
+ }
+ // 停止錄音
+ else {
+ // 設定按鈕圖示為停止錄音
+ record_button.setImageResource(R.drawable.record_dark_icon);
+ // 麥克風音量歸零
+ record_volumn.setProgress(0);
+ // 停止錄音
+ myRecoder.stop();
+ }
+ }
+
+ // 在錄音過程中顯示麥克風音量
+ private class MicLevelTask extends AsyncTask
{
+ @Override
+ protected Void doInBackground(Void... args) {
+ while (isRecording) {
+ publishProgress();
+
+ try {
+ Thread.sleep(200);
+ }
+ catch (InterruptedException e) {
+ Log.d("RecordActivity", e.toString());
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ protected void onProgressUpdate(Void... values) {
+ record_volumn.setProgress((int) myRecoder.getAmplitudeEMA());
+ }
+
+ }
+
+ // 執行錄音並且可以取得麥克風音量的錄音物件
+ private class MyRecoder {
+
+ private static final double EMA_FILTER = 0.6;
+ private MediaRecorder recorder = null;
+ private double mEMA = 0.0;
+ private String output;
+
+ // 建立錄音物件,參數為錄音儲存的位置與檔名
+ MyRecoder(String output) {
+ this.output = output;
+ }
+
+ // 開始錄音
+ public void start() {
+ if (recorder == null) {
+ // 建立錄音用的MediaRecorder物件
+ recorder = new MediaRecorder();
+ // 設定錄音來源為麥克風,必須在setOutputFormat方法之前呼叫
+ recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
+ // 設定輸出格式為3GP壓縮格式,必須在setAudioSource方法之後,
+ // 在prepare方法之前呼叫
+ recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
+ // 設定錄音的編碼方式,必須在setOutputFormat方法之後,
+ // 在prepare方法之前呼叫
+ recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
+ // 設定輸出的檔案名稱,必須在setOutputFormat方法之後,
+ // 在prepare方法之前呼叫
+ recorder.setOutputFile(output);
+
+ try {
+ // 準備執行錄音工作,必須在所有設定之後呼叫
+ recorder.prepare();
+ }
+ catch (IOException e) {
+ Log.d("RecordActivity", e.toString());
+ }
+
+ // 開始錄音
+ recorder.start();
+ mEMA = 0.0;
+ }
+ }
+
+ // 停止錄音
+ public void stop() {
+ if (recorder != null) {
+ // 停止錄音
+ recorder.stop();
+ // 清除錄音資源
+ recorder.release();
+ recorder = null;
+ }
+ }
+
+ public double getAmplitude() {
+ if (recorder != null)
+ return (recorder.getMaxAmplitude() / 2700.0);
+ else
+ return 0;
+ }
+
+ // 取得麥克風音量
+ public double getAmplitudeEMA() {
+ double amp = getAmplitude();
+ mEMA = EMA_FILTER * amp + (1.0 - EMA_FILTER) * mEMA;
+ return mEMA;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0403/MyAndroidTutorial/app/src/main/res/drawable-hdpi/ic_launcher.png b/examples/0403/MyAndroidTutorial/app/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..96a442e
Binary files /dev/null and b/examples/0403/MyAndroidTutorial/app/src/main/res/drawable-hdpi/ic_launcher.png differ
diff --git a/examples/0403/MyAndroidTutorial/app/src/main/res/drawable-mdpi/ic_launcher.png b/examples/0403/MyAndroidTutorial/app/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..359047d
Binary files /dev/null and b/examples/0403/MyAndroidTutorial/app/src/main/res/drawable-mdpi/ic_launcher.png differ
diff --git a/examples/0403/MyAndroidTutorial/app/src/main/res/drawable-xhdpi/ic_launcher.png b/examples/0403/MyAndroidTutorial/app/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..71c6d76
Binary files /dev/null and b/examples/0403/MyAndroidTutorial/app/src/main/res/drawable-xhdpi/ic_launcher.png differ
diff --git a/examples/0403/MyAndroidTutorial/app/src/main/res/drawable-xxhdpi/ic_launcher.png b/examples/0403/MyAndroidTutorial/app/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..4df1894
Binary files /dev/null and b/examples/0403/MyAndroidTutorial/app/src/main/res/drawable-xxhdpi/ic_launcher.png differ
diff --git a/examples/0403/MyAndroidTutorial/app/src/main/res/drawable/alarm_icon.png b/examples/0403/MyAndroidTutorial/app/src/main/res/drawable/alarm_icon.png
new file mode 100644
index 0000000..c6cac88
Binary files /dev/null and b/examples/0403/MyAndroidTutorial/app/src/main/res/drawable/alarm_icon.png differ
diff --git a/examples/0403/MyAndroidTutorial/app/src/main/res/drawable/item_drawable.xml b/examples/0403/MyAndroidTutorial/app/src/main/res/drawable/item_drawable.xml
new file mode 100644
index 0000000..37607e2
--- /dev/null
+++ b/examples/0403/MyAndroidTutorial/app/src/main/res/drawable/item_drawable.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0403/MyAndroidTutorial/app/src/main/res/drawable/location_icon.png b/examples/0403/MyAndroidTutorial/app/src/main/res/drawable/location_icon.png
new file mode 100644
index 0000000..4c3c514
Binary files /dev/null and b/examples/0403/MyAndroidTutorial/app/src/main/res/drawable/location_icon.png differ
diff --git a/examples/0403/MyAndroidTutorial/app/src/main/res/drawable/pause_icon.png b/examples/0403/MyAndroidTutorial/app/src/main/res/drawable/pause_icon.png
new file mode 100755
index 0000000..a5aee6f
Binary files /dev/null and b/examples/0403/MyAndroidTutorial/app/src/main/res/drawable/pause_icon.png differ
diff --git a/examples/0403/MyAndroidTutorial/app/src/main/res/drawable/play_icon.png b/examples/0403/MyAndroidTutorial/app/src/main/res/drawable/play_icon.png
new file mode 100755
index 0000000..6a40cd5
Binary files /dev/null and b/examples/0403/MyAndroidTutorial/app/src/main/res/drawable/play_icon.png differ
diff --git a/examples/0403/MyAndroidTutorial/app/src/main/res/drawable/record_dark_icon.png b/examples/0403/MyAndroidTutorial/app/src/main/res/drawable/record_dark_icon.png
new file mode 100755
index 0000000..bcf83ca
Binary files /dev/null and b/examples/0403/MyAndroidTutorial/app/src/main/res/drawable/record_dark_icon.png differ
diff --git a/examples/0403/MyAndroidTutorial/app/src/main/res/drawable/record_red_icon.png b/examples/0403/MyAndroidTutorial/app/src/main/res/drawable/record_red_icon.png
new file mode 100755
index 0000000..2b44af0
Binary files /dev/null and b/examples/0403/MyAndroidTutorial/app/src/main/res/drawable/record_red_icon.png differ
diff --git a/examples/0403/MyAndroidTutorial/app/src/main/res/drawable/record_sound_icon.png b/examples/0403/MyAndroidTutorial/app/src/main/res/drawable/record_sound_icon.png
new file mode 100755
index 0000000..a1382ac
Binary files /dev/null and b/examples/0403/MyAndroidTutorial/app/src/main/res/drawable/record_sound_icon.png differ
diff --git a/examples/0403/MyAndroidTutorial/app/src/main/res/drawable/retangle_drawable.xml b/examples/0403/MyAndroidTutorial/app/src/main/res/drawable/retangle_drawable.xml
new file mode 100644
index 0000000..51d1e84
--- /dev/null
+++ b/examples/0403/MyAndroidTutorial/app/src/main/res/drawable/retangle_drawable.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0403/MyAndroidTutorial/app/src/main/res/drawable/select_color_icon.png b/examples/0403/MyAndroidTutorial/app/src/main/res/drawable/select_color_icon.png
new file mode 100644
index 0000000..8567d5e
Binary files /dev/null and b/examples/0403/MyAndroidTutorial/app/src/main/res/drawable/select_color_icon.png differ
diff --git a/examples/0403/MyAndroidTutorial/app/src/main/res/drawable/selected_icon.png b/examples/0403/MyAndroidTutorial/app/src/main/res/drawable/selected_icon.png
new file mode 100755
index 0000000..b891571
Binary files /dev/null and b/examples/0403/MyAndroidTutorial/app/src/main/res/drawable/selected_icon.png differ
diff --git a/examples/0403/MyAndroidTutorial/app/src/main/res/drawable/stop_icon.png b/examples/0403/MyAndroidTutorial/app/src/main/res/drawable/stop_icon.png
new file mode 100755
index 0000000..20df415
Binary files /dev/null and b/examples/0403/MyAndroidTutorial/app/src/main/res/drawable/stop_icon.png differ
diff --git a/examples/0403/MyAndroidTutorial/app/src/main/res/drawable/take_picture_icon.png b/examples/0403/MyAndroidTutorial/app/src/main/res/drawable/take_picture_icon.png
new file mode 100644
index 0000000..08fb514
Binary files /dev/null and b/examples/0403/MyAndroidTutorial/app/src/main/res/drawable/take_picture_icon.png differ
diff --git a/examples/0403/MyAndroidTutorial/app/src/main/res/layout/activity_about.xml b/examples/0403/MyAndroidTutorial/app/src/main/res/layout/activity_about.xml
new file mode 100644
index 0000000..8e78611
--- /dev/null
+++ b/examples/0403/MyAndroidTutorial/app/src/main/res/layout/activity_about.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0403/MyAndroidTutorial/app/src/main/res/layout/activity_color.xml b/examples/0403/MyAndroidTutorial/app/src/main/res/layout/activity_color.xml
new file mode 100644
index 0000000..d25bbc5
--- /dev/null
+++ b/examples/0403/MyAndroidTutorial/app/src/main/res/layout/activity_color.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
diff --git a/examples/0403/MyAndroidTutorial/app/src/main/res/layout/activity_item.xml b/examples/0403/MyAndroidTutorial/app/src/main/res/layout/activity_item.xml
new file mode 100644
index 0000000..4ec4362
--- /dev/null
+++ b/examples/0403/MyAndroidTutorial/app/src/main/res/layout/activity_item.xml
@@ -0,0 +1,125 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0403/MyAndroidTutorial/app/src/main/res/layout/activity_main.xml b/examples/0403/MyAndroidTutorial/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..121511b
--- /dev/null
+++ b/examples/0403/MyAndroidTutorial/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
diff --git a/examples/0403/MyAndroidTutorial/app/src/main/res/layout/activity_maps.xml b/examples/0403/MyAndroidTutorial/app/src/main/res/layout/activity_maps.xml
new file mode 100644
index 0000000..5de477b
--- /dev/null
+++ b/examples/0403/MyAndroidTutorial/app/src/main/res/layout/activity_maps.xml
@@ -0,0 +1,7 @@
+
diff --git a/examples/0403/MyAndroidTutorial/app/src/main/res/layout/activity_play.xml b/examples/0403/MyAndroidTutorial/app/src/main/res/layout/activity_play.xml
new file mode 100644
index 0000000..52db308
--- /dev/null
+++ b/examples/0403/MyAndroidTutorial/app/src/main/res/layout/activity_play.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0403/MyAndroidTutorial/app/src/main/res/layout/activity_record.xml b/examples/0403/MyAndroidTutorial/app/src/main/res/layout/activity_record.xml
new file mode 100644
index 0000000..63d9e36
--- /dev/null
+++ b/examples/0403/MyAndroidTutorial/app/src/main/res/layout/activity_record.xml
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0403/MyAndroidTutorial/app/src/main/res/layout/single_item.xml b/examples/0403/MyAndroidTutorial/app/src/main/res/layout/single_item.xml
new file mode 100644
index 0000000..40ddbc9
--- /dev/null
+++ b/examples/0403/MyAndroidTutorial/app/src/main/res/layout/single_item.xml
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0403/MyAndroidTutorial/app/src/main/res/menu/menu_about.xml b/examples/0403/MyAndroidTutorial/app/src/main/res/menu/menu_about.xml
new file mode 100644
index 0000000..d481100
--- /dev/null
+++ b/examples/0403/MyAndroidTutorial/app/src/main/res/menu/menu_about.xml
@@ -0,0 +1,7 @@
+
+
+
diff --git a/examples/0403/MyAndroidTutorial/app/src/main/res/menu/menu_color.xml b/examples/0403/MyAndroidTutorial/app/src/main/res/menu/menu_color.xml
new file mode 100644
index 0000000..8ff243b
--- /dev/null
+++ b/examples/0403/MyAndroidTutorial/app/src/main/res/menu/menu_color.xml
@@ -0,0 +1,7 @@
+
+
+
diff --git a/examples/0403/MyAndroidTutorial/app/src/main/res/menu/menu_item.xml b/examples/0403/MyAndroidTutorial/app/src/main/res/menu/menu_item.xml
new file mode 100644
index 0000000..cd2c9e4
--- /dev/null
+++ b/examples/0403/MyAndroidTutorial/app/src/main/res/menu/menu_item.xml
@@ -0,0 +1,7 @@
+
+
+
diff --git a/examples/0403/MyAndroidTutorial/app/src/main/res/menu/menu_main.xml b/examples/0403/MyAndroidTutorial/app/src/main/res/menu/menu_main.xml
new file mode 100644
index 0000000..0203cfa
--- /dev/null
+++ b/examples/0403/MyAndroidTutorial/app/src/main/res/menu/menu_main.xml
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
diff --git a/examples/0403/MyAndroidTutorial/app/src/main/res/values-en/strings.xml b/examples/0403/MyAndroidTutorial/app/src/main/res/values-en/strings.xml
new file mode 100644
index 0000000..c532533
--- /dev/null
+++ b/examples/0403/MyAndroidTutorial/app/src/main/res/values-en/strings.xml
@@ -0,0 +1,12 @@
+
+
+
+ MyAndroidTutorial
+ Hello world!
+ Settings
+
+ Title
+ Enter title
+ Content
+ Enter content
+
diff --git a/examples/0403/MyAndroidTutorial/app/src/main/res/values-w820dp/dimens.xml b/examples/0403/MyAndroidTutorial/app/src/main/res/values-w820dp/dimens.xml
new file mode 100644
index 0000000..63fc816
--- /dev/null
+++ b/examples/0403/MyAndroidTutorial/app/src/main/res/values-w820dp/dimens.xml
@@ -0,0 +1,6 @@
+
+
+ 64dp
+
diff --git a/examples/0403/MyAndroidTutorial/app/src/main/res/values/colors.xml b/examples/0403/MyAndroidTutorial/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..6b13c1d
--- /dev/null
+++ b/examples/0403/MyAndroidTutorial/app/src/main/res/values/colors.xml
@@ -0,0 +1,7 @@
+
+
+ #CCCCCC
+ #AAAAAA
+ #DD999999
+ #111111
+
\ No newline at end of file
diff --git a/examples/0403/MyAndroidTutorial/app/src/main/res/values/dimens.xml b/examples/0403/MyAndroidTutorial/app/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..02898ec
--- /dev/null
+++ b/examples/0403/MyAndroidTutorial/app/src/main/res/values/dimens.xml
@@ -0,0 +1,9 @@
+
+
+ 16dp
+ 16dp
+
+ 6dp
+ 24sp
+ 2dp
+
diff --git a/examples/0403/MyAndroidTutorial/app/src/main/res/values/strings.xml b/examples/0403/MyAndroidTutorial/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..89dcf0f
--- /dev/null
+++ b/examples/0403/MyAndroidTutorial/app/src/main/res/values/strings.xml
@@ -0,0 +1,56 @@
+
+
+
+ MyAndroidTutorial
+ Hello world!
+ Settings
+ 標題
+ 輸入標題
+ 內容
+ 輸入內容
+ 這是Android Tutorial應用程式
+ AboutActivity
+ 版本:AndroidTutorial_0.2.4
+ ItemActivity
+ ColorActivity
+ 刪除
+ 確定要刪除 %1$d 個項目?
+ 預設的顏色
+ 新增記事的預設顏色
+
+ 預設提醒時間
+ 在指定的時間之前通知
+
+
+ - 五分鐘
+ - 十分鐘
+ - 二十分鐘
+ - 三十分鐘
+ - 六十分鐘
+
+
+
+ - 5
+ - 10
+ - 20
+ - 30
+ - 60
+
+
+ 語音備忘
+ 播放語音備忘
+ 播放
+ 重新錄製
+ Map
+
+ 記事儲存的位置
+ 更新或清除儲存的位置資訊?
+ 更新
+ 清除
+
+ 目前位置
+ 是否儲存目前位置?
+
+ 裝置沒有安裝Google Play服務
+
+
diff --git a/examples/0403/MyAndroidTutorial/app/src/main/res/values/styles.xml b/examples/0403/MyAndroidTutorial/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..766ab99
--- /dev/null
+++ b/examples/0403/MyAndroidTutorial/app/src/main/res/values/styles.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
diff --git a/examples/0403/MyAndroidTutorial/app/src/main/res/xml/mypreference.xml b/examples/0403/MyAndroidTutorial/app/src/main/res/xml/mypreference.xml
new file mode 100644
index 0000000..33e714c
--- /dev/null
+++ b/examples/0403/MyAndroidTutorial/app/src/main/res/xml/mypreference.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0403/MyAndroidTutorial/app/src/release/res/values/google_maps_api.xml b/examples/0403/MyAndroidTutorial/app/src/release/res/values/google_maps_api.xml
new file mode 100644
index 0000000..c4e2431
--- /dev/null
+++ b/examples/0403/MyAndroidTutorial/app/src/release/res/values/google_maps_api.xml
@@ -0,0 +1,18 @@
+
+
+
+ YOUR_KEY_HERE
+
+
diff --git a/examples/0403/MyAndroidTutorial/build.gradle b/examples/0403/MyAndroidTutorial/build.gradle
new file mode 100644
index 0000000..6356aab
--- /dev/null
+++ b/examples/0403/MyAndroidTutorial/build.gradle
@@ -0,0 +1,19 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+ repositories {
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:1.0.0'
+
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+}
+
+allprojects {
+ repositories {
+ jcenter()
+ }
+}
diff --git a/examples/0403/MyAndroidTutorial/gradle.properties b/examples/0403/MyAndroidTutorial/gradle.properties
new file mode 100644
index 0000000..1d3591c
--- /dev/null
+++ b/examples/0403/MyAndroidTutorial/gradle.properties
@@ -0,0 +1,18 @@
+# Project-wide Gradle settings.
+
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+# Default value: -Xmx10248m -XX:MaxPermSize=256m
+# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
+
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
\ No newline at end of file
diff --git a/examples/0403/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.jar b/examples/0403/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
Binary files /dev/null and b/examples/0403/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/examples/0403/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.properties b/examples/0403/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..0c71e76
--- /dev/null
+++ b/examples/0403/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
diff --git a/examples/0403/MyAndroidTutorial/gradlew b/examples/0403/MyAndroidTutorial/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/examples/0403/MyAndroidTutorial/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/examples/0403/MyAndroidTutorial/gradlew.bat b/examples/0403/MyAndroidTutorial/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/examples/0403/MyAndroidTutorial/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/examples/0403/MyAndroidTutorial/settings.gradle b/examples/0403/MyAndroidTutorial/settings.gradle
new file mode 100644
index 0000000..e7b4def
--- /dev/null
+++ b/examples/0403/MyAndroidTutorial/settings.gradle
@@ -0,0 +1 @@
+include ':app'
diff --git a/examples/0501/MyAndroidTutorial/.gitignore b/examples/0501/MyAndroidTutorial/.gitignore
new file mode 100644
index 0000000..afbdab3
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/.gitignore
@@ -0,0 +1,6 @@
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
diff --git a/examples/0501/MyAndroidTutorial/.idea/.name b/examples/0501/MyAndroidTutorial/.idea/.name
new file mode 100644
index 0000000..5bb7a85
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/.idea/.name
@@ -0,0 +1 @@
+MyAndroidTutorial
\ No newline at end of file
diff --git a/examples/0501/MyAndroidTutorial/.idea/compiler.xml b/examples/0501/MyAndroidTutorial/.idea/compiler.xml
new file mode 100644
index 0000000..217af47
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/.idea/compiler.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0501/MyAndroidTutorial/.idea/copyright/profiles_settings.xml b/examples/0501/MyAndroidTutorial/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..e7bedf3
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/examples/0501/MyAndroidTutorial/.idea/encodings.xml b/examples/0501/MyAndroidTutorial/.idea/encodings.xml
new file mode 100644
index 0000000..e206d70
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/.idea/encodings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/examples/0501/MyAndroidTutorial/.idea/gradle.xml b/examples/0501/MyAndroidTutorial/.idea/gradle.xml
new file mode 100644
index 0000000..fe865d3
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/.idea/gradle.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0501/MyAndroidTutorial/.idea/misc.xml b/examples/0501/MyAndroidTutorial/.idea/misc.xml
new file mode 100644
index 0000000..9076de5
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/.idea/misc.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0501/MyAndroidTutorial/.idea/modules.xml b/examples/0501/MyAndroidTutorial/.idea/modules.xml
new file mode 100644
index 0000000..327df67
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/.idea/modules.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0501/MyAndroidTutorial/.idea/scopes/scope_settings.xml b/examples/0501/MyAndroidTutorial/.idea/scopes/scope_settings.xml
new file mode 100644
index 0000000..922003b
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/.idea/scopes/scope_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0501/MyAndroidTutorial/.idea/vcs.xml b/examples/0501/MyAndroidTutorial/.idea/vcs.xml
new file mode 100644
index 0000000..def6a6a
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/.idea/vcs.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/examples/0501/MyAndroidTutorial/MyAndroidTutorial.iml b/examples/0501/MyAndroidTutorial/MyAndroidTutorial.iml
new file mode 100644
index 0000000..0bb6048
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/MyAndroidTutorial.iml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0501/MyAndroidTutorial/app/.gitignore b/examples/0501/MyAndroidTutorial/app/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/app/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/examples/0501/MyAndroidTutorial/app/app.iml b/examples/0501/MyAndroidTutorial/app/app.iml
new file mode 100644
index 0000000..b767e16
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/app/app.iml
@@ -0,0 +1,113 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0501/MyAndroidTutorial/app/build.gradle b/examples/0501/MyAndroidTutorial/app/build.gradle
new file mode 100644
index 0000000..e1475ee
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/app/build.gradle
@@ -0,0 +1,26 @@
+apply plugin: 'com.android.application'
+
+android {
+ compileSdkVersion 21
+ buildToolsVersion "21.1.2"
+
+ defaultConfig {
+ applicationId "net.macdidi.myandroidtutorial"
+ minSdkVersion 15
+ targetSdkVersion 21
+ versionCode 1
+ versionName "1.0"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ compile fileTree(dir: 'libs', include: ['*.jar'])
+ compile 'com.android.support:appcompat-v7:22.0.0'
+ compile 'com.google.android.gms:play-services:7.0.0'
+}
diff --git a/examples/0501/MyAndroidTutorial/app/proguard-rules.pro b/examples/0501/MyAndroidTutorial/app/proguard-rules.pro
new file mode 100644
index 0000000..b5fa7ec
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/app/proguard-rules.pro
@@ -0,0 +1,17 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /Users/macdidi5/Library/Android/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
diff --git a/examples/0501/MyAndroidTutorial/app/src/androidTest/java/net/macdidi/myandroidtutorial/ApplicationTest.java b/examples/0501/MyAndroidTutorial/app/src/androidTest/java/net/macdidi/myandroidtutorial/ApplicationTest.java
new file mode 100644
index 0000000..2cb214e
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/app/src/androidTest/java/net/macdidi/myandroidtutorial/ApplicationTest.java
@@ -0,0 +1,13 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Application;
+import android.test.ApplicationTestCase;
+
+/**
+ * Testing Fundamentals
+ */
+public class ApplicationTest extends ApplicationTestCase {
+ public ApplicationTest() {
+ super(Application.class);
+ }
+}
\ No newline at end of file
diff --git a/examples/0501/MyAndroidTutorial/app/src/debug/res/values/google_maps_api.xml b/examples/0501/MyAndroidTutorial/app/src/debug/res/values/google_maps_api.xml
new file mode 100644
index 0000000..7341c8d
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/app/src/debug/res/values/google_maps_api.xml
@@ -0,0 +1,18 @@
+
+
+
+ AIzaSyCZg9YWlfokPA96VxWGYr6u4C12jL16VhM
+
+
diff --git a/examples/0501/MyAndroidTutorial/app/src/main/AndroidManifest.xml b/examples/0501/MyAndroidTutorial/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..5cccaf4
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/app/src/main/AndroidManifest.xml
@@ -0,0 +1,112 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0501/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/AboutActivity.java b/examples/0501/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/AboutActivity.java
new file mode 100644
index 0000000..42dddeb
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/AboutActivity.java
@@ -0,0 +1,24 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.view.Window;
+
+public class AboutActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ // 取消元件的應用程式標題
+ requestWindowFeature(Window.FEATURE_NO_TITLE);
+ setContentView(R.layout.activity_about);
+ }
+
+ // 結束按鈕
+ public void clickOk(View view) {
+ // 呼叫這個方法結束Activity元件
+ finish();
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0501/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/AlarmReceiver.java b/examples/0501/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/AlarmReceiver.java
new file mode 100644
index 0000000..dc9fbc0
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/AlarmReceiver.java
@@ -0,0 +1,18 @@
+package net.macdidi.myandroidtutorial;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.widget.Toast;
+
+public class AlarmReceiver extends BroadcastReceiver {
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ // 讀取記事標題
+ String title = intent.getStringExtra("title");
+ // 顯示訊息框
+ Toast.makeText(context, title, Toast.LENGTH_LONG).show();
+ }
+
+}
diff --git a/examples/0501/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ColorActivity.java b/examples/0501/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ColorActivity.java
new file mode 100644
index 0000000..182cd55
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ColorActivity.java
@@ -0,0 +1,75 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.LinearLayout;
+
+public class ColorActivity extends Activity {
+
+ private LinearLayout color_gallery;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_color);
+
+ processViews();
+
+ ColorListener listener = new ColorListener();
+
+ for (Colors c : Colors.values()) {
+ Button button = new Button(this);
+ button.setId(c.parseColor());
+ LinearLayout.LayoutParams layout =
+ new LinearLayout.LayoutParams(128, 128);
+ layout.setMargins(6, 6, 6, 6);
+ button.setLayoutParams(layout);
+ button.setBackgroundColor(c.parseColor());
+
+ button.setOnClickListener(listener);
+
+ color_gallery.addView(button);
+ }
+ }
+
+ private void processViews() {
+ color_gallery = (LinearLayout) findViewById(R.id.color_gallery);
+ }
+
+ private class ColorListener implements OnClickListener {
+
+ @Override
+ public void onClick(View view) {
+ String action = ColorActivity.this.getIntent().getAction();
+
+ // 經由設定元件啟動
+ if (action != null &&
+ action.equals("net.macdidi.myandroidtutorial.CHOOSE_COLOR")) {
+ // 建立SharedPreferences物件
+ SharedPreferences.Editor editor =
+ PreferenceManager.getDefaultSharedPreferences(
+ ColorActivity.this).edit();
+ // 儲存預設顏色
+ editor.putInt("DEFAULT_COLOR", view.getId());
+ // 寫入設定值
+ editor.commit();
+ finish();
+ }
+ // 經由新增或修改記事的元件啟動
+ else {
+ Intent result = getIntent();
+ result.putExtra("colorId", view.getId());
+ setResult(Activity.RESULT_OK, result);
+ finish();
+ }
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0501/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Colors.java b/examples/0501/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Colors.java
new file mode 100644
index 0000000..1462149
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Colors.java
@@ -0,0 +1,24 @@
+package net.macdidi.myandroidtutorial;
+
+import android.graphics.Color;
+
+public enum Colors {
+
+ LIGHTGREY("#D3D3D3"), BLUE("#33B5E5"), PURPLE("#AA66CC"),
+ GREEN("#99CC00"), ORANGE("#FFBB33"), RED("#FF4444");
+
+ private String code;
+
+ private Colors(String code) {
+ this.code = code;
+ }
+
+ public String getCode() {
+ return code;
+ }
+
+ public int parseColor() {
+ return Color.parseColor(code);
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0501/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/FileUtil.java b/examples/0501/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/FileUtil.java
new file mode 100644
index 0000000..1fb41be
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/FileUtil.java
@@ -0,0 +1,112 @@
+package net.macdidi.myandroidtutorial;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.os.Environment;
+import android.util.Log;
+import android.widget.ImageView;
+
+import java.io.File;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+public class FileUtil {
+
+ // 應用程式儲存檔案的目錄
+ public static final String APP_DIR = "androidtutorial";
+
+ // 外部儲存設備是否可寫入
+ public static boolean isExternalStorageWritable() {
+ // 取得目前外部儲存設備的狀態
+ String state = Environment.getExternalStorageState();
+
+ // 判斷是否可寫入
+ if (Environment.MEDIA_MOUNTED.equals(state)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ // 外部儲存設備是否可讀取
+ public static boolean isExternalStorageReadable() {
+ // 取得目前外部儲存設備的狀態
+ String state = Environment.getExternalStorageState();
+
+ // 判斷是否可讀取
+ if (Environment.MEDIA_MOUNTED.equals(state) ||
+ Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ // 建立並傳回在公用相簿下參數指定的路徑
+ public static File getPublicAlbumStorageDir(String albumName) {
+ // 取得公用的照片路徑
+ File pictures = Environment.getExternalStoragePublicDirectory(
+ Environment.DIRECTORY_PICTURES);
+ // 準備在照片路徑下建立一個指定的路徑
+ File file = new File(pictures, albumName);
+
+ // 如果建立路徑不成功
+ if (!file.mkdirs()) {
+ Log.e("getAlbumStorageDir", "Directory not created");
+ }
+
+ return file;
+ }
+
+ // 建立並傳回在應用程式專用相簿下參數指定的路徑
+ public static File getAlbumStorageDir(Context context, String albumName) {
+ // 取得應用程式專用的照片路徑
+ File pictures = context.getExternalFilesDir(
+ Environment.DIRECTORY_PICTURES);
+ // 準備在照片路徑下建立一個指定的路徑
+ File file = new File(pictures, albumName);
+
+ // 如果建立路徑不成功
+ if (!file.mkdirs()) {
+ Log.e("getAlbumStorageDir", "Directory not created");
+ }
+
+ return file;
+ }
+
+ // 建立並傳回外部儲存媒體參數指定的路徑
+ public static File getExternalStorageDir(String dir) {
+ File result = new File(
+ Environment.getExternalStorageDirectory(), dir);
+
+ if (!isExternalStorageWritable()) {
+ return null;
+ }
+
+ if (!result.exists() && !result.mkdirs()) {
+ return null;
+ }
+
+ return result;
+ }
+
+ // 讀取指定的照片檔案名稱設定給ImageView元件
+ public static void fileToImageView(String fileName, ImageView imageView) {
+ if (new File(fileName).exists()) {
+ Bitmap bitmap = BitmapFactory.decodeFile(fileName);
+ imageView.setImageBitmap(bitmap);
+ }
+ else {
+ Log.e("fileToImageView", fileName + " not found.");
+ }
+ }
+
+ // 產生唯一的檔案名稱
+ public static String getUniqueFileName() {
+ // 使用年月日_時分秒格式為檔案名稱
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
+ return sdf.format(new Date());
+ }
+
+}
diff --git a/examples/0501/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/InitAlarmReceiver.java b/examples/0501/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/InitAlarmReceiver.java
new file mode 100644
index 0000000..39d6e6c
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/InitAlarmReceiver.java
@@ -0,0 +1,46 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+import java.util.Calendar;
+import java.util.List;
+
+public class InitAlarmReceiver extends BroadcastReceiver {
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ // 建立資料庫物件
+ ItemDAO itemDAO = new ItemDAO(context.getApplicationContext());
+ // 讀取資料庫所有記事資料
+ List- items = itemDAO.getAll();
+
+ // 讀取目前時間
+ long current = Calendar.getInstance().getTimeInMillis();
+
+ AlarmManager am = (AlarmManager)
+ context.getSystemService(Context.ALARM_SERVICE);
+
+ for (Item item : items) {
+ long alarm = item.getAlarmDatetime();
+
+ // 如果沒有設定提醒或是提醒已經過期
+ if (alarm == 0 || alarm <= current) {
+ continue;
+ }
+
+ // 設定提醒
+ Intent alarmIntent = new Intent(context, AlarmReceiver.class);
+ alarmIntent.putExtra("title", item.getTitle());
+
+ PendingIntent pi = PendingIntent.getBroadcast(
+ context, (int)item.getId(),
+ alarmIntent, PendingIntent.FLAG_ONE_SHOT);
+ am.set(AlarmManager.RTC_WAKEUP, item.getAlarmDatetime(), pi);
+ }
+ }
+
+}
diff --git a/examples/0501/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Item.java b/examples/0501/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Item.java
new file mode 100644
index 0000000..6f4e0b2
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Item.java
@@ -0,0 +1,157 @@
+package net.macdidi.myandroidtutorial;
+
+import java.util.Date;
+import java.util.Locale;
+
+public class Item implements java.io.Serializable {
+
+ // 編號、日期時間、顏色、標題、內容、檔案名稱、經緯度、修改、已選擇
+ private long id;
+ private long datetime;
+ private Colors color;
+ private String title;
+ private String content;
+ private String fileName;
+ private String recFileName;
+ private double latitude;
+ private double longitude;
+ private long lastModify;
+ private boolean selected;
+
+ // 提醒日期時間
+ private long alarmDatetime;
+
+ public Item() {
+ title = "";
+ content = "";
+ color = Colors.LIGHTGREY;
+ }
+
+ public Item(long id, long datetime, Colors color, String title,
+ String content, String fileName, String recFileName,
+ double latitude, double longitude, long lastModify) {
+ this.id = id;
+ this.datetime = datetime;
+ this.color = color;
+ this.title = title;
+ this.content = content;
+ this.fileName = fileName;
+ this.recFileName = recFileName;
+ this.latitude = latitude;
+ this.longitude = longitude;
+ this.lastModify = lastModify;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public long getDatetime() {
+ return datetime;
+ }
+
+ // 裝置區域的日期時間
+ public String getLocaleDatetime() {
+ return String.format(Locale.getDefault(), "%tF %
0) {
+ // 照片檔案物件
+ File file = configFileName("P", ".jpg");
+
+ // 如果照片檔案存在
+ if (file.exists()) {
+ // 顯示照片元件
+ picture.setVisibility(View.VISIBLE);
+ // 設定照片
+ FileUtil.fileToImageView(file.getAbsolutePath(), picture);
+ }
+ }
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (resultCode == Activity.RESULT_OK) {
+ switch (requestCode) {
+ // 照像
+ case START_CAMERA:
+ // 設定照片檔案名稱
+ item.setFileName(fileName);
+ break;
+ case START_RECORD:
+ // 設定錄音檔案名稱
+ item.setRecFileName(recFileName);
+ break;
+ case START_LOCATION:
+ // 讀取與設定座標
+ double lat = data.getDoubleExtra("lat", 0.0);
+ double lng = data.getDoubleExtra("lng", 0.0);
+ item.setLatitude(lat);
+ item.setLongitude(lng);
+ break;
+ case START_ALARM:
+ break;
+ // 設定顏色
+ case START_COLOR:
+ int colorId = data.getIntExtra(
+ "colorId", Colors.LIGHTGREY.parseColor());
+ item.setColor(getColors(colorId));
+ break;
+ }
+ }
+ }
+
+ public static Colors getColors(int color) {
+ Colors result = Colors.LIGHTGREY;
+
+ if (color == Colors.BLUE.parseColor()) {
+ result = Colors.BLUE;
+ }
+ else if (color == Colors.PURPLE.parseColor()) {
+ result = Colors.PURPLE;
+ }
+ else if (color == Colors.GREEN.parseColor()) {
+ result = Colors.GREEN;
+ }
+ else if (color == Colors.ORANGE.parseColor()) {
+ result = Colors.ORANGE;
+ }
+ else if (color == Colors.RED.parseColor()) {
+ result = Colors.RED;
+ }
+
+ return result;
+ }
+
+ private void processViews() {
+ title_text = (EditText) findViewById(R.id.title_text);
+ content_text = (EditText) findViewById(R.id.content_text);
+ // 取得顯示照片的ImageView元件
+ picture = (ImageView) findViewById(R.id.picture);
+ }
+
+ // 點擊確定與取消按鈕都會呼叫這個方法
+ public void onSubmit(View view) {
+
+ if (view.getId() == R.id.ok_teim) {
+ String titleText = title_text.getText().toString();
+ String contentText = content_text.getText().toString();
+
+ item.setTitle(titleText);
+ item.setContent(contentText);
+
+ if (getIntent().getAction().equals(
+ "net.macdidi.myandroidtutorial.EDIT_ITEM")) {
+ item.setLastModify(new Date().getTime());
+ }
+ // 新增記事
+ else {
+ item.setDatetime(new Date().getTime());
+ // 建立SharedPreferences物件
+ SharedPreferences sharedPreferences =
+ PreferenceManager.getDefaultSharedPreferences(this);
+ // 讀取設定的預設顏色
+ int color = sharedPreferences.getInt("DEFAULT_COLOR", -1);
+ item.setColor(getColors(color));
+ }
+
+ Intent result = getIntent();
+ result.putExtra("net.macdidi.myandroidtutorial.Item", item);
+ setResult(Activity.RESULT_OK, result);
+ }
+
+ // 結束
+ finish();
+ }
+
+ public void clickFunction(View view) {
+ int id = view.getId();
+
+ switch (id) {
+ case R.id.take_picture:
+ // 啟動相機元件用的Intent物件
+ Intent intentCamera =
+ new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
+
+ // 照片檔案名稱
+ File pictureFile = configFileName("P", ".jpg");
+ Uri uri = Uri.fromFile(pictureFile);
+ // 設定檔案名稱
+ intentCamera.putExtra(MediaStore.EXTRA_OUTPUT, uri);
+ // 啟動相機元件
+ startActivityForResult(intentCamera, START_CAMERA);
+ break;
+ case R.id.record_sound:
+ // 錄音檔案名稱
+ final File recordFile = configRecFileName("R", ".mp3");
+
+ // 如果已經有錄音檔,詢問播放或重新錄製
+ if (recordFile.exists()) {
+ // 詢問播放還是重新錄製的對話框
+ AlertDialog.Builder d = new AlertDialog.Builder(this);
+
+ d.setTitle(R.string.title_record)
+ .setCancelable(false);
+ d.setPositiveButton(R.string.record_play,
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ // 播放
+ Intent playIntent = new Intent(
+ ItemActivity.this, PlayActivity.class);
+ playIntent.putExtra("fileName",
+ recordFile.getAbsolutePath());
+ startActivity(playIntent);
+ }
+ });
+ d.setNeutralButton(R.string.record_new,
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ goToRecord(recordFile);
+ }
+ });
+ d.setNegativeButton(android.R.string.cancel, null);
+
+ // 顯示對話框
+ d.show();
+ }
+ // 如果沒有錄音檔,啟動錄音元件
+ else {
+ goToRecord(recordFile);
+ }
+
+ break;
+ case R.id.set_location:
+ // 啟動地圖元件用的Intent物件
+ Intent intentMap = new Intent(this, MapsActivity.class);
+
+ // 設定儲存的座標
+ intentMap.putExtra("lat", item.getLatitude());
+ intentMap.putExtra("lng", item.getLongitude());
+ intentMap.putExtra("title", item.getTitle());
+ intentMap.putExtra("datetime", item.getLocaleDatetime());
+
+ // 啟動地圖元件
+ startActivityForResult(intentMap, START_LOCATION);
+ break;
+ case R.id.set_alarm:
+ // 設定提醒日期時間
+ processSetAlarm();
+ break;
+ case R.id.select_color:
+ // 啟動設定顏色的Activity元件
+ startActivityForResult(
+ new Intent(this, ColorActivity.class), START_COLOR);
+ break;
+ }
+
+ }
+
+ // 設定提醒日期時間
+ private void processSetAlarm() {
+ Calendar calendar = Calendar.getInstance();
+
+ if (item.getAlarmDatetime() != 0) {
+ // 設定為已經儲存的提醒日期時間
+ calendar.setTimeInMillis(item.getAlarmDatetime());
+ }
+
+ // 讀取年、月、日、時、分
+ int year = calendar.get(Calendar.YEAR);
+ int month = calendar.get(Calendar.MONTH);
+ int day = calendar.get(Calendar.DAY_OF_MONTH);
+ int hour = calendar.get(Calendar.HOUR_OF_DAY);
+ int minute = calendar.get(Calendar.MINUTE);
+
+ // 儲存設定的提醒日期時間
+ final Calendar alarm = Calendar.getInstance();
+
+ // 設定提醒時間
+ TimePickerDialog.OnTimeSetListener timeSetListener =
+ new TimePickerDialog.OnTimeSetListener() {
+ @Override
+ public void onTimeSet(TimePicker view,
+ int hourOfDay, int minute) {
+ alarm.set(Calendar.HOUR_OF_DAY, hourOfDay);
+ alarm.set(Calendar.MINUTE, minute);
+
+ item.setAlarmDatetime(alarm.getTimeInMillis());
+ }
+ };
+
+ // 選擇時間對話框
+ final TimePickerDialog tpd = new TimePickerDialog(
+ this, timeSetListener, hour, minute, true);
+
+ // 設定提醒日期
+ DatePickerDialog.OnDateSetListener dateSetListener =
+ new DatePickerDialog.OnDateSetListener() {
+ @Override
+ public void onDateSet(DatePicker view,
+ int year,
+ int monthOfYear,
+ int dayOfMonth) {
+ alarm.set(Calendar.YEAR, year);
+ alarm.set(Calendar.MONTH, monthOfYear);
+ alarm.set(Calendar.DAY_OF_MONTH, dayOfMonth);
+
+ // 繼續選擇提醒時間
+ tpd.show();
+ }
+ };
+
+ // 建立與顯示選擇日期對話框
+ final DatePickerDialog dpd = new DatePickerDialog(
+ this, dateSetListener, year, month, day);
+ dpd.show();
+ }
+
+ private void goToRecord(File recordFile) {
+ // 錄音
+ Intent recordIntent = new Intent(this, RecordActivity.class);
+ recordIntent.putExtra("fileName", recordFile.getAbsolutePath());
+ startActivityForResult(recordIntent, START_RECORD);
+ }
+
+ private File configFileName(String prefix, String extension) {
+ // 如果記事資料已經有檔案名稱
+ if (item.getFileName() != null && item.getFileName().length() > 0) {
+ fileName = item.getFileName();
+ }
+ // 產生檔案名稱
+ else {
+ fileName = FileUtil.getUniqueFileName();
+ }
+
+ return new File(FileUtil.getExternalStorageDir(FileUtil.APP_DIR),
+ prefix + fileName + extension);
+ }
+
+ private File configRecFileName(String prefix, String extension) {
+ // 如果記事資料已經有檔案名稱
+ if (item.getRecFileName() != null && item.getRecFileName().length() > 0) {
+ recFileName = item.getRecFileName();
+ }
+ // 產生檔案名稱
+ else {
+ recFileName = FileUtil.getUniqueFileName();
+ }
+
+ return new File(FileUtil.getExternalStorageDir(FileUtil.APP_DIR),
+ prefix + recFileName + extension);
+ }
+
+}
diff --git a/examples/0501/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemAdapter.java b/examples/0501/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemAdapter.java
new file mode 100644
index 0000000..85b40ba
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemAdapter.java
@@ -0,0 +1,80 @@
+package net.macdidi.myandroidtutorial;
+
+import android.content.Context;
+import android.graphics.drawable.GradientDrawable;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+import java.util.List;
+
+public class ItemAdapter extends ArrayAdapter- {
+
+ // 畫面資源編號
+ private int resource;
+ // 包裝的記事資料
+ private List
- items;
+
+ public ItemAdapter(Context context, int resource, List
- items) {
+ super(context, resource, items);
+ this.resource = resource;
+ this.items = items;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ LinearLayout itemView;
+ // 讀取目前位置的記事物件
+ final Item item = getItem(position);
+
+ if (convertView == null) {
+ // 建立項目畫面元件
+ itemView = new LinearLayout(getContext());
+ String inflater = Context.LAYOUT_INFLATER_SERVICE;
+ LayoutInflater li = (LayoutInflater)
+ getContext().getSystemService(inflater);
+ li.inflate(resource, itemView, true);
+ }
+ else {
+ itemView = (LinearLayout) convertView;
+ }
+
+ // 讀取記事顏色、已選擇、標題與日期時間元件
+ RelativeLayout typeColor = (RelativeLayout) itemView.findViewById(R.id.type_color);
+ ImageView selectedItem = (ImageView) itemView.findViewById(R.id.selected_item);
+ TextView titleView = (TextView) itemView.findViewById(R.id.title_text);
+ TextView dateView = (TextView) itemView.findViewById(R.id.date_text);
+
+ // 設定記事顏色
+ GradientDrawable background = (GradientDrawable)typeColor.getBackground();
+ background.setColor(item.getColor().parseColor());
+
+ // 設定標題與日期時間
+ titleView.setText(item.getTitle());
+ dateView.setText(item.getLocaleDatetime());
+
+ // 設定是否已選擇
+ selectedItem.setVisibility(item.isSelected() ? View.VISIBLE : View.INVISIBLE);
+
+ return itemView;
+ }
+
+ // 設定指定編號的記事資料
+ public void set(int index, Item item) {
+ if (index >= 0 && index < items.size()) {
+ items.set(index, item);
+ notifyDataSetChanged();
+ }
+ }
+
+ // 讀取指定編號的記事資料
+ public Item get(int index) {
+ return items.get(index);
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0501/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemDAO.java b/examples/0501/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemDAO.java
new file mode 100644
index 0000000..6e5b007
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemDAO.java
@@ -0,0 +1,214 @@
+package net.macdidi.myandroidtutorial;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+// 資料功能類別
+public class ItemDAO {
+ // 表格名稱
+ public static final String TABLE_NAME = "item";
+
+ // 編號表格欄位名稱,固定不變
+ public static final String KEY_ID = "_id";
+
+ // 其它表格欄位名稱
+ public static final String DATETIME_COLUMN = "datetime";
+ public static final String COLOR_COLUMN = "color";
+ public static final String TITLE_COLUMN = "title";
+ public static final String CONTENT_COLUMN = "content";
+ public static final String FILENAME_COLUMN = "filename";
+ public static final String RECFILENAME_COLUMN = "recfilename";
+ public static final String LATITUDE_COLUMN = "latitude";
+ public static final String LONGITUDE_COLUMN = "longitude";
+ public static final String LASTMODIFY_COLUMN = "lastmodify";
+
+ // 提醒日期時間
+ public static final String ALARMDATETIME_COLUMN = "alarmdatetime";
+
+ // 使用上面宣告的變數建立表格的SQL指令
+ public static final String CREATE_TABLE =
+ "CREATE TABLE " + TABLE_NAME + " (" +
+ KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
+ DATETIME_COLUMN + " INTEGER NOT NULL, " +
+ COLOR_COLUMN + " INTEGER NOT NULL, " +
+ TITLE_COLUMN + " TEXT NOT NULL, " +
+ CONTENT_COLUMN + " TEXT NOT NULL, " +
+ FILENAME_COLUMN + " TEXT, " +
+ RECFILENAME_COLUMN + " TEXT, " +
+ LATITUDE_COLUMN + " REAL, " +
+ LONGITUDE_COLUMN + " REAL, " +
+ LASTMODIFY_COLUMN + " INTEGER, " +
+ ALARMDATETIME_COLUMN + " INTEGER)";
+
+ // 資料庫物件
+ private SQLiteDatabase db;
+
+ // 建構子,一般的應用都不需要修改
+ public ItemDAO(Context context) {
+ db = MyDBHelper.getDatabase(context);
+ }
+
+ // 關閉資料庫,一般的應用都不需要修改
+ public void close() {
+ db.close();
+ }
+
+ // 新增參數指定的物件
+ public Item insert(Item item) {
+ // 建立準備新增資料的ContentValues物件
+ ContentValues cv = new ContentValues();
+
+ // 加入ContentValues物件包裝的新增資料
+ // 第一個參數是欄位名稱, 第二個參數是欄位的資料
+ cv.put(DATETIME_COLUMN, item.getDatetime());
+ cv.put(COLOR_COLUMN, item.getColor().parseColor());
+ cv.put(TITLE_COLUMN, item.getTitle());
+ cv.put(CONTENT_COLUMN, item.getContent());
+ cv.put(FILENAME_COLUMN, item.getFileName());
+ cv.put(RECFILENAME_COLUMN, item.getRecFileName());
+ cv.put(LATITUDE_COLUMN, item.getLatitude());
+ cv.put(LONGITUDE_COLUMN, item.getLongitude());
+ cv.put(LASTMODIFY_COLUMN, item.getLastModify());
+
+ // 提醒日期時間
+ cv.put(ALARMDATETIME_COLUMN, item.getAlarmDatetime());
+
+ // 新增一筆資料並取得編號
+ // 第一個參數是表格名稱
+ // 第二個參數是沒有指定欄位值的預設值
+ // 第三個參數是包裝新增資料的ContentValues物件
+ long id = db.insert(TABLE_NAME, null, cv);
+
+ // 設定編號
+ item.setId(id);
+ // 回傳結果
+ return item;
+ }
+
+ // 修改參數指定的物件
+ public boolean update(Item item) {
+ // 建立準備修改資料的ContentValues物件
+ ContentValues cv = new ContentValues();
+
+ // 加入ContentValues物件包裝的修改資料
+ // 第一個參數是欄位名稱, 第二個參數是欄位的資料
+ cv.put(DATETIME_COLUMN, item.getDatetime());
+ cv.put(COLOR_COLUMN, item.getColor().parseColor());
+ cv.put(TITLE_COLUMN, item.getTitle());
+ cv.put(CONTENT_COLUMN, item.getContent());
+ cv.put(FILENAME_COLUMN, item.getFileName());
+ cv.put(RECFILENAME_COLUMN, item.getRecFileName());
+ cv.put(LATITUDE_COLUMN, item.getLatitude());
+ cv.put(LONGITUDE_COLUMN, item.getLongitude());
+ cv.put(LASTMODIFY_COLUMN, item.getLastModify());
+
+ // 提醒日期時間
+ cv.put(ALARMDATETIME_COLUMN, item.getAlarmDatetime());
+
+ // 設定修改資料的條件為編號
+ // 格式為「欄位名稱=資料」
+ String where = KEY_ID + "=" + item.getId();
+
+ // 執行修改資料並回傳修改的資料數量是否成功
+ return db.update(TABLE_NAME, cv, where, null) > 0;
+ }
+
+ // 刪除參數指定編號的資料
+ public boolean delete(long id){
+ // 設定條件為編號,格式為「欄位名稱=資料」
+ String where = KEY_ID + "=" + id;
+ // 刪除指定編號資料並回傳刪除是否成功
+ return db.delete(TABLE_NAME, where , null) > 0;
+ }
+
+ // 讀取所有記事資料
+ public List
- getAll() {
+ List
- result = new ArrayList<>();
+ Cursor cursor = db.query(
+ TABLE_NAME, null, null, null, null, null, null, null);
+
+ while (cursor.moveToNext()) {
+ result.add(getRecord(cursor));
+ }
+
+ cursor.close();
+ return result;
+ }
+
+ // 取得指定編號的資料物件
+ public Item get(long id) {
+ // 準備回傳結果用的物件
+ Item item = null;
+ // 使用編號為查詢條件
+ String where = KEY_ID + "=" + id;
+ // 執行查詢
+ Cursor result = db.query(
+ TABLE_NAME, null, where, null, null, null, null, null);
+
+ // 如果有查詢結果
+ if (result.moveToFirst()) {
+ // 讀取包裝一筆資料的物件
+ item = getRecord(result);
+ }
+
+ // 關閉Cursor物件
+ result.close();
+ // 回傳結果
+ return item;
+ }
+
+ // 把Cursor目前的資料包裝為物件
+ public Item getRecord(Cursor cursor) {
+ // 準備回傳結果用的物件
+ Item result = new Item();
+
+ result.setId(cursor.getLong(0));
+ result.setDatetime(cursor.getLong(1));
+ result.setColor(ItemActivity.getColors(cursor.getInt(2)));
+ result.setTitle(cursor.getString(3));
+ result.setContent(cursor.getString(4));
+ result.setFileName(cursor.getString(5));
+ result.setRecFileName(cursor.getString(6));
+ result.setLatitude(cursor.getDouble(7));
+ result.setLongitude(cursor.getDouble(8));
+ result.setLastModify(cursor.getLong(9));
+
+ // 提醒日期時間
+ result.setAlarmDatetime(cursor.getLong(10));
+
+ // 回傳結果
+ return result;
+ }
+
+ // 取得資料數量
+ public int getCount() {
+ int result = 0;
+ Cursor cursor = db.rawQuery("SELECT COUNT(*) FROM " + TABLE_NAME, null);
+
+ if (cursor.moveToNext()) {
+ result = cursor.getInt(0);
+ }
+
+ return result;
+ }
+
+ // 建立範例資料
+ public void sample() {
+ Item item = new Item(0, new Date().getTime(), Colors.RED, "關於Android Tutorial的事情.", "Hello content", "", "", 0, 0, 0);
+ Item item2 = new Item(0, new Date().getTime(), Colors.BLUE, "一隻非常可愛的小狗狗!", "她的名字叫「大熱狗」,又叫\n作「奶嘴」,是一隻非常可愛\n的小狗。", "", "", 25.04719, 121.516981, 0);
+ Item item3 = new Item(0, new Date().getTime(), Colors.GREEN, "一首非常好聽的音樂!", "Hello content", "", "", 0, 0, 0);
+ Item item4 = new Item(0, new Date().getTime(), Colors.ORANGE, "儲存在資料庫的資料", "Hello content", "", "", 0, 0, 0);
+
+ insert(item);
+ insert(item2);
+ insert(item3);
+ insert(item4);
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0501/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MainActivity.java b/examples/0501/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MainActivity.java
new file mode 100644
index 0000000..0a8c1f0
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MainActivity.java
@@ -0,0 +1,327 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.app.AlarmManager;
+import android.app.AlertDialog;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.v7.app.ActionBarActivity;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import java.util.List;
+
+public class MainActivity extends ActionBarActivity {
+ private ListView item_list;
+ private TextView show_app_name;
+
+ // ListView使用的自定Adapter物件
+ private ItemAdapter itemAdapter;
+ // 儲存所有記事本的List物件
+ private List
- items;
+
+ // 選單項目物件
+ private MenuItem add_item, search_item, revert_item, share_item, delete_item;
+
+ // 已選擇項目數量
+ private int selectedCount = 0;
+
+ // 宣告資料庫功能類別欄位變數
+ private ItemDAO itemDAO;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ processViews();
+ processControllers();
+
+ // 建立資料庫物件
+ itemDAO = new ItemDAO(getApplicationContext());
+
+ // 如果資料庫是空的,就建立一些範例資料
+ // 這是為了方便測試用的,完成應用程式以後可以拿掉
+ if (itemDAO.getCount() == 0) {
+ itemDAO.sample();
+ }
+
+ // 取得所有記事資料
+ items = itemDAO.getAll();
+
+ itemAdapter = new ItemAdapter(this, R.layout.single_item, items);
+ item_list.setAdapter(itemAdapter);
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (resultCode == Activity.RESULT_OK) {
+ Item item = (Item) data.getExtras().getSerializable(
+ "net.macdidi.myandroidtutorial.Item");
+
+ // 是否修改提醒設定
+ boolean updateAlarm = false;
+
+ if (requestCode == 0) {
+ // 新增記事資料到資料庫
+ item = itemDAO.insert(item);
+
+ items.add(item);
+ itemAdapter.notifyDataSetChanged();
+ }
+ else if (requestCode == 1) {
+ int position = data.getIntExtra("position", -1);
+
+ if (position != -1) {
+ // 讀取原來的提醒設定
+ Item ori = itemDAO.get(item.getId());
+ // 判斷是否需要設定提醒
+ updateAlarm = (item.getAlarmDatetime() != ori.getAlarmDatetime());
+
+ // 修改資料庫中的記事資料
+ itemDAO.update(item);
+
+ items.set(position, item);
+ itemAdapter.notifyDataSetChanged();
+ }
+ }
+
+ // 設定提醒
+ if (item.getAlarmDatetime() != 0 && updateAlarm) {
+ Intent intent = new Intent(this, AlarmReceiver.class);
+ intent.putExtra("title", item.getTitle());
+
+ PendingIntent pi = PendingIntent.getBroadcast(
+ this, (int)item.getId(),
+ intent, PendingIntent.FLAG_ONE_SHOT);
+
+ AlarmManager am = (AlarmManager)
+ getSystemService(Context.ALARM_SERVICE);
+ am.set(AlarmManager.RTC_WAKEUP, item.getAlarmDatetime(), pi);
+ }
+ }
+ }
+
+ private void processViews() {
+ item_list = (ListView)findViewById(R.id.item_list);
+ show_app_name = (TextView) findViewById(R.id.show_app_name);
+ }
+
+ private void processControllers() {
+
+ // 建立選單項目點擊監聽物件
+ AdapterView.OnItemClickListener itemListener = new AdapterView.OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView> parent, View view,
+ int position, long id) {
+ // 讀取選擇的記事物件
+ Item item = itemAdapter.getItem(position);
+
+ // 如果已經有勾選的項目
+ if (selectedCount > 0) {
+ // 處理是否顯示已選擇項目
+ processMenu(item);
+ // 重新設定記事項目
+ itemAdapter.set(position, item);
+ }
+ else {
+ Intent intent = new Intent(
+ "net.macdidi.myandroidtutorial.EDIT_ITEM");
+
+ // 設定記事編號與記事物件
+ intent.putExtra("position", position);
+ intent.putExtra("net.macdidi.myandroidtutorial.Item", item);
+
+ startActivityForResult(intent, 1);
+ }
+ }
+ };
+
+ // 註冊選單項目點擊監聽物件
+ item_list.setOnItemClickListener(itemListener);
+
+ // 建立記事項目長按監聽物件
+ AdapterView.OnItemLongClickListener itemLongListener = new AdapterView.OnItemLongClickListener() {
+ @Override
+ public boolean onItemLongClick(AdapterView> parent, View view,
+ int position, long id) {
+ // 讀取選擇的記事物件
+ Item item = itemAdapter.getItem(position);
+ // 處理是否顯示已選擇項目
+ processMenu(item);
+ // 重新設定記事項目
+ itemAdapter.set(position, item);
+ return true;
+ }
+ };
+
+ // 註冊記事項目長按監聽物件
+ item_list.setOnItemLongClickListener(itemLongListener);
+
+ // 建立長按監聽物件
+ View.OnLongClickListener listener = new View.OnLongClickListener() {
+
+ @Override
+ public boolean onLongClick(View view) {
+ AlertDialog.Builder dialog =
+ new AlertDialog.Builder(MainActivity.this);
+ dialog.setTitle(R.string.app_name)
+ .setMessage(R.string.about)
+ .show();
+ return false;
+ }
+
+ };
+
+ // 註冊長按監聽物件
+ show_app_name.setOnLongClickListener(listener);
+ }
+
+ // 處理是否顯示已選擇項目
+ private void processMenu(Item item) {
+ // 如果需要設定記事項目
+ if (item != null) {
+ // 設定已勾選的狀態
+ item.setSelected(!item.isSelected());
+
+ // 計算已勾選數量
+ if (item.isSelected()) {
+ selectedCount++;
+ }
+ else {
+ selectedCount--;
+ }
+ }
+
+ // 根據選擇的狀況,設定是否顯示選單項目
+ add_item.setVisible(selectedCount == 0);
+ search_item.setVisible(selectedCount == 0);
+ revert_item.setVisible(selectedCount > 0);
+ share_item.setVisible(selectedCount > 0);
+ delete_item.setVisible(selectedCount > 0);
+ }
+
+ // 載入選單資源
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ MenuInflater menuInflater = getMenuInflater();
+ menuInflater.inflate(R.menu.menu_main, menu);
+
+ // 取得選單項目物件
+ add_item = menu.findItem(R.id.add_item);
+ search_item = menu.findItem(R.id.search_item);
+ revert_item = menu.findItem(R.id.revert_item);
+ share_item = menu.findItem(R.id.share_item);
+ delete_item = menu.findItem(R.id.delete_item);
+
+ // 設定選單項目
+ processMenu(null);
+
+ return true;
+ }
+
+ // 使用者選擇所有的選單項目都會呼叫這個方法
+ public void clickMenuItem(MenuItem item) {
+ // 使用參數取得使用者選擇的選單項目元件編號
+ int itemId = item.getItemId();
+
+ // 判斷該執行什麼工作,目前還沒有加入需要執行的工作
+ switch (itemId) {
+ case R.id.search_item:
+ break;
+ // 使用者選擇新增選單項目
+ case R.id.add_item:
+ // 使用Action名稱建立啟動另一個Activity元件需要的Intent物件
+ Intent intent = new Intent("net.macdidi.myandroidtutorial.ADD_ITEM");
+ // 呼叫「startActivityForResult」,,第二個參數「0」表示執行新增
+ startActivityForResult(intent, 0);
+ break;
+ // 取消所有已勾選的項目
+ case R.id.revert_item:
+ for (int i = 0; i < itemAdapter.getCount(); i++) {
+ Item ri = itemAdapter.getItem(i);
+
+ if (ri.isSelected()) {
+ ri.setSelected(false);
+ itemAdapter.set(i, ri);
+ }
+ }
+
+ selectedCount = 0;
+ processMenu(null);
+
+ break;
+ // 刪除
+ case R.id.delete_item:
+ if (selectedCount == 0) {
+ break;
+ }
+
+ AlertDialog.Builder d = new AlertDialog.Builder(this);
+ String message = getString(R.string.delete_item);
+ d.setTitle(R.string.delete)
+ .setMessage(String.format(message, selectedCount));
+ d.setPositiveButton(android.R.string.yes,
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ // 取得最後一個元素的編號
+ int index = itemAdapter.getCount() - 1;
+
+ while (index > -1) {
+ Item item = itemAdapter.get(index);
+
+ if (item.isSelected()) {
+ itemAdapter.remove(item);
+ // 刪除資料庫中的記事資料
+ itemDAO.delete(item.getId());
+ }
+
+ index--;
+ }
+
+ itemAdapter.notifyDataSetChanged();
+ selectedCount = 0;
+ processMenu(null);
+ }
+ });
+ d.setNegativeButton(android.R.string.no, null);
+ d.show();
+
+ break;
+ case R.id.googleplus_item:
+ break;
+ case R.id.facebook_item:
+ break;
+ }
+
+ }
+
+ // 方法名稱與onClick的設定一樣,參數的型態是android.view.View
+ public void aboutApp(View view) {
+ // 建立啟動另一個Activity元件需要的Intent物件
+ // 建構式的第一個參數:「this」
+ // 建構式的第二個參數:「Activity元件類別名稱.class」
+ Intent intent = new Intent(this, AboutActivity.class);
+ // 呼叫「startActivity」,參數為一個建立好的Intent物件
+ // 這行敘述執行以後,如果沒有任何錯誤,就會啟動指定的元件
+ startActivity(intent);
+ }
+
+ // 設定
+ public void clickPreferences(MenuItem item) {
+ // 啟動設定元件
+ startActivity(new Intent(this, PrefActivity.class));
+ }
+
+}
+
+
diff --git a/examples/0501/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MapsActivity.java b/examples/0501/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MapsActivity.java
new file mode 100644
index 0000000..abab911
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MapsActivity.java
@@ -0,0 +1,338 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.location.Location;
+import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
+import android.widget.Toast;
+
+import com.google.android.gms.common.ConnectionResult;
+import com.google.android.gms.common.api.GoogleApiClient;
+import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
+import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
+
+import com.google.android.gms.location.LocationListener;
+import com.google.android.gms.location.LocationRequest;
+import com.google.android.gms.location.LocationServices;
+
+import com.google.android.gms.maps.CameraUpdateFactory;
+import com.google.android.gms.maps.GoogleMap;
+import com.google.android.gms.maps.SupportMapFragment;
+import com.google.android.gms.maps.model.BitmapDescriptor;
+import com.google.android.gms.maps.model.BitmapDescriptorFactory;
+import com.google.android.gms.maps.model.CameraPosition;
+import com.google.android.gms.maps.model.LatLng;
+import com.google.android.gms.maps.model.Marker;
+import com.google.android.gms.maps.model.MarkerOptions;
+
+public class MapsActivity extends FragmentActivity
+ implements ConnectionCallbacks,
+ OnConnectionFailedListener,
+ LocationListener {
+
+ private GoogleMap mMap;
+
+ // Google API用戶端物件
+ private GoogleApiClient googleApiClient;
+
+ // Location請求物件
+ private LocationRequest locationRequest;
+
+ // 記錄目前最新的位置
+ private Location currentLocation;
+
+ // 顯示目前與儲存位置的標記物件
+ private Marker currentMarker, itemMarker;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_maps);
+ setUpMapIfNeeded();
+
+ // 建立Google API用戶端物件
+ configGoogleApiClient();
+
+ // 建立Location請求物件
+ configLocationRequest();
+
+ // 讀取記事儲存的座標
+ Intent intent = getIntent();
+ double lat = intent.getDoubleExtra("lat", 0.0);
+ double lng = intent.getDoubleExtra("lng", 0.0);
+
+ // 如果記事已經儲存座標
+ if (lat != 0.0 && lng != 0.0) {
+ // 建立座標物件
+ LatLng itemPlace = new LatLng(lat, lng);
+ // 加入地圖標記
+ addMarker(itemPlace, intent.getStringExtra("title"),
+ intent.getStringExtra("datetime"));
+ // 移動地圖
+ moveMap(itemPlace);
+ }
+ else {
+ // 連線到Google API用戶端
+ if (!googleApiClient.isConnected()) {
+ googleApiClient.connect();
+ }
+ }
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ setUpMapIfNeeded();
+
+ // 連線到Google API用戶端
+ if (!googleApiClient.isConnected() && currentMarker != null) {
+ googleApiClient.connect();
+ }
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+
+ // 移除位置請求服務
+ if (googleApiClient.isConnected()) {
+ LocationServices.FusedLocationApi.removeLocationUpdates(
+ googleApiClient, this);
+ }
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+
+ // 移除Google API用戶端連線
+ if (googleApiClient.isConnected()) {
+ googleApiClient.disconnect();
+ }
+ }
+
+ // 建立Google API用戶端物件
+ private synchronized void configGoogleApiClient() {
+ googleApiClient = new GoogleApiClient.Builder(this)
+ .addConnectionCallbacks(this)
+ .addOnConnectionFailedListener(this)
+ .addApi(LocationServices.API)
+ .build();
+ }
+
+ // 建立Location請求物件
+ private void configLocationRequest() {
+ locationRequest = new LocationRequest();
+ // 設定讀取位置資訊的間隔時間為一秒(1000ms)
+ locationRequest.setInterval(1000);
+ // 設定讀取位置資訊最快的間隔時間為一秒(1000ms)
+ locationRequest.setFastestInterval(1000);
+ // 設定優先讀取高精確度的位置資訊(GPS)
+ locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
+ }
+
+ private void setUpMapIfNeeded() {
+ if (mMap == null) {
+ mMap = ((SupportMapFragment) getSupportFragmentManager().
+ findFragmentById(R.id.map)).getMap();
+
+ if (mMap != null) {
+ // 移除地圖設定
+ //setUpMap();
+ processController();
+ }
+ }
+ }
+
+ // 移除地圖設定方法
+ private void setUpMap() {
+ // 建立位置的座標物件
+ LatLng place = new LatLng(25.033408, 121.564099);
+ // 移動地圖
+ moveMap(place);
+
+ // 加入地圖標記
+ addMarker(place, "Hello!", " Google Maps v2!");
+ }
+
+ private void processController() {
+ // 對話框按鈕事件
+ final DialogInterface.OnClickListener listener =
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ switch (which) {
+ // 更新位置資訊
+ case DialogInterface.BUTTON_POSITIVE:
+ // 連線到Google API用戶端
+ if (!googleApiClient.isConnected()) {
+ googleApiClient.connect();
+ }
+ break;
+ // 清除位置資訊
+ case DialogInterface.BUTTON_NEUTRAL:
+ Intent result = new Intent();
+ result.putExtra("lat", 0);
+ result.putExtra("lng", 0);
+ setResult(Activity.RESULT_OK, result);
+ finish();
+ break;
+ // 取消
+ case DialogInterface.BUTTON_NEGATIVE:
+ break;
+ }
+ }
+ };
+
+ // 標記訊息框點擊事件
+ mMap.setOnInfoWindowClickListener(new GoogleMap.OnInfoWindowClickListener() {
+ @Override
+ public void onInfoWindowClick(Marker marker) {
+ // 如果是記事儲存的標記
+ if (marker.equals(itemMarker)) {
+ AlertDialog.Builder ab = new AlertDialog.Builder(MapsActivity.this);
+
+ ab.setTitle(R.string.title_update_location)
+ .setMessage(R.string.message_update_location)
+ .setCancelable(true);
+
+ ab.setPositiveButton(R.string.update, listener);
+ ab.setNeutralButton(R.string.clear, listener);
+ ab.setNegativeButton(android.R.string.cancel, listener);
+
+ ab.show();
+ }
+ }
+ });
+
+ // 標記點擊事件
+ mMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
+ @Override
+ public boolean onMarkerClick(Marker marker) {
+ // 如果是目前位置標記
+ if (marker.equals(currentMarker)) {
+ AlertDialog.Builder ab = new AlertDialog.Builder(MapsActivity.this);
+
+ ab.setTitle(R.string.title_current_location)
+ .setMessage(R.string.message_current_location)
+ .setCancelable(true);
+
+ ab.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ Intent result = new Intent();
+ result.putExtra("lat", currentLocation.getLatitude());
+ result.putExtra("lng", currentLocation.getLongitude());
+ setResult(Activity.RESULT_OK, result);
+ finish();
+ }
+ });
+ ab.setNegativeButton(android.R.string.cancel, null);
+
+ ab.show();
+
+ return true;
+ }
+
+ return false;
+ }
+ });
+ }
+
+ // 移動地圖到參數指定的位置
+ private void moveMap(LatLng place) {
+ // 建立地圖攝影機的位置物件
+ CameraPosition cameraPosition =
+ new CameraPosition.Builder()
+ .target(place)
+ .zoom(17)
+ .build();
+
+ // 使用動畫的效果移動地圖
+ mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition),
+ new GoogleMap.CancelableCallback() {
+ @Override
+ public void onFinish() {
+ if (itemMarker != null) {
+ itemMarker.showInfoWindow();
+ }
+ }
+
+ @Override
+ public void onCancel() {
+
+ }
+ });
+ }
+
+ // 在地圖加入指定位置與標題的標記
+ private void addMarker(LatLng place, String title, String snippet) {
+ BitmapDescriptor icon =
+ BitmapDescriptorFactory.fromResource(R.drawable.ic_launcher);
+
+ MarkerOptions markerOptions = new MarkerOptions();
+ markerOptions.position(place)
+ .title(title)
+ .snippet(snippet)
+ .icon(icon);
+
+ // 加入並設定記事儲存的位置標記
+ itemMarker = mMap.addMarker(markerOptions);
+ }
+
+ // ConnectionCallbacks
+ @Override
+ public void onConnected(Bundle bundle) {
+ // 已經連線到Google Services
+ // 啟動位置更新服務
+ // 位置資訊更新的時候,應用程式會自動呼叫LocationListener.onLocationChanged
+ LocationServices.FusedLocationApi.requestLocationUpdates(
+ googleApiClient, locationRequest, MapsActivity.this);
+ }
+
+ // ConnectionCallbacks
+ @Override
+ public void onConnectionSuspended(int i) {
+ // Google Services連線中斷
+ // int參數是連線中斷的代號
+ }
+
+ // OnConnectionFailedListener
+ @Override
+ public void onConnectionFailed(ConnectionResult connectionResult) {
+ // Google Services連線失敗
+ // ConnectionResult參數是連線失敗的資訊
+ int errorCode = connectionResult.getErrorCode();
+
+ // 裝置沒有安裝Google Play服務
+ if (errorCode == ConnectionResult.SERVICE_MISSING) {
+ Toast.makeText(this, R.string.google_play_service_missing,
+ Toast.LENGTH_LONG).show();
+ }
+ }
+
+ // LocationListener
+ @Override
+ public void onLocationChanged(Location location) {
+ // 位置改變
+ // Location參數是目前的位置
+ currentLocation = location;
+ LatLng latLng = new LatLng(
+ location.getLatitude(), location.getLongitude());
+
+ // 設定目前位置的標記
+ if (currentMarker == null) {
+ currentMarker = mMap.addMarker(new MarkerOptions().position(latLng));
+ }
+ else {
+ currentMarker.setPosition(latLng);
+ }
+
+ // 移動地圖到目前的位置
+ moveMap(latLng);
+ }
+
+}
diff --git a/examples/0501/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MyDBHelper.java b/examples/0501/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MyDBHelper.java
new file mode 100644
index 0000000..9350577
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MyDBHelper.java
@@ -0,0 +1,47 @@
+package net.macdidi.myandroidtutorial;
+
+import android.content.Context;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteDatabase.CursorFactory;
+import android.database.sqlite.SQLiteOpenHelper;
+
+public class MyDBHelper extends SQLiteOpenHelper {
+
+ // 資料庫名稱
+ public static final String DATABASE_NAME = "mydata.db";
+ // 資料庫版本,資料結構改變的時候要更改這個數字,通常是加一
+ public static final int VERSION = 3;
+ // 資料庫物件,固定的欄位變數
+ private static SQLiteDatabase database;
+
+ // 建構子,在一般的應用都不需要修改
+ public MyDBHelper(Context context, String name, CursorFactory factory,
+ int version) {
+ super(context, name, factory, version);
+ }
+
+ // 需要資料庫的元件呼叫這個方法,這個方法在一般的應用都不需要修改
+ public static SQLiteDatabase getDatabase(Context context) {
+ if (database == null || !database.isOpen()) {
+ database = new MyDBHelper(context, DATABASE_NAME,
+ null, VERSION).getWritableDatabase();
+ }
+
+ return database;
+ }
+
+ @Override
+ public void onCreate(SQLiteDatabase db) {
+ // 建立應用程式需要的表格
+ db.execSQL(ItemDAO.CREATE_TABLE);
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ // 刪除原有的表格
+ db.execSQL("DROP TABLE IF EXISTS " + ItemDAO.TABLE_NAME);
+ // 呼叫onCreate建立新版的表格
+ onCreate(db);
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0501/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PlayActivity.java b/examples/0501/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PlayActivity.java
new file mode 100644
index 0000000..5cfb523
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PlayActivity.java
@@ -0,0 +1,64 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.media.MediaPlayer;
+import android.net.Uri;
+import android.os.Bundle;
+import android.view.View;
+
+public class PlayActivity extends Activity {
+
+ private MediaPlayer mediaPlayer;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_play);
+
+ Intent intent = getIntent();
+ String fileName = intent.getStringExtra("fileName");
+
+ // 建立指定資源的MediaPlayer物件
+ Uri uri = Uri.parse(fileName);
+ mediaPlayer = MediaPlayer.create(this, uri);
+ }
+
+ @Override
+ protected void onStop() {
+ if (mediaPlayer.isPlaying()) {
+ // 停止播放
+ mediaPlayer.stop();
+ }
+
+ // 清除MediaPlayer物件
+ mediaPlayer.release();
+ super.onStop();
+ }
+
+ public void onSubmit(View view) {
+ // 結束Activity元件
+ finish();
+ }
+
+ public void clickPlay(View view) {
+ // 開始播放
+ mediaPlayer.start();
+ }
+
+ public void clickPause(View view) {
+ // 暫停播放
+ mediaPlayer.pause();
+ }
+
+ public void clickStop(View view) {
+ // 停止播放
+ if (mediaPlayer.isPlaying()) {
+ mediaPlayer.stop();
+ }
+
+ // 回到開始的位置
+ mediaPlayer.seekTo(0);
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0501/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PrefActivity.java b/examples/0501/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PrefActivity.java
new file mode 100644
index 0000000..b2dcc4a
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PrefActivity.java
@@ -0,0 +1,38 @@
+package net.macdidi.myandroidtutorial;
+
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceManager;
+
+public class PrefActivity extends PreferenceActivity {
+
+ private SharedPreferences sharedPreferences;
+ private Preference defaultColor;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ // 指定使用的設定畫面配置資源
+ addPreferencesFromResource(R.xml.mypreference);
+ defaultColor = (Preference)findPreference("DEFAULT_COLOR");
+ // 建立SharedPreferences物件
+ sharedPreferences =
+ PreferenceManager.getDefaultSharedPreferences(this);
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ // 讀取設定的預設顏色
+ int color = sharedPreferences.getInt("DEFAULT_COLOR", -1);
+
+ if (color != -1) {
+ // 設定顏色說明
+ defaultColor.setSummary(getString(R.string.default_color_summary) +
+ ": " + ItemActivity.getColors(color));
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0501/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/RecordActivity.java b/examples/0501/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/RecordActivity.java
new file mode 100644
index 0000000..62b5e93
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/RecordActivity.java
@@ -0,0 +1,180 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.media.MediaRecorder;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.widget.ImageButton;
+import android.widget.ProgressBar;
+
+import java.io.IOException;
+
+public class RecordActivity extends Activity {
+
+ private ImageButton record_button;
+ private boolean isRecording = false;
+ private ProgressBar record_volumn;
+
+ private MyRecoder myRecoder;
+
+ private String fileName;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_record);
+
+ processViews();
+
+ // 讀取檔案名稱
+ Intent intent = getIntent();
+ fileName = intent.getStringExtra("fileName");
+ }
+
+ public void onSubmit(View view) {
+ if (isRecording) {
+ // 停止錄音
+ myRecoder.stop();
+ }
+
+ // 確定
+ if (view.getId() == R.id.record_ok) {
+ Intent result = getIntent();
+ setResult(Activity.RESULT_OK, result);
+ }
+
+ finish();
+ }
+
+ private void processViews() {
+ record_button = (ImageButton) findViewById(R.id.record_button);
+ record_volumn = (ProgressBar) findViewById(R.id.record_volumn);
+ // 隱藏狀態列ProgressBar
+ setProgressBarIndeterminateVisibility(false);
+ }
+
+ public void clickRecord(View view) {
+ // 切換
+ isRecording = !isRecording;
+
+ // 開始錄音
+ if (isRecording) {
+ // 設定按鈕圖示為錄音中
+ record_button.setImageResource(R.drawable.record_red_icon);
+ // 建立錄音物件
+ myRecoder = new MyRecoder(fileName);
+ // 開始錄音
+ myRecoder.start();
+ // 建立並執行顯示麥克風音量的AsyncTask物件
+ new MicLevelTask().execute();
+ }
+ // 停止錄音
+ else {
+ // 設定按鈕圖示為停止錄音
+ record_button.setImageResource(R.drawable.record_dark_icon);
+ // 麥克風音量歸零
+ record_volumn.setProgress(0);
+ // 停止錄音
+ myRecoder.stop();
+ }
+ }
+
+ // 在錄音過程中顯示麥克風音量
+ private class MicLevelTask extends AsyncTask
{
+ @Override
+ protected Void doInBackground(Void... args) {
+ while (isRecording) {
+ publishProgress();
+
+ try {
+ Thread.sleep(200);
+ }
+ catch (InterruptedException e) {
+ Log.d("RecordActivity", e.toString());
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ protected void onProgressUpdate(Void... values) {
+ record_volumn.setProgress((int) myRecoder.getAmplitudeEMA());
+ }
+
+ }
+
+ // 執行錄音並且可以取得麥克風音量的錄音物件
+ private class MyRecoder {
+
+ private static final double EMA_FILTER = 0.6;
+ private MediaRecorder recorder = null;
+ private double mEMA = 0.0;
+ private String output;
+
+ // 建立錄音物件,參數為錄音儲存的位置與檔名
+ MyRecoder(String output) {
+ this.output = output;
+ }
+
+ // 開始錄音
+ public void start() {
+ if (recorder == null) {
+ // 建立錄音用的MediaRecorder物件
+ recorder = new MediaRecorder();
+ // 設定錄音來源為麥克風,必須在setOutputFormat方法之前呼叫
+ recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
+ // 設定輸出格式為3GP壓縮格式,必須在setAudioSource方法之後,
+ // 在prepare方法之前呼叫
+ recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
+ // 設定錄音的編碼方式,必須在setOutputFormat方法之後,
+ // 在prepare方法之前呼叫
+ recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
+ // 設定輸出的檔案名稱,必須在setOutputFormat方法之後,
+ // 在prepare方法之前呼叫
+ recorder.setOutputFile(output);
+
+ try {
+ // 準備執行錄音工作,必須在所有設定之後呼叫
+ recorder.prepare();
+ }
+ catch (IOException e) {
+ Log.d("RecordActivity", e.toString());
+ }
+
+ // 開始錄音
+ recorder.start();
+ mEMA = 0.0;
+ }
+ }
+
+ // 停止錄音
+ public void stop() {
+ if (recorder != null) {
+ // 停止錄音
+ recorder.stop();
+ // 清除錄音資源
+ recorder.release();
+ recorder = null;
+ }
+ }
+
+ public double getAmplitude() {
+ if (recorder != null)
+ return (recorder.getMaxAmplitude() / 2700.0);
+ else
+ return 0;
+ }
+
+ // 取得麥克風音量
+ public double getAmplitudeEMA() {
+ double amp = getAmplitude();
+ mEMA = EMA_FILTER * amp + (1.0 - EMA_FILTER) * mEMA;
+ return mEMA;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0501/MyAndroidTutorial/app/src/main/res/drawable-hdpi/ic_launcher.png b/examples/0501/MyAndroidTutorial/app/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..96a442e
Binary files /dev/null and b/examples/0501/MyAndroidTutorial/app/src/main/res/drawable-hdpi/ic_launcher.png differ
diff --git a/examples/0501/MyAndroidTutorial/app/src/main/res/drawable-mdpi/ic_launcher.png b/examples/0501/MyAndroidTutorial/app/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..359047d
Binary files /dev/null and b/examples/0501/MyAndroidTutorial/app/src/main/res/drawable-mdpi/ic_launcher.png differ
diff --git a/examples/0501/MyAndroidTutorial/app/src/main/res/drawable-xhdpi/ic_launcher.png b/examples/0501/MyAndroidTutorial/app/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..71c6d76
Binary files /dev/null and b/examples/0501/MyAndroidTutorial/app/src/main/res/drawable-xhdpi/ic_launcher.png differ
diff --git a/examples/0501/MyAndroidTutorial/app/src/main/res/drawable-xxhdpi/ic_launcher.png b/examples/0501/MyAndroidTutorial/app/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..4df1894
Binary files /dev/null and b/examples/0501/MyAndroidTutorial/app/src/main/res/drawable-xxhdpi/ic_launcher.png differ
diff --git a/examples/0501/MyAndroidTutorial/app/src/main/res/drawable/alarm_icon.png b/examples/0501/MyAndroidTutorial/app/src/main/res/drawable/alarm_icon.png
new file mode 100644
index 0000000..c6cac88
Binary files /dev/null and b/examples/0501/MyAndroidTutorial/app/src/main/res/drawable/alarm_icon.png differ
diff --git a/examples/0501/MyAndroidTutorial/app/src/main/res/drawable/item_drawable.xml b/examples/0501/MyAndroidTutorial/app/src/main/res/drawable/item_drawable.xml
new file mode 100644
index 0000000..37607e2
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/app/src/main/res/drawable/item_drawable.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0501/MyAndroidTutorial/app/src/main/res/drawable/location_icon.png b/examples/0501/MyAndroidTutorial/app/src/main/res/drawable/location_icon.png
new file mode 100644
index 0000000..4c3c514
Binary files /dev/null and b/examples/0501/MyAndroidTutorial/app/src/main/res/drawable/location_icon.png differ
diff --git a/examples/0501/MyAndroidTutorial/app/src/main/res/drawable/pause_icon.png b/examples/0501/MyAndroidTutorial/app/src/main/res/drawable/pause_icon.png
new file mode 100755
index 0000000..a5aee6f
Binary files /dev/null and b/examples/0501/MyAndroidTutorial/app/src/main/res/drawable/pause_icon.png differ
diff --git a/examples/0501/MyAndroidTutorial/app/src/main/res/drawable/play_icon.png b/examples/0501/MyAndroidTutorial/app/src/main/res/drawable/play_icon.png
new file mode 100755
index 0000000..6a40cd5
Binary files /dev/null and b/examples/0501/MyAndroidTutorial/app/src/main/res/drawable/play_icon.png differ
diff --git a/examples/0501/MyAndroidTutorial/app/src/main/res/drawable/record_dark_icon.png b/examples/0501/MyAndroidTutorial/app/src/main/res/drawable/record_dark_icon.png
new file mode 100755
index 0000000..bcf83ca
Binary files /dev/null and b/examples/0501/MyAndroidTutorial/app/src/main/res/drawable/record_dark_icon.png differ
diff --git a/examples/0501/MyAndroidTutorial/app/src/main/res/drawable/record_red_icon.png b/examples/0501/MyAndroidTutorial/app/src/main/res/drawable/record_red_icon.png
new file mode 100755
index 0000000..2b44af0
Binary files /dev/null and b/examples/0501/MyAndroidTutorial/app/src/main/res/drawable/record_red_icon.png differ
diff --git a/examples/0501/MyAndroidTutorial/app/src/main/res/drawable/record_sound_icon.png b/examples/0501/MyAndroidTutorial/app/src/main/res/drawable/record_sound_icon.png
new file mode 100755
index 0000000..a1382ac
Binary files /dev/null and b/examples/0501/MyAndroidTutorial/app/src/main/res/drawable/record_sound_icon.png differ
diff --git a/examples/0501/MyAndroidTutorial/app/src/main/res/drawable/retangle_drawable.xml b/examples/0501/MyAndroidTutorial/app/src/main/res/drawable/retangle_drawable.xml
new file mode 100644
index 0000000..51d1e84
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/app/src/main/res/drawable/retangle_drawable.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0501/MyAndroidTutorial/app/src/main/res/drawable/select_color_icon.png b/examples/0501/MyAndroidTutorial/app/src/main/res/drawable/select_color_icon.png
new file mode 100644
index 0000000..8567d5e
Binary files /dev/null and b/examples/0501/MyAndroidTutorial/app/src/main/res/drawable/select_color_icon.png differ
diff --git a/examples/0501/MyAndroidTutorial/app/src/main/res/drawable/selected_icon.png b/examples/0501/MyAndroidTutorial/app/src/main/res/drawable/selected_icon.png
new file mode 100755
index 0000000..b891571
Binary files /dev/null and b/examples/0501/MyAndroidTutorial/app/src/main/res/drawable/selected_icon.png differ
diff --git a/examples/0501/MyAndroidTutorial/app/src/main/res/drawable/stop_icon.png b/examples/0501/MyAndroidTutorial/app/src/main/res/drawable/stop_icon.png
new file mode 100755
index 0000000..20df415
Binary files /dev/null and b/examples/0501/MyAndroidTutorial/app/src/main/res/drawable/stop_icon.png differ
diff --git a/examples/0501/MyAndroidTutorial/app/src/main/res/drawable/take_picture_icon.png b/examples/0501/MyAndroidTutorial/app/src/main/res/drawable/take_picture_icon.png
new file mode 100644
index 0000000..08fb514
Binary files /dev/null and b/examples/0501/MyAndroidTutorial/app/src/main/res/drawable/take_picture_icon.png differ
diff --git a/examples/0501/MyAndroidTutorial/app/src/main/res/layout/activity_about.xml b/examples/0501/MyAndroidTutorial/app/src/main/res/layout/activity_about.xml
new file mode 100644
index 0000000..8e78611
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/app/src/main/res/layout/activity_about.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0501/MyAndroidTutorial/app/src/main/res/layout/activity_color.xml b/examples/0501/MyAndroidTutorial/app/src/main/res/layout/activity_color.xml
new file mode 100644
index 0000000..d25bbc5
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/app/src/main/res/layout/activity_color.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
diff --git a/examples/0501/MyAndroidTutorial/app/src/main/res/layout/activity_item.xml b/examples/0501/MyAndroidTutorial/app/src/main/res/layout/activity_item.xml
new file mode 100644
index 0000000..4ec4362
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/app/src/main/res/layout/activity_item.xml
@@ -0,0 +1,125 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0501/MyAndroidTutorial/app/src/main/res/layout/activity_main.xml b/examples/0501/MyAndroidTutorial/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..121511b
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
diff --git a/examples/0501/MyAndroidTutorial/app/src/main/res/layout/activity_maps.xml b/examples/0501/MyAndroidTutorial/app/src/main/res/layout/activity_maps.xml
new file mode 100644
index 0000000..5de477b
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/app/src/main/res/layout/activity_maps.xml
@@ -0,0 +1,7 @@
+
diff --git a/examples/0501/MyAndroidTutorial/app/src/main/res/layout/activity_play.xml b/examples/0501/MyAndroidTutorial/app/src/main/res/layout/activity_play.xml
new file mode 100644
index 0000000..52db308
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/app/src/main/res/layout/activity_play.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0501/MyAndroidTutorial/app/src/main/res/layout/activity_record.xml b/examples/0501/MyAndroidTutorial/app/src/main/res/layout/activity_record.xml
new file mode 100644
index 0000000..63d9e36
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/app/src/main/res/layout/activity_record.xml
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0501/MyAndroidTutorial/app/src/main/res/layout/single_item.xml b/examples/0501/MyAndroidTutorial/app/src/main/res/layout/single_item.xml
new file mode 100644
index 0000000..40ddbc9
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/app/src/main/res/layout/single_item.xml
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0501/MyAndroidTutorial/app/src/main/res/menu/menu_about.xml b/examples/0501/MyAndroidTutorial/app/src/main/res/menu/menu_about.xml
new file mode 100644
index 0000000..d481100
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/app/src/main/res/menu/menu_about.xml
@@ -0,0 +1,7 @@
+
+
+
diff --git a/examples/0501/MyAndroidTutorial/app/src/main/res/menu/menu_color.xml b/examples/0501/MyAndroidTutorial/app/src/main/res/menu/menu_color.xml
new file mode 100644
index 0000000..8ff243b
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/app/src/main/res/menu/menu_color.xml
@@ -0,0 +1,7 @@
+
+
+
diff --git a/examples/0501/MyAndroidTutorial/app/src/main/res/menu/menu_item.xml b/examples/0501/MyAndroidTutorial/app/src/main/res/menu/menu_item.xml
new file mode 100644
index 0000000..cd2c9e4
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/app/src/main/res/menu/menu_item.xml
@@ -0,0 +1,7 @@
+
+
+
diff --git a/examples/0501/MyAndroidTutorial/app/src/main/res/menu/menu_main.xml b/examples/0501/MyAndroidTutorial/app/src/main/res/menu/menu_main.xml
new file mode 100644
index 0000000..0203cfa
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/app/src/main/res/menu/menu_main.xml
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
diff --git a/examples/0501/MyAndroidTutorial/app/src/main/res/values-en/strings.xml b/examples/0501/MyAndroidTutorial/app/src/main/res/values-en/strings.xml
new file mode 100644
index 0000000..c532533
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/app/src/main/res/values-en/strings.xml
@@ -0,0 +1,12 @@
+
+
+
+ MyAndroidTutorial
+ Hello world!
+ Settings
+
+ Title
+ Enter title
+ Content
+ Enter content
+
diff --git a/examples/0501/MyAndroidTutorial/app/src/main/res/values-w820dp/dimens.xml b/examples/0501/MyAndroidTutorial/app/src/main/res/values-w820dp/dimens.xml
new file mode 100644
index 0000000..63fc816
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/app/src/main/res/values-w820dp/dimens.xml
@@ -0,0 +1,6 @@
+
+
+ 64dp
+
diff --git a/examples/0501/MyAndroidTutorial/app/src/main/res/values/colors.xml b/examples/0501/MyAndroidTutorial/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..6b13c1d
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/app/src/main/res/values/colors.xml
@@ -0,0 +1,7 @@
+
+
+ #CCCCCC
+ #AAAAAA
+ #DD999999
+ #111111
+
\ No newline at end of file
diff --git a/examples/0501/MyAndroidTutorial/app/src/main/res/values/dimens.xml b/examples/0501/MyAndroidTutorial/app/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..02898ec
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/app/src/main/res/values/dimens.xml
@@ -0,0 +1,9 @@
+
+
+ 16dp
+ 16dp
+
+ 6dp
+ 24sp
+ 2dp
+
diff --git a/examples/0501/MyAndroidTutorial/app/src/main/res/values/strings.xml b/examples/0501/MyAndroidTutorial/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..89dcf0f
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/app/src/main/res/values/strings.xml
@@ -0,0 +1,56 @@
+
+
+
+ MyAndroidTutorial
+ Hello world!
+ Settings
+ 標題
+ 輸入標題
+ 內容
+ 輸入內容
+ 這是Android Tutorial應用程式
+ AboutActivity
+ 版本:AndroidTutorial_0.2.4
+ ItemActivity
+ ColorActivity
+ 刪除
+ 確定要刪除 %1$d 個項目?
+ 預設的顏色
+ 新增記事的預設顏色
+
+ 預設提醒時間
+ 在指定的時間之前通知
+
+
+ - 五分鐘
+ - 十分鐘
+ - 二十分鐘
+ - 三十分鐘
+ - 六十分鐘
+
+
+
+ - 5
+ - 10
+ - 20
+ - 30
+ - 60
+
+
+ 語音備忘
+ 播放語音備忘
+ 播放
+ 重新錄製
+ Map
+
+ 記事儲存的位置
+ 更新或清除儲存的位置資訊?
+ 更新
+ 清除
+
+ 目前位置
+ 是否儲存目前位置?
+
+ 裝置沒有安裝Google Play服務
+
+
diff --git a/examples/0501/MyAndroidTutorial/app/src/main/res/values/styles.xml b/examples/0501/MyAndroidTutorial/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..766ab99
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/app/src/main/res/values/styles.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
diff --git a/examples/0501/MyAndroidTutorial/app/src/main/res/xml/mypreference.xml b/examples/0501/MyAndroidTutorial/app/src/main/res/xml/mypreference.xml
new file mode 100644
index 0000000..33e714c
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/app/src/main/res/xml/mypreference.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0501/MyAndroidTutorial/app/src/release/res/values/google_maps_api.xml b/examples/0501/MyAndroidTutorial/app/src/release/res/values/google_maps_api.xml
new file mode 100644
index 0000000..c4e2431
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/app/src/release/res/values/google_maps_api.xml
@@ -0,0 +1,18 @@
+
+
+
+ YOUR_KEY_HERE
+
+
diff --git a/examples/0501/MyAndroidTutorial/build.gradle b/examples/0501/MyAndroidTutorial/build.gradle
new file mode 100644
index 0000000..6356aab
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/build.gradle
@@ -0,0 +1,19 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+ repositories {
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:1.0.0'
+
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+}
+
+allprojects {
+ repositories {
+ jcenter()
+ }
+}
diff --git a/examples/0501/MyAndroidTutorial/gradle.properties b/examples/0501/MyAndroidTutorial/gradle.properties
new file mode 100644
index 0000000..1d3591c
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/gradle.properties
@@ -0,0 +1,18 @@
+# Project-wide Gradle settings.
+
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+# Default value: -Xmx10248m -XX:MaxPermSize=256m
+# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
+
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
\ No newline at end of file
diff --git a/examples/0501/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.jar b/examples/0501/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
Binary files /dev/null and b/examples/0501/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/examples/0501/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.properties b/examples/0501/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..0c71e76
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
diff --git a/examples/0501/MyAndroidTutorial/gradlew b/examples/0501/MyAndroidTutorial/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/examples/0501/MyAndroidTutorial/gradlew.bat b/examples/0501/MyAndroidTutorial/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/examples/0501/MyAndroidTutorial/settings.gradle b/examples/0501/MyAndroidTutorial/settings.gradle
new file mode 100644
index 0000000..e7b4def
--- /dev/null
+++ b/examples/0501/MyAndroidTutorial/settings.gradle
@@ -0,0 +1 @@
+include ':app'
diff --git a/examples/0502/MyAndroidTutorial/.gitignore b/examples/0502/MyAndroidTutorial/.gitignore
new file mode 100644
index 0000000..afbdab3
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/.gitignore
@@ -0,0 +1,6 @@
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
diff --git a/examples/0502/MyAndroidTutorial/.idea/.name b/examples/0502/MyAndroidTutorial/.idea/.name
new file mode 100644
index 0000000..5bb7a85
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/.idea/.name
@@ -0,0 +1 @@
+MyAndroidTutorial
\ No newline at end of file
diff --git a/examples/0502/MyAndroidTutorial/.idea/compiler.xml b/examples/0502/MyAndroidTutorial/.idea/compiler.xml
new file mode 100644
index 0000000..217af47
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/.idea/compiler.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0502/MyAndroidTutorial/.idea/copyright/profiles_settings.xml b/examples/0502/MyAndroidTutorial/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..e7bedf3
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/examples/0502/MyAndroidTutorial/.idea/encodings.xml b/examples/0502/MyAndroidTutorial/.idea/encodings.xml
new file mode 100644
index 0000000..e206d70
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/.idea/encodings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/examples/0502/MyAndroidTutorial/.idea/gradle.xml b/examples/0502/MyAndroidTutorial/.idea/gradle.xml
new file mode 100644
index 0000000..fe865d3
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/.idea/gradle.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0502/MyAndroidTutorial/.idea/misc.xml b/examples/0502/MyAndroidTutorial/.idea/misc.xml
new file mode 100644
index 0000000..9076de5
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/.idea/misc.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0502/MyAndroidTutorial/.idea/modules.xml b/examples/0502/MyAndroidTutorial/.idea/modules.xml
new file mode 100644
index 0000000..327df67
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/.idea/modules.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0502/MyAndroidTutorial/.idea/scopes/scope_settings.xml b/examples/0502/MyAndroidTutorial/.idea/scopes/scope_settings.xml
new file mode 100644
index 0000000..922003b
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/.idea/scopes/scope_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0502/MyAndroidTutorial/.idea/vcs.xml b/examples/0502/MyAndroidTutorial/.idea/vcs.xml
new file mode 100644
index 0000000..def6a6a
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/.idea/vcs.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/examples/0502/MyAndroidTutorial/MyAndroidTutorial.iml b/examples/0502/MyAndroidTutorial/MyAndroidTutorial.iml
new file mode 100644
index 0000000..0bb6048
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/MyAndroidTutorial.iml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0502/MyAndroidTutorial/app/.gitignore b/examples/0502/MyAndroidTutorial/app/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/app/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/examples/0502/MyAndroidTutorial/app/app.iml b/examples/0502/MyAndroidTutorial/app/app.iml
new file mode 100644
index 0000000..b767e16
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/app/app.iml
@@ -0,0 +1,113 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0502/MyAndroidTutorial/app/build.gradle b/examples/0502/MyAndroidTutorial/app/build.gradle
new file mode 100644
index 0000000..9423d38
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/app/build.gradle
@@ -0,0 +1,26 @@
+apply plugin: 'com.android.application'
+
+android {
+ compileSdkVersion 21
+ buildToolsVersion "21.1.2"
+
+ defaultConfig {
+ applicationId "net.macdidi.myandroidtutorial"
+ minSdkVersion 16
+ targetSdkVersion 21
+ versionCode 1
+ versionName "1.0"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ compile fileTree(dir: 'libs', include: ['*.jar'])
+ compile 'com.android.support:appcompat-v7:22.0.0'
+ compile 'com.google.android.gms:play-services:7.0.0'
+}
diff --git a/examples/0502/MyAndroidTutorial/app/proguard-rules.pro b/examples/0502/MyAndroidTutorial/app/proguard-rules.pro
new file mode 100644
index 0000000..b5fa7ec
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/app/proguard-rules.pro
@@ -0,0 +1,17 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /Users/macdidi5/Library/Android/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
diff --git a/examples/0502/MyAndroidTutorial/app/src/androidTest/java/net/macdidi/myandroidtutorial/ApplicationTest.java b/examples/0502/MyAndroidTutorial/app/src/androidTest/java/net/macdidi/myandroidtutorial/ApplicationTest.java
new file mode 100644
index 0000000..2cb214e
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/app/src/androidTest/java/net/macdidi/myandroidtutorial/ApplicationTest.java
@@ -0,0 +1,13 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Application;
+import android.test.ApplicationTestCase;
+
+/**
+ * Testing Fundamentals
+ */
+public class ApplicationTest extends ApplicationTestCase {
+ public ApplicationTest() {
+ super(Application.class);
+ }
+}
\ No newline at end of file
diff --git a/examples/0502/MyAndroidTutorial/app/src/debug/res/values/google_maps_api.xml b/examples/0502/MyAndroidTutorial/app/src/debug/res/values/google_maps_api.xml
new file mode 100644
index 0000000..7341c8d
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/app/src/debug/res/values/google_maps_api.xml
@@ -0,0 +1,18 @@
+
+
+
+ AIzaSyCZg9YWlfokPA96VxWGYr6u4C12jL16VhM
+
+
diff --git a/examples/0502/MyAndroidTutorial/app/src/main/AndroidManifest.xml b/examples/0502/MyAndroidTutorial/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..5cccaf4
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/app/src/main/AndroidManifest.xml
@@ -0,0 +1,112 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0502/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/AboutActivity.java b/examples/0502/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/AboutActivity.java
new file mode 100644
index 0000000..42dddeb
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/AboutActivity.java
@@ -0,0 +1,24 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.view.Window;
+
+public class AboutActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ // 取消元件的應用程式標題
+ requestWindowFeature(Window.FEATURE_NO_TITLE);
+ setContentView(R.layout.activity_about);
+ }
+
+ // 結束按鈕
+ public void clickOk(View view) {
+ // 呼叫這個方法結束Activity元件
+ finish();
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0502/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/AlarmReceiver.java b/examples/0502/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/AlarmReceiver.java
new file mode 100644
index 0000000..368165c
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/AlarmReceiver.java
@@ -0,0 +1,86 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.support.v4.app.NotificationCompat;
+
+import java.io.File;
+
+public class AlarmReceiver extends BroadcastReceiver {
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ // 讀取記事標題
+ //String title = intent.getStringExtra("title");
+ // 顯示訊息框
+ //Toast.makeText(context, title, Toast.LENGTH_LONG).show();
+
+ // 讀取記事編號
+ long id = intent.getLongExtra("id", 0);
+
+ if (id != 0) {
+ sendNotify(context, id);
+ }
+ }
+
+ private void sendNotify(Context context, long id) {
+ // 建立資料庫物件
+ ItemDAO itemDAO = new ItemDAO(context.getApplicationContext());
+ // 讀取指定編號的記事物件
+ Item item = itemDAO.get(id);
+
+ // 建立照片檔案物件
+ File file = new File(FileUtil.getExternalStorageDir(FileUtil.APP_DIR),
+ "P" + item.getFileName() + ".jpg");
+
+ // 是否儲存照片檔案
+ boolean isPicture = (item.getFileName() != null &&
+ item.getFileName().length() > 0 &&
+ file.exists());
+
+ // 取得NotificationManager物件
+ NotificationManager nm = (NotificationManager)
+ context.getSystemService(Context.NOTIFICATION_SERVICE);
+
+ // 如果有儲存照片檔案
+ if (isPicture) {
+ // 建立Notification.Builder物件,因為要設定大型圖片樣式
+ // 所以不能使用NotificationCompat.Builder
+ Notification.Builder builder = new Notification.Builder(context);
+ builder.setSmallIcon(android.R.drawable.star_on)
+ .setWhen(System.currentTimeMillis())
+ .setContentTitle(context.getString(R.string.app_name));
+
+ // 建立大型圖片樣式物件
+ Notification.BigPictureStyle bigPictureStyle =
+ new Notification.BigPictureStyle();
+ // 設定圖片與簡介
+ Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
+ bigPictureStyle.bigPicture(bitmap)
+ .setSummaryText(item.getTitle());
+ // 設定樣式為大型圖片
+ builder.setStyle(bigPictureStyle);
+ // 發出通知
+ nm.notify((int)item.getId(), builder.build());
+ }
+ // 如果沒有儲存照片檔案
+ else {
+ // 建立NotificationCompat.Builder物件
+ NotificationCompat.Builder builder =
+ new NotificationCompat.Builder(context);
+ // 設定圖示、時間、內容標題和內容訊息
+ builder.setSmallIcon(android.R.drawable.star_big_on)
+ .setWhen(System.currentTimeMillis())
+ .setContentTitle(context.getString(R.string.app_name))
+ .setContentText(item.getTitle());
+ // 發出通知
+ nm.notify((int)item.getId(), builder.build());
+ }
+ }
+
+}
diff --git a/examples/0502/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ColorActivity.java b/examples/0502/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ColorActivity.java
new file mode 100644
index 0000000..182cd55
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ColorActivity.java
@@ -0,0 +1,75 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.LinearLayout;
+
+public class ColorActivity extends Activity {
+
+ private LinearLayout color_gallery;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_color);
+
+ processViews();
+
+ ColorListener listener = new ColorListener();
+
+ for (Colors c : Colors.values()) {
+ Button button = new Button(this);
+ button.setId(c.parseColor());
+ LinearLayout.LayoutParams layout =
+ new LinearLayout.LayoutParams(128, 128);
+ layout.setMargins(6, 6, 6, 6);
+ button.setLayoutParams(layout);
+ button.setBackgroundColor(c.parseColor());
+
+ button.setOnClickListener(listener);
+
+ color_gallery.addView(button);
+ }
+ }
+
+ private void processViews() {
+ color_gallery = (LinearLayout) findViewById(R.id.color_gallery);
+ }
+
+ private class ColorListener implements OnClickListener {
+
+ @Override
+ public void onClick(View view) {
+ String action = ColorActivity.this.getIntent().getAction();
+
+ // 經由設定元件啟動
+ if (action != null &&
+ action.equals("net.macdidi.myandroidtutorial.CHOOSE_COLOR")) {
+ // 建立SharedPreferences物件
+ SharedPreferences.Editor editor =
+ PreferenceManager.getDefaultSharedPreferences(
+ ColorActivity.this).edit();
+ // 儲存預設顏色
+ editor.putInt("DEFAULT_COLOR", view.getId());
+ // 寫入設定值
+ editor.commit();
+ finish();
+ }
+ // 經由新增或修改記事的元件啟動
+ else {
+ Intent result = getIntent();
+ result.putExtra("colorId", view.getId());
+ setResult(Activity.RESULT_OK, result);
+ finish();
+ }
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0502/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Colors.java b/examples/0502/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Colors.java
new file mode 100644
index 0000000..1462149
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Colors.java
@@ -0,0 +1,24 @@
+package net.macdidi.myandroidtutorial;
+
+import android.graphics.Color;
+
+public enum Colors {
+
+ LIGHTGREY("#D3D3D3"), BLUE("#33B5E5"), PURPLE("#AA66CC"),
+ GREEN("#99CC00"), ORANGE("#FFBB33"), RED("#FF4444");
+
+ private String code;
+
+ private Colors(String code) {
+ this.code = code;
+ }
+
+ public String getCode() {
+ return code;
+ }
+
+ public int parseColor() {
+ return Color.parseColor(code);
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0502/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/FileUtil.java b/examples/0502/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/FileUtil.java
new file mode 100644
index 0000000..1fb41be
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/FileUtil.java
@@ -0,0 +1,112 @@
+package net.macdidi.myandroidtutorial;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.os.Environment;
+import android.util.Log;
+import android.widget.ImageView;
+
+import java.io.File;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+public class FileUtil {
+
+ // 應用程式儲存檔案的目錄
+ public static final String APP_DIR = "androidtutorial";
+
+ // 外部儲存設備是否可寫入
+ public static boolean isExternalStorageWritable() {
+ // 取得目前外部儲存設備的狀態
+ String state = Environment.getExternalStorageState();
+
+ // 判斷是否可寫入
+ if (Environment.MEDIA_MOUNTED.equals(state)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ // 外部儲存設備是否可讀取
+ public static boolean isExternalStorageReadable() {
+ // 取得目前外部儲存設備的狀態
+ String state = Environment.getExternalStorageState();
+
+ // 判斷是否可讀取
+ if (Environment.MEDIA_MOUNTED.equals(state) ||
+ Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ // 建立並傳回在公用相簿下參數指定的路徑
+ public static File getPublicAlbumStorageDir(String albumName) {
+ // 取得公用的照片路徑
+ File pictures = Environment.getExternalStoragePublicDirectory(
+ Environment.DIRECTORY_PICTURES);
+ // 準備在照片路徑下建立一個指定的路徑
+ File file = new File(pictures, albumName);
+
+ // 如果建立路徑不成功
+ if (!file.mkdirs()) {
+ Log.e("getAlbumStorageDir", "Directory not created");
+ }
+
+ return file;
+ }
+
+ // 建立並傳回在應用程式專用相簿下參數指定的路徑
+ public static File getAlbumStorageDir(Context context, String albumName) {
+ // 取得應用程式專用的照片路徑
+ File pictures = context.getExternalFilesDir(
+ Environment.DIRECTORY_PICTURES);
+ // 準備在照片路徑下建立一個指定的路徑
+ File file = new File(pictures, albumName);
+
+ // 如果建立路徑不成功
+ if (!file.mkdirs()) {
+ Log.e("getAlbumStorageDir", "Directory not created");
+ }
+
+ return file;
+ }
+
+ // 建立並傳回外部儲存媒體參數指定的路徑
+ public static File getExternalStorageDir(String dir) {
+ File result = new File(
+ Environment.getExternalStorageDirectory(), dir);
+
+ if (!isExternalStorageWritable()) {
+ return null;
+ }
+
+ if (!result.exists() && !result.mkdirs()) {
+ return null;
+ }
+
+ return result;
+ }
+
+ // 讀取指定的照片檔案名稱設定給ImageView元件
+ public static void fileToImageView(String fileName, ImageView imageView) {
+ if (new File(fileName).exists()) {
+ Bitmap bitmap = BitmapFactory.decodeFile(fileName);
+ imageView.setImageBitmap(bitmap);
+ }
+ else {
+ Log.e("fileToImageView", fileName + " not found.");
+ }
+ }
+
+ // 產生唯一的檔案名稱
+ public static String getUniqueFileName() {
+ // 使用年月日_時分秒格式為檔案名稱
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
+ return sdf.format(new Date());
+ }
+
+}
diff --git a/examples/0502/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/InitAlarmReceiver.java b/examples/0502/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/InitAlarmReceiver.java
new file mode 100644
index 0000000..959785f
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/InitAlarmReceiver.java
@@ -0,0 +1,49 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+import java.util.Calendar;
+import java.util.List;
+
+public class InitAlarmReceiver extends BroadcastReceiver {
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ // 建立資料庫物件
+ ItemDAO itemDAO = new ItemDAO(context.getApplicationContext());
+ // 讀取資料庫所有記事資料
+ List- items = itemDAO.getAll();
+
+ // 讀取目前時間
+ long current = Calendar.getInstance().getTimeInMillis();
+
+ AlarmManager am = (AlarmManager)
+ context.getSystemService(Context.ALARM_SERVICE);
+
+ for (Item item : items) {
+ long alarm = item.getAlarmDatetime();
+
+ // 如果沒有設定提醒或是提醒已經過期
+ if (alarm == 0 || alarm <= current) {
+ continue;
+ }
+
+ // 設定提醒
+ Intent alarmIntent = new Intent(context, AlarmReceiver.class);
+ //alarmIntent.putExtra("title", item.getTitle());
+
+ // 加入記事編號
+ intent.putExtra("id", item.getId());
+
+ PendingIntent pi = PendingIntent.getBroadcast(
+ context, (int)item.getId(),
+ alarmIntent, PendingIntent.FLAG_ONE_SHOT);
+ am.set(AlarmManager.RTC_WAKEUP, item.getAlarmDatetime(), pi);
+ }
+ }
+
+}
diff --git a/examples/0502/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Item.java b/examples/0502/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Item.java
new file mode 100644
index 0000000..6f4e0b2
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Item.java
@@ -0,0 +1,157 @@
+package net.macdidi.myandroidtutorial;
+
+import java.util.Date;
+import java.util.Locale;
+
+public class Item implements java.io.Serializable {
+
+ // 編號、日期時間、顏色、標題、內容、檔案名稱、經緯度、修改、已選擇
+ private long id;
+ private long datetime;
+ private Colors color;
+ private String title;
+ private String content;
+ private String fileName;
+ private String recFileName;
+ private double latitude;
+ private double longitude;
+ private long lastModify;
+ private boolean selected;
+
+ // 提醒日期時間
+ private long alarmDatetime;
+
+ public Item() {
+ title = "";
+ content = "";
+ color = Colors.LIGHTGREY;
+ }
+
+ public Item(long id, long datetime, Colors color, String title,
+ String content, String fileName, String recFileName,
+ double latitude, double longitude, long lastModify) {
+ this.id = id;
+ this.datetime = datetime;
+ this.color = color;
+ this.title = title;
+ this.content = content;
+ this.fileName = fileName;
+ this.recFileName = recFileName;
+ this.latitude = latitude;
+ this.longitude = longitude;
+ this.lastModify = lastModify;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public long getDatetime() {
+ return datetime;
+ }
+
+ // 裝置區域的日期時間
+ public String getLocaleDatetime() {
+ return String.format(Locale.getDefault(), "%tF %
0) {
+ // 照片檔案物件
+ File file = configFileName("P", ".jpg");
+
+ // 如果照片檔案存在
+ if (file.exists()) {
+ // 顯示照片元件
+ picture.setVisibility(View.VISIBLE);
+ // 設定照片
+ FileUtil.fileToImageView(file.getAbsolutePath(), picture);
+ }
+ }
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (resultCode == Activity.RESULT_OK) {
+ switch (requestCode) {
+ // 照像
+ case START_CAMERA:
+ // 設定照片檔案名稱
+ item.setFileName(fileName);
+ break;
+ case START_RECORD:
+ // 設定錄音檔案名稱
+ item.setRecFileName(recFileName);
+ break;
+ case START_LOCATION:
+ // 讀取與設定座標
+ double lat = data.getDoubleExtra("lat", 0.0);
+ double lng = data.getDoubleExtra("lng", 0.0);
+ item.setLatitude(lat);
+ item.setLongitude(lng);
+ break;
+ case START_ALARM:
+ break;
+ // 設定顏色
+ case START_COLOR:
+ int colorId = data.getIntExtra(
+ "colorId", Colors.LIGHTGREY.parseColor());
+ item.setColor(getColors(colorId));
+ break;
+ }
+ }
+ }
+
+ public static Colors getColors(int color) {
+ Colors result = Colors.LIGHTGREY;
+
+ if (color == Colors.BLUE.parseColor()) {
+ result = Colors.BLUE;
+ }
+ else if (color == Colors.PURPLE.parseColor()) {
+ result = Colors.PURPLE;
+ }
+ else if (color == Colors.GREEN.parseColor()) {
+ result = Colors.GREEN;
+ }
+ else if (color == Colors.ORANGE.parseColor()) {
+ result = Colors.ORANGE;
+ }
+ else if (color == Colors.RED.parseColor()) {
+ result = Colors.RED;
+ }
+
+ return result;
+ }
+
+ private void processViews() {
+ title_text = (EditText) findViewById(R.id.title_text);
+ content_text = (EditText) findViewById(R.id.content_text);
+ // 取得顯示照片的ImageView元件
+ picture = (ImageView) findViewById(R.id.picture);
+ }
+
+ // 點擊確定與取消按鈕都會呼叫這個方法
+ public void onSubmit(View view) {
+
+ if (view.getId() == R.id.ok_teim) {
+ String titleText = title_text.getText().toString();
+ String contentText = content_text.getText().toString();
+
+ item.setTitle(titleText);
+ item.setContent(contentText);
+
+ if (getIntent().getAction().equals(
+ "net.macdidi.myandroidtutorial.EDIT_ITEM")) {
+ item.setLastModify(new Date().getTime());
+ }
+ // 新增記事
+ else {
+ item.setDatetime(new Date().getTime());
+ }
+
+ Intent result = getIntent();
+ result.putExtra("net.macdidi.myandroidtutorial.Item", item);
+ setResult(Activity.RESULT_OK, result);
+ }
+
+ // 結束
+ finish();
+ }
+
+ public void clickFunction(View view) {
+ int id = view.getId();
+
+ switch (id) {
+ case R.id.take_picture:
+ // 啟動相機元件用的Intent物件
+ Intent intentCamera =
+ new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
+
+ // 照片檔案名稱
+ File pictureFile = configFileName("P", ".jpg");
+ Uri uri = Uri.fromFile(pictureFile);
+ // 設定檔案名稱
+ intentCamera.putExtra(MediaStore.EXTRA_OUTPUT, uri);
+ // 啟動相機元件
+ startActivityForResult(intentCamera, START_CAMERA);
+ break;
+ case R.id.record_sound:
+ // 錄音檔案名稱
+ final File recordFile = configRecFileName("R", ".mp3");
+
+ // 如果已經有錄音檔,詢問播放或重新錄製
+ if (recordFile.exists()) {
+ // 詢問播放還是重新錄製的對話框
+ AlertDialog.Builder d = new AlertDialog.Builder(this);
+
+ d.setTitle(R.string.title_record)
+ .setCancelable(false);
+ d.setPositiveButton(R.string.record_play,
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ // 播放
+ Intent playIntent = new Intent(
+ ItemActivity.this, PlayActivity.class);
+ playIntent.putExtra("fileName",
+ recordFile.getAbsolutePath());
+ startActivity(playIntent);
+ }
+ });
+ d.setNeutralButton(R.string.record_new,
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ goToRecord(recordFile);
+ }
+ });
+ d.setNegativeButton(android.R.string.cancel, null);
+
+ // 顯示對話框
+ d.show();
+ }
+ // 如果沒有錄音檔,啟動錄音元件
+ else {
+ goToRecord(recordFile);
+ }
+
+ break;
+ case R.id.set_location:
+ // 啟動地圖元件用的Intent物件
+ Intent intentMap = new Intent(this, MapsActivity.class);
+
+ // 設定儲存的座標
+ intentMap.putExtra("lat", item.getLatitude());
+ intentMap.putExtra("lng", item.getLongitude());
+ intentMap.putExtra("title", item.getTitle());
+ intentMap.putExtra("datetime", item.getLocaleDatetime());
+
+ // 啟動地圖元件
+ startActivityForResult(intentMap, START_LOCATION);
+ break;
+ case R.id.set_alarm:
+ // 設定提醒日期時間
+ processSetAlarm();
+ break;
+ case R.id.select_color:
+ // 啟動設定顏色的Activity元件
+ startActivityForResult(
+ new Intent(this, ColorActivity.class), START_COLOR);
+ break;
+ }
+
+ }
+
+ // 設定提醒日期時間
+ private void processSetAlarm() {
+ Calendar calendar = Calendar.getInstance();
+
+ if (item.getAlarmDatetime() != 0) {
+ // 設定為已經儲存的提醒日期時間
+ calendar.setTimeInMillis(item.getAlarmDatetime());
+ }
+
+ // 讀取年、月、日、時、分
+ int year = calendar.get(Calendar.YEAR);
+ int month = calendar.get(Calendar.MONTH);
+ int day = calendar.get(Calendar.DAY_OF_MONTH);
+ int hour = calendar.get(Calendar.HOUR_OF_DAY);
+ int minute = calendar.get(Calendar.MINUTE);
+
+ // 儲存設定的提醒日期時間
+ final Calendar alarm = Calendar.getInstance();
+
+ // 設定提醒時間
+ TimePickerDialog.OnTimeSetListener timeSetListener =
+ new TimePickerDialog.OnTimeSetListener() {
+ @Override
+ public void onTimeSet(TimePicker view,
+ int hourOfDay, int minute) {
+ alarm.set(Calendar.HOUR_OF_DAY, hourOfDay);
+ alarm.set(Calendar.MINUTE, minute);
+
+ item.setAlarmDatetime(alarm.getTimeInMillis());
+ }
+ };
+
+ // 選擇時間對話框
+ final TimePickerDialog tpd = new TimePickerDialog(
+ this, timeSetListener, hour, minute, true);
+
+ // 設定提醒日期
+ DatePickerDialog.OnDateSetListener dateSetListener =
+ new DatePickerDialog.OnDateSetListener() {
+ @Override
+ public void onDateSet(DatePicker view,
+ int year,
+ int monthOfYear,
+ int dayOfMonth) {
+ alarm.set(Calendar.YEAR, year);
+ alarm.set(Calendar.MONTH, monthOfYear);
+ alarm.set(Calendar.DAY_OF_MONTH, dayOfMonth);
+
+ // 繼續選擇提醒時間
+ tpd.show();
+ }
+ };
+
+ // 建立與顯示選擇日期對話框
+ final DatePickerDialog dpd = new DatePickerDialog(
+ this, dateSetListener, year, month, day);
+ dpd.show();
+ }
+
+ private void goToRecord(File recordFile) {
+ // 錄音
+ Intent recordIntent = new Intent(this, RecordActivity.class);
+ recordIntent.putExtra("fileName", recordFile.getAbsolutePath());
+ startActivityForResult(recordIntent, START_RECORD);
+ }
+
+ private File configFileName(String prefix, String extension) {
+ // 如果記事資料已經有檔案名稱
+ if (item.getFileName() != null && item.getFileName().length() > 0) {
+ fileName = item.getFileName();
+ }
+ // 產生檔案名稱
+ else {
+ fileName = FileUtil.getUniqueFileName();
+ }
+
+ return new File(FileUtil.getExternalStorageDir(FileUtil.APP_DIR),
+ prefix + fileName + extension);
+ }
+
+ private File configRecFileName(String prefix, String extension) {
+ // 如果記事資料已經有檔案名稱
+ if (item.getRecFileName() != null && item.getRecFileName().length() > 0) {
+ recFileName = item.getRecFileName();
+ }
+ // 產生檔案名稱
+ else {
+ recFileName = FileUtil.getUniqueFileName();
+ }
+
+ return new File(FileUtil.getExternalStorageDir(FileUtil.APP_DIR),
+ prefix + recFileName + extension);
+ }
+
+}
diff --git a/examples/0502/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemAdapter.java b/examples/0502/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemAdapter.java
new file mode 100644
index 0000000..85b40ba
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemAdapter.java
@@ -0,0 +1,80 @@
+package net.macdidi.myandroidtutorial;
+
+import android.content.Context;
+import android.graphics.drawable.GradientDrawable;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+import java.util.List;
+
+public class ItemAdapter extends ArrayAdapter- {
+
+ // 畫面資源編號
+ private int resource;
+ // 包裝的記事資料
+ private List
- items;
+
+ public ItemAdapter(Context context, int resource, List
- items) {
+ super(context, resource, items);
+ this.resource = resource;
+ this.items = items;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ LinearLayout itemView;
+ // 讀取目前位置的記事物件
+ final Item item = getItem(position);
+
+ if (convertView == null) {
+ // 建立項目畫面元件
+ itemView = new LinearLayout(getContext());
+ String inflater = Context.LAYOUT_INFLATER_SERVICE;
+ LayoutInflater li = (LayoutInflater)
+ getContext().getSystemService(inflater);
+ li.inflate(resource, itemView, true);
+ }
+ else {
+ itemView = (LinearLayout) convertView;
+ }
+
+ // 讀取記事顏色、已選擇、標題與日期時間元件
+ RelativeLayout typeColor = (RelativeLayout) itemView.findViewById(R.id.type_color);
+ ImageView selectedItem = (ImageView) itemView.findViewById(R.id.selected_item);
+ TextView titleView = (TextView) itemView.findViewById(R.id.title_text);
+ TextView dateView = (TextView) itemView.findViewById(R.id.date_text);
+
+ // 設定記事顏色
+ GradientDrawable background = (GradientDrawable)typeColor.getBackground();
+ background.setColor(item.getColor().parseColor());
+
+ // 設定標題與日期時間
+ titleView.setText(item.getTitle());
+ dateView.setText(item.getLocaleDatetime());
+
+ // 設定是否已選擇
+ selectedItem.setVisibility(item.isSelected() ? View.VISIBLE : View.INVISIBLE);
+
+ return itemView;
+ }
+
+ // 設定指定編號的記事資料
+ public void set(int index, Item item) {
+ if (index >= 0 && index < items.size()) {
+ items.set(index, item);
+ notifyDataSetChanged();
+ }
+ }
+
+ // 讀取指定編號的記事資料
+ public Item get(int index) {
+ return items.get(index);
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0502/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemDAO.java b/examples/0502/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemDAO.java
new file mode 100644
index 0000000..6e5b007
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemDAO.java
@@ -0,0 +1,214 @@
+package net.macdidi.myandroidtutorial;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+// 資料功能類別
+public class ItemDAO {
+ // 表格名稱
+ public static final String TABLE_NAME = "item";
+
+ // 編號表格欄位名稱,固定不變
+ public static final String KEY_ID = "_id";
+
+ // 其它表格欄位名稱
+ public static final String DATETIME_COLUMN = "datetime";
+ public static final String COLOR_COLUMN = "color";
+ public static final String TITLE_COLUMN = "title";
+ public static final String CONTENT_COLUMN = "content";
+ public static final String FILENAME_COLUMN = "filename";
+ public static final String RECFILENAME_COLUMN = "recfilename";
+ public static final String LATITUDE_COLUMN = "latitude";
+ public static final String LONGITUDE_COLUMN = "longitude";
+ public static final String LASTMODIFY_COLUMN = "lastmodify";
+
+ // 提醒日期時間
+ public static final String ALARMDATETIME_COLUMN = "alarmdatetime";
+
+ // 使用上面宣告的變數建立表格的SQL指令
+ public static final String CREATE_TABLE =
+ "CREATE TABLE " + TABLE_NAME + " (" +
+ KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
+ DATETIME_COLUMN + " INTEGER NOT NULL, " +
+ COLOR_COLUMN + " INTEGER NOT NULL, " +
+ TITLE_COLUMN + " TEXT NOT NULL, " +
+ CONTENT_COLUMN + " TEXT NOT NULL, " +
+ FILENAME_COLUMN + " TEXT, " +
+ RECFILENAME_COLUMN + " TEXT, " +
+ LATITUDE_COLUMN + " REAL, " +
+ LONGITUDE_COLUMN + " REAL, " +
+ LASTMODIFY_COLUMN + " INTEGER, " +
+ ALARMDATETIME_COLUMN + " INTEGER)";
+
+ // 資料庫物件
+ private SQLiteDatabase db;
+
+ // 建構子,一般的應用都不需要修改
+ public ItemDAO(Context context) {
+ db = MyDBHelper.getDatabase(context);
+ }
+
+ // 關閉資料庫,一般的應用都不需要修改
+ public void close() {
+ db.close();
+ }
+
+ // 新增參數指定的物件
+ public Item insert(Item item) {
+ // 建立準備新增資料的ContentValues物件
+ ContentValues cv = new ContentValues();
+
+ // 加入ContentValues物件包裝的新增資料
+ // 第一個參數是欄位名稱, 第二個參數是欄位的資料
+ cv.put(DATETIME_COLUMN, item.getDatetime());
+ cv.put(COLOR_COLUMN, item.getColor().parseColor());
+ cv.put(TITLE_COLUMN, item.getTitle());
+ cv.put(CONTENT_COLUMN, item.getContent());
+ cv.put(FILENAME_COLUMN, item.getFileName());
+ cv.put(RECFILENAME_COLUMN, item.getRecFileName());
+ cv.put(LATITUDE_COLUMN, item.getLatitude());
+ cv.put(LONGITUDE_COLUMN, item.getLongitude());
+ cv.put(LASTMODIFY_COLUMN, item.getLastModify());
+
+ // 提醒日期時間
+ cv.put(ALARMDATETIME_COLUMN, item.getAlarmDatetime());
+
+ // 新增一筆資料並取得編號
+ // 第一個參數是表格名稱
+ // 第二個參數是沒有指定欄位值的預設值
+ // 第三個參數是包裝新增資料的ContentValues物件
+ long id = db.insert(TABLE_NAME, null, cv);
+
+ // 設定編號
+ item.setId(id);
+ // 回傳結果
+ return item;
+ }
+
+ // 修改參數指定的物件
+ public boolean update(Item item) {
+ // 建立準備修改資料的ContentValues物件
+ ContentValues cv = new ContentValues();
+
+ // 加入ContentValues物件包裝的修改資料
+ // 第一個參數是欄位名稱, 第二個參數是欄位的資料
+ cv.put(DATETIME_COLUMN, item.getDatetime());
+ cv.put(COLOR_COLUMN, item.getColor().parseColor());
+ cv.put(TITLE_COLUMN, item.getTitle());
+ cv.put(CONTENT_COLUMN, item.getContent());
+ cv.put(FILENAME_COLUMN, item.getFileName());
+ cv.put(RECFILENAME_COLUMN, item.getRecFileName());
+ cv.put(LATITUDE_COLUMN, item.getLatitude());
+ cv.put(LONGITUDE_COLUMN, item.getLongitude());
+ cv.put(LASTMODIFY_COLUMN, item.getLastModify());
+
+ // 提醒日期時間
+ cv.put(ALARMDATETIME_COLUMN, item.getAlarmDatetime());
+
+ // 設定修改資料的條件為編號
+ // 格式為「欄位名稱=資料」
+ String where = KEY_ID + "=" + item.getId();
+
+ // 執行修改資料並回傳修改的資料數量是否成功
+ return db.update(TABLE_NAME, cv, where, null) > 0;
+ }
+
+ // 刪除參數指定編號的資料
+ public boolean delete(long id){
+ // 設定條件為編號,格式為「欄位名稱=資料」
+ String where = KEY_ID + "=" + id;
+ // 刪除指定編號資料並回傳刪除是否成功
+ return db.delete(TABLE_NAME, where , null) > 0;
+ }
+
+ // 讀取所有記事資料
+ public List
- getAll() {
+ List
- result = new ArrayList<>();
+ Cursor cursor = db.query(
+ TABLE_NAME, null, null, null, null, null, null, null);
+
+ while (cursor.moveToNext()) {
+ result.add(getRecord(cursor));
+ }
+
+ cursor.close();
+ return result;
+ }
+
+ // 取得指定編號的資料物件
+ public Item get(long id) {
+ // 準備回傳結果用的物件
+ Item item = null;
+ // 使用編號為查詢條件
+ String where = KEY_ID + "=" + id;
+ // 執行查詢
+ Cursor result = db.query(
+ TABLE_NAME, null, where, null, null, null, null, null);
+
+ // 如果有查詢結果
+ if (result.moveToFirst()) {
+ // 讀取包裝一筆資料的物件
+ item = getRecord(result);
+ }
+
+ // 關閉Cursor物件
+ result.close();
+ // 回傳結果
+ return item;
+ }
+
+ // 把Cursor目前的資料包裝為物件
+ public Item getRecord(Cursor cursor) {
+ // 準備回傳結果用的物件
+ Item result = new Item();
+
+ result.setId(cursor.getLong(0));
+ result.setDatetime(cursor.getLong(1));
+ result.setColor(ItemActivity.getColors(cursor.getInt(2)));
+ result.setTitle(cursor.getString(3));
+ result.setContent(cursor.getString(4));
+ result.setFileName(cursor.getString(5));
+ result.setRecFileName(cursor.getString(6));
+ result.setLatitude(cursor.getDouble(7));
+ result.setLongitude(cursor.getDouble(8));
+ result.setLastModify(cursor.getLong(9));
+
+ // 提醒日期時間
+ result.setAlarmDatetime(cursor.getLong(10));
+
+ // 回傳結果
+ return result;
+ }
+
+ // 取得資料數量
+ public int getCount() {
+ int result = 0;
+ Cursor cursor = db.rawQuery("SELECT COUNT(*) FROM " + TABLE_NAME, null);
+
+ if (cursor.moveToNext()) {
+ result = cursor.getInt(0);
+ }
+
+ return result;
+ }
+
+ // 建立範例資料
+ public void sample() {
+ Item item = new Item(0, new Date().getTime(), Colors.RED, "關於Android Tutorial的事情.", "Hello content", "", "", 0, 0, 0);
+ Item item2 = new Item(0, new Date().getTime(), Colors.BLUE, "一隻非常可愛的小狗狗!", "她的名字叫「大熱狗」,又叫\n作「奶嘴」,是一隻非常可愛\n的小狗。", "", "", 25.04719, 121.516981, 0);
+ Item item3 = new Item(0, new Date().getTime(), Colors.GREEN, "一首非常好聽的音樂!", "Hello content", "", "", 0, 0, 0);
+ Item item4 = new Item(0, new Date().getTime(), Colors.ORANGE, "儲存在資料庫的資料", "Hello content", "", "", 0, 0, 0);
+
+ insert(item);
+ insert(item2);
+ insert(item3);
+ insert(item4);
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0502/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MainActivity.java b/examples/0502/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MainActivity.java
new file mode 100644
index 0000000..899ddfe
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MainActivity.java
@@ -0,0 +1,330 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.app.AlarmManager;
+import android.app.AlertDialog;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.v7.app.ActionBarActivity;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import java.util.List;
+
+public class MainActivity extends ActionBarActivity {
+ private ListView item_list;
+ private TextView show_app_name;
+
+ // ListView使用的自定Adapter物件
+ private ItemAdapter itemAdapter;
+ // 儲存所有記事本的List物件
+ private List
- items;
+
+ // 選單項目物件
+ private MenuItem add_item, search_item, revert_item, share_item, delete_item;
+
+ // 已選擇項目數量
+ private int selectedCount = 0;
+
+ // 宣告資料庫功能類別欄位變數
+ private ItemDAO itemDAO;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ processViews();
+ processControllers();
+
+ // 建立資料庫物件
+ itemDAO = new ItemDAO(getApplicationContext());
+
+ // 如果資料庫是空的,就建立一些範例資料
+ // 這是為了方便測試用的,完成應用程式以後可以拿掉
+ if (itemDAO.getCount() == 0) {
+ itemDAO.sample();
+ }
+
+ // 取得所有記事資料
+ items = itemDAO.getAll();
+
+ itemAdapter = new ItemAdapter(this, R.layout.single_item, items);
+ item_list.setAdapter(itemAdapter);
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (resultCode == Activity.RESULT_OK) {
+ Item item = (Item) data.getExtras().getSerializable(
+ "net.macdidi.myandroidtutorial.Item");
+
+ // 是否修改提醒設定
+ boolean updateAlarm = false;
+
+ if (requestCode == 0) {
+ // 新增記事資料到資料庫
+ item = itemDAO.insert(item);
+
+ items.add(item);
+ itemAdapter.notifyDataSetChanged();
+ }
+ else if (requestCode == 1) {
+ int position = data.getIntExtra("position", -1);
+
+ if (position != -1) {
+ // 讀取原來的提醒設定
+ Item ori = itemDAO.get(item.getId());
+ // 判斷是否需要設定提醒
+ updateAlarm = (item.getAlarmDatetime() != ori.getAlarmDatetime());
+
+ // 修改資料庫中的記事資料
+ itemDAO.update(item);
+
+ items.set(position, item);
+ itemAdapter.notifyDataSetChanged();
+ }
+ }
+
+ // 設定提醒
+ if (item.getAlarmDatetime() != 0 && updateAlarm) {
+ Intent intent = new Intent(this, AlarmReceiver.class);
+ //intent.putExtra("title", item.getTitle());
+
+ // 加入記事編號
+ intent.putExtra("id", item.getId());
+
+ PendingIntent pi = PendingIntent.getBroadcast(
+ this, (int)item.getId(),
+ intent, PendingIntent.FLAG_ONE_SHOT);
+
+ AlarmManager am = (AlarmManager)
+ getSystemService(Context.ALARM_SERVICE);
+ am.set(AlarmManager.RTC_WAKEUP, item.getAlarmDatetime(), pi);
+ }
+ }
+ }
+
+ private void processViews() {
+ item_list = (ListView)findViewById(R.id.item_list);
+ show_app_name = (TextView) findViewById(R.id.show_app_name);
+ }
+
+ private void processControllers() {
+
+ // 建立選單項目點擊監聽物件
+ AdapterView.OnItemClickListener itemListener = new AdapterView.OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView> parent, View view,
+ int position, long id) {
+ // 讀取選擇的記事物件
+ Item item = itemAdapter.getItem(position);
+
+ // 如果已經有勾選的項目
+ if (selectedCount > 0) {
+ // 處理是否顯示已選擇項目
+ processMenu(item);
+ // 重新設定記事項目
+ itemAdapter.set(position, item);
+ }
+ else {
+ Intent intent = new Intent(
+ "net.macdidi.myandroidtutorial.EDIT_ITEM");
+
+ // 設定記事編號與記事物件
+ intent.putExtra("position", position);
+ intent.putExtra("net.macdidi.myandroidtutorial.Item", item);
+
+ startActivityForResult(intent, 1);
+ }
+ }
+ };
+
+ // 註冊選單項目點擊監聽物件
+ item_list.setOnItemClickListener(itemListener);
+
+ // 建立記事項目長按監聽物件
+ AdapterView.OnItemLongClickListener itemLongListener = new AdapterView.OnItemLongClickListener() {
+ @Override
+ public boolean onItemLongClick(AdapterView> parent, View view,
+ int position, long id) {
+ // 讀取選擇的記事物件
+ Item item = itemAdapter.getItem(position);
+ // 處理是否顯示已選擇項目
+ processMenu(item);
+ // 重新設定記事項目
+ itemAdapter.set(position, item);
+ return true;
+ }
+ };
+
+ // 註冊記事項目長按監聽物件
+ item_list.setOnItemLongClickListener(itemLongListener);
+
+ // 建立長按監聽物件
+ View.OnLongClickListener listener = new View.OnLongClickListener() {
+
+ @Override
+ public boolean onLongClick(View view) {
+ AlertDialog.Builder dialog =
+ new AlertDialog.Builder(MainActivity.this);
+ dialog.setTitle(R.string.app_name)
+ .setMessage(R.string.about)
+ .show();
+ return false;
+ }
+
+ };
+
+ // 註冊長按監聽物件
+ show_app_name.setOnLongClickListener(listener);
+ }
+
+ // 處理是否顯示已選擇項目
+ private void processMenu(Item item) {
+ // 如果需要設定記事項目
+ if (item != null) {
+ // 設定已勾選的狀態
+ item.setSelected(!item.isSelected());
+
+ // 計算已勾選數量
+ if (item.isSelected()) {
+ selectedCount++;
+ }
+ else {
+ selectedCount--;
+ }
+ }
+
+ // 根據選擇的狀況,設定是否顯示選單項目
+ add_item.setVisible(selectedCount == 0);
+ search_item.setVisible(selectedCount == 0);
+ revert_item.setVisible(selectedCount > 0);
+ share_item.setVisible(selectedCount > 0);
+ delete_item.setVisible(selectedCount > 0);
+ }
+
+ // 載入選單資源
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ MenuInflater menuInflater = getMenuInflater();
+ menuInflater.inflate(R.menu.menu_main, menu);
+
+ // 取得選單項目物件
+ add_item = menu.findItem(R.id.add_item);
+ search_item = menu.findItem(R.id.search_item);
+ revert_item = menu.findItem(R.id.revert_item);
+ share_item = menu.findItem(R.id.share_item);
+ delete_item = menu.findItem(R.id.delete_item);
+
+ // 設定選單項目
+ processMenu(null);
+
+ return true;
+ }
+
+ // 使用者選擇所有的選單項目都會呼叫這個方法
+ public void clickMenuItem(MenuItem item) {
+ // 使用參數取得使用者選擇的選單項目元件編號
+ int itemId = item.getItemId();
+
+ // 判斷該執行什麼工作,目前還沒有加入需要執行的工作
+ switch (itemId) {
+ case R.id.search_item:
+ break;
+ // 使用者選擇新增選單項目
+ case R.id.add_item:
+ // 使用Action名稱建立啟動另一個Activity元件需要的Intent物件
+ Intent intent = new Intent("net.macdidi.myandroidtutorial.ADD_ITEM");
+ // 呼叫「startActivityForResult」,,第二個參數「0」表示執行新增
+ startActivityForResult(intent, 0);
+ break;
+ // 取消所有已勾選的項目
+ case R.id.revert_item:
+ for (int i = 0; i < itemAdapter.getCount(); i++) {
+ Item ri = itemAdapter.getItem(i);
+
+ if (ri.isSelected()) {
+ ri.setSelected(false);
+ itemAdapter.set(i, ri);
+ }
+ }
+
+ selectedCount = 0;
+ processMenu(null);
+
+ break;
+ // 刪除
+ case R.id.delete_item:
+ if (selectedCount == 0) {
+ break;
+ }
+
+ AlertDialog.Builder d = new AlertDialog.Builder(this);
+ String message = getString(R.string.delete_item);
+ d.setTitle(R.string.delete)
+ .setMessage(String.format(message, selectedCount));
+ d.setPositiveButton(android.R.string.yes,
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ // 取得最後一個元素的編號
+ int index = itemAdapter.getCount() - 1;
+
+ while (index > -1) {
+ Item item = itemAdapter.get(index);
+
+ if (item.isSelected()) {
+ itemAdapter.remove(item);
+ // 刪除資料庫中的記事資料
+ itemDAO.delete(item.getId());
+ }
+
+ index--;
+ }
+
+ itemAdapter.notifyDataSetChanged();
+ selectedCount = 0;
+ processMenu(null);
+ }
+ });
+ d.setNegativeButton(android.R.string.no, null);
+ d.show();
+
+ break;
+ case R.id.googleplus_item:
+ break;
+ case R.id.facebook_item:
+ break;
+ }
+
+ }
+
+ // 方法名稱與onClick的設定一樣,參數的型態是android.view.View
+ public void aboutApp(View view) {
+ // 建立啟動另一個Activity元件需要的Intent物件
+ // 建構式的第一個參數:「this」
+ // 建構式的第二個參數:「Activity元件類別名稱.class」
+ Intent intent = new Intent(this, AboutActivity.class);
+ // 呼叫「startActivity」,參數為一個建立好的Intent物件
+ // 這行敘述執行以後,如果沒有任何錯誤,就會啟動指定的元件
+ startActivity(intent);
+ }
+
+ // 設定
+ public void clickPreferences(MenuItem item) {
+ // 啟動設定元件
+ startActivity(new Intent(this, PrefActivity.class));
+ }
+
+}
+
+
diff --git a/examples/0502/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MapsActivity.java b/examples/0502/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MapsActivity.java
new file mode 100644
index 0000000..abab911
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MapsActivity.java
@@ -0,0 +1,338 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.location.Location;
+import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
+import android.widget.Toast;
+
+import com.google.android.gms.common.ConnectionResult;
+import com.google.android.gms.common.api.GoogleApiClient;
+import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
+import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
+
+import com.google.android.gms.location.LocationListener;
+import com.google.android.gms.location.LocationRequest;
+import com.google.android.gms.location.LocationServices;
+
+import com.google.android.gms.maps.CameraUpdateFactory;
+import com.google.android.gms.maps.GoogleMap;
+import com.google.android.gms.maps.SupportMapFragment;
+import com.google.android.gms.maps.model.BitmapDescriptor;
+import com.google.android.gms.maps.model.BitmapDescriptorFactory;
+import com.google.android.gms.maps.model.CameraPosition;
+import com.google.android.gms.maps.model.LatLng;
+import com.google.android.gms.maps.model.Marker;
+import com.google.android.gms.maps.model.MarkerOptions;
+
+public class MapsActivity extends FragmentActivity
+ implements ConnectionCallbacks,
+ OnConnectionFailedListener,
+ LocationListener {
+
+ private GoogleMap mMap;
+
+ // Google API用戶端物件
+ private GoogleApiClient googleApiClient;
+
+ // Location請求物件
+ private LocationRequest locationRequest;
+
+ // 記錄目前最新的位置
+ private Location currentLocation;
+
+ // 顯示目前與儲存位置的標記物件
+ private Marker currentMarker, itemMarker;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_maps);
+ setUpMapIfNeeded();
+
+ // 建立Google API用戶端物件
+ configGoogleApiClient();
+
+ // 建立Location請求物件
+ configLocationRequest();
+
+ // 讀取記事儲存的座標
+ Intent intent = getIntent();
+ double lat = intent.getDoubleExtra("lat", 0.0);
+ double lng = intent.getDoubleExtra("lng", 0.0);
+
+ // 如果記事已經儲存座標
+ if (lat != 0.0 && lng != 0.0) {
+ // 建立座標物件
+ LatLng itemPlace = new LatLng(lat, lng);
+ // 加入地圖標記
+ addMarker(itemPlace, intent.getStringExtra("title"),
+ intent.getStringExtra("datetime"));
+ // 移動地圖
+ moveMap(itemPlace);
+ }
+ else {
+ // 連線到Google API用戶端
+ if (!googleApiClient.isConnected()) {
+ googleApiClient.connect();
+ }
+ }
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ setUpMapIfNeeded();
+
+ // 連線到Google API用戶端
+ if (!googleApiClient.isConnected() && currentMarker != null) {
+ googleApiClient.connect();
+ }
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+
+ // 移除位置請求服務
+ if (googleApiClient.isConnected()) {
+ LocationServices.FusedLocationApi.removeLocationUpdates(
+ googleApiClient, this);
+ }
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+
+ // 移除Google API用戶端連線
+ if (googleApiClient.isConnected()) {
+ googleApiClient.disconnect();
+ }
+ }
+
+ // 建立Google API用戶端物件
+ private synchronized void configGoogleApiClient() {
+ googleApiClient = new GoogleApiClient.Builder(this)
+ .addConnectionCallbacks(this)
+ .addOnConnectionFailedListener(this)
+ .addApi(LocationServices.API)
+ .build();
+ }
+
+ // 建立Location請求物件
+ private void configLocationRequest() {
+ locationRequest = new LocationRequest();
+ // 設定讀取位置資訊的間隔時間為一秒(1000ms)
+ locationRequest.setInterval(1000);
+ // 設定讀取位置資訊最快的間隔時間為一秒(1000ms)
+ locationRequest.setFastestInterval(1000);
+ // 設定優先讀取高精確度的位置資訊(GPS)
+ locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
+ }
+
+ private void setUpMapIfNeeded() {
+ if (mMap == null) {
+ mMap = ((SupportMapFragment) getSupportFragmentManager().
+ findFragmentById(R.id.map)).getMap();
+
+ if (mMap != null) {
+ // 移除地圖設定
+ //setUpMap();
+ processController();
+ }
+ }
+ }
+
+ // 移除地圖設定方法
+ private void setUpMap() {
+ // 建立位置的座標物件
+ LatLng place = new LatLng(25.033408, 121.564099);
+ // 移動地圖
+ moveMap(place);
+
+ // 加入地圖標記
+ addMarker(place, "Hello!", " Google Maps v2!");
+ }
+
+ private void processController() {
+ // 對話框按鈕事件
+ final DialogInterface.OnClickListener listener =
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ switch (which) {
+ // 更新位置資訊
+ case DialogInterface.BUTTON_POSITIVE:
+ // 連線到Google API用戶端
+ if (!googleApiClient.isConnected()) {
+ googleApiClient.connect();
+ }
+ break;
+ // 清除位置資訊
+ case DialogInterface.BUTTON_NEUTRAL:
+ Intent result = new Intent();
+ result.putExtra("lat", 0);
+ result.putExtra("lng", 0);
+ setResult(Activity.RESULT_OK, result);
+ finish();
+ break;
+ // 取消
+ case DialogInterface.BUTTON_NEGATIVE:
+ break;
+ }
+ }
+ };
+
+ // 標記訊息框點擊事件
+ mMap.setOnInfoWindowClickListener(new GoogleMap.OnInfoWindowClickListener() {
+ @Override
+ public void onInfoWindowClick(Marker marker) {
+ // 如果是記事儲存的標記
+ if (marker.equals(itemMarker)) {
+ AlertDialog.Builder ab = new AlertDialog.Builder(MapsActivity.this);
+
+ ab.setTitle(R.string.title_update_location)
+ .setMessage(R.string.message_update_location)
+ .setCancelable(true);
+
+ ab.setPositiveButton(R.string.update, listener);
+ ab.setNeutralButton(R.string.clear, listener);
+ ab.setNegativeButton(android.R.string.cancel, listener);
+
+ ab.show();
+ }
+ }
+ });
+
+ // 標記點擊事件
+ mMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
+ @Override
+ public boolean onMarkerClick(Marker marker) {
+ // 如果是目前位置標記
+ if (marker.equals(currentMarker)) {
+ AlertDialog.Builder ab = new AlertDialog.Builder(MapsActivity.this);
+
+ ab.setTitle(R.string.title_current_location)
+ .setMessage(R.string.message_current_location)
+ .setCancelable(true);
+
+ ab.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ Intent result = new Intent();
+ result.putExtra("lat", currentLocation.getLatitude());
+ result.putExtra("lng", currentLocation.getLongitude());
+ setResult(Activity.RESULT_OK, result);
+ finish();
+ }
+ });
+ ab.setNegativeButton(android.R.string.cancel, null);
+
+ ab.show();
+
+ return true;
+ }
+
+ return false;
+ }
+ });
+ }
+
+ // 移動地圖到參數指定的位置
+ private void moveMap(LatLng place) {
+ // 建立地圖攝影機的位置物件
+ CameraPosition cameraPosition =
+ new CameraPosition.Builder()
+ .target(place)
+ .zoom(17)
+ .build();
+
+ // 使用動畫的效果移動地圖
+ mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition),
+ new GoogleMap.CancelableCallback() {
+ @Override
+ public void onFinish() {
+ if (itemMarker != null) {
+ itemMarker.showInfoWindow();
+ }
+ }
+
+ @Override
+ public void onCancel() {
+
+ }
+ });
+ }
+
+ // 在地圖加入指定位置與標題的標記
+ private void addMarker(LatLng place, String title, String snippet) {
+ BitmapDescriptor icon =
+ BitmapDescriptorFactory.fromResource(R.drawable.ic_launcher);
+
+ MarkerOptions markerOptions = new MarkerOptions();
+ markerOptions.position(place)
+ .title(title)
+ .snippet(snippet)
+ .icon(icon);
+
+ // 加入並設定記事儲存的位置標記
+ itemMarker = mMap.addMarker(markerOptions);
+ }
+
+ // ConnectionCallbacks
+ @Override
+ public void onConnected(Bundle bundle) {
+ // 已經連線到Google Services
+ // 啟動位置更新服務
+ // 位置資訊更新的時候,應用程式會自動呼叫LocationListener.onLocationChanged
+ LocationServices.FusedLocationApi.requestLocationUpdates(
+ googleApiClient, locationRequest, MapsActivity.this);
+ }
+
+ // ConnectionCallbacks
+ @Override
+ public void onConnectionSuspended(int i) {
+ // Google Services連線中斷
+ // int參數是連線中斷的代號
+ }
+
+ // OnConnectionFailedListener
+ @Override
+ public void onConnectionFailed(ConnectionResult connectionResult) {
+ // Google Services連線失敗
+ // ConnectionResult參數是連線失敗的資訊
+ int errorCode = connectionResult.getErrorCode();
+
+ // 裝置沒有安裝Google Play服務
+ if (errorCode == ConnectionResult.SERVICE_MISSING) {
+ Toast.makeText(this, R.string.google_play_service_missing,
+ Toast.LENGTH_LONG).show();
+ }
+ }
+
+ // LocationListener
+ @Override
+ public void onLocationChanged(Location location) {
+ // 位置改變
+ // Location參數是目前的位置
+ currentLocation = location;
+ LatLng latLng = new LatLng(
+ location.getLatitude(), location.getLongitude());
+
+ // 設定目前位置的標記
+ if (currentMarker == null) {
+ currentMarker = mMap.addMarker(new MarkerOptions().position(latLng));
+ }
+ else {
+ currentMarker.setPosition(latLng);
+ }
+
+ // 移動地圖到目前的位置
+ moveMap(latLng);
+ }
+
+}
diff --git a/examples/0502/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MyDBHelper.java b/examples/0502/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MyDBHelper.java
new file mode 100644
index 0000000..9350577
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MyDBHelper.java
@@ -0,0 +1,47 @@
+package net.macdidi.myandroidtutorial;
+
+import android.content.Context;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteDatabase.CursorFactory;
+import android.database.sqlite.SQLiteOpenHelper;
+
+public class MyDBHelper extends SQLiteOpenHelper {
+
+ // 資料庫名稱
+ public static final String DATABASE_NAME = "mydata.db";
+ // 資料庫版本,資料結構改變的時候要更改這個數字,通常是加一
+ public static final int VERSION = 3;
+ // 資料庫物件,固定的欄位變數
+ private static SQLiteDatabase database;
+
+ // 建構子,在一般的應用都不需要修改
+ public MyDBHelper(Context context, String name, CursorFactory factory,
+ int version) {
+ super(context, name, factory, version);
+ }
+
+ // 需要資料庫的元件呼叫這個方法,這個方法在一般的應用都不需要修改
+ public static SQLiteDatabase getDatabase(Context context) {
+ if (database == null || !database.isOpen()) {
+ database = new MyDBHelper(context, DATABASE_NAME,
+ null, VERSION).getWritableDatabase();
+ }
+
+ return database;
+ }
+
+ @Override
+ public void onCreate(SQLiteDatabase db) {
+ // 建立應用程式需要的表格
+ db.execSQL(ItemDAO.CREATE_TABLE);
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ // 刪除原有的表格
+ db.execSQL("DROP TABLE IF EXISTS " + ItemDAO.TABLE_NAME);
+ // 呼叫onCreate建立新版的表格
+ onCreate(db);
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0502/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PlayActivity.java b/examples/0502/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PlayActivity.java
new file mode 100644
index 0000000..5cfb523
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PlayActivity.java
@@ -0,0 +1,64 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.media.MediaPlayer;
+import android.net.Uri;
+import android.os.Bundle;
+import android.view.View;
+
+public class PlayActivity extends Activity {
+
+ private MediaPlayer mediaPlayer;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_play);
+
+ Intent intent = getIntent();
+ String fileName = intent.getStringExtra("fileName");
+
+ // 建立指定資源的MediaPlayer物件
+ Uri uri = Uri.parse(fileName);
+ mediaPlayer = MediaPlayer.create(this, uri);
+ }
+
+ @Override
+ protected void onStop() {
+ if (mediaPlayer.isPlaying()) {
+ // 停止播放
+ mediaPlayer.stop();
+ }
+
+ // 清除MediaPlayer物件
+ mediaPlayer.release();
+ super.onStop();
+ }
+
+ public void onSubmit(View view) {
+ // 結束Activity元件
+ finish();
+ }
+
+ public void clickPlay(View view) {
+ // 開始播放
+ mediaPlayer.start();
+ }
+
+ public void clickPause(View view) {
+ // 暫停播放
+ mediaPlayer.pause();
+ }
+
+ public void clickStop(View view) {
+ // 停止播放
+ if (mediaPlayer.isPlaying()) {
+ mediaPlayer.stop();
+ }
+
+ // 回到開始的位置
+ mediaPlayer.seekTo(0);
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0502/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PrefActivity.java b/examples/0502/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PrefActivity.java
new file mode 100644
index 0000000..b2dcc4a
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PrefActivity.java
@@ -0,0 +1,38 @@
+package net.macdidi.myandroidtutorial;
+
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceManager;
+
+public class PrefActivity extends PreferenceActivity {
+
+ private SharedPreferences sharedPreferences;
+ private Preference defaultColor;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ // 指定使用的設定畫面配置資源
+ addPreferencesFromResource(R.xml.mypreference);
+ defaultColor = (Preference)findPreference("DEFAULT_COLOR");
+ // 建立SharedPreferences物件
+ sharedPreferences =
+ PreferenceManager.getDefaultSharedPreferences(this);
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ // 讀取設定的預設顏色
+ int color = sharedPreferences.getInt("DEFAULT_COLOR", -1);
+
+ if (color != -1) {
+ // 設定顏色說明
+ defaultColor.setSummary(getString(R.string.default_color_summary) +
+ ": " + ItemActivity.getColors(color));
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0502/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/RecordActivity.java b/examples/0502/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/RecordActivity.java
new file mode 100644
index 0000000..62b5e93
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/RecordActivity.java
@@ -0,0 +1,180 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.media.MediaRecorder;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.widget.ImageButton;
+import android.widget.ProgressBar;
+
+import java.io.IOException;
+
+public class RecordActivity extends Activity {
+
+ private ImageButton record_button;
+ private boolean isRecording = false;
+ private ProgressBar record_volumn;
+
+ private MyRecoder myRecoder;
+
+ private String fileName;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_record);
+
+ processViews();
+
+ // 讀取檔案名稱
+ Intent intent = getIntent();
+ fileName = intent.getStringExtra("fileName");
+ }
+
+ public void onSubmit(View view) {
+ if (isRecording) {
+ // 停止錄音
+ myRecoder.stop();
+ }
+
+ // 確定
+ if (view.getId() == R.id.record_ok) {
+ Intent result = getIntent();
+ setResult(Activity.RESULT_OK, result);
+ }
+
+ finish();
+ }
+
+ private void processViews() {
+ record_button = (ImageButton) findViewById(R.id.record_button);
+ record_volumn = (ProgressBar) findViewById(R.id.record_volumn);
+ // 隱藏狀態列ProgressBar
+ setProgressBarIndeterminateVisibility(false);
+ }
+
+ public void clickRecord(View view) {
+ // 切換
+ isRecording = !isRecording;
+
+ // 開始錄音
+ if (isRecording) {
+ // 設定按鈕圖示為錄音中
+ record_button.setImageResource(R.drawable.record_red_icon);
+ // 建立錄音物件
+ myRecoder = new MyRecoder(fileName);
+ // 開始錄音
+ myRecoder.start();
+ // 建立並執行顯示麥克風音量的AsyncTask物件
+ new MicLevelTask().execute();
+ }
+ // 停止錄音
+ else {
+ // 設定按鈕圖示為停止錄音
+ record_button.setImageResource(R.drawable.record_dark_icon);
+ // 麥克風音量歸零
+ record_volumn.setProgress(0);
+ // 停止錄音
+ myRecoder.stop();
+ }
+ }
+
+ // 在錄音過程中顯示麥克風音量
+ private class MicLevelTask extends AsyncTask
{
+ @Override
+ protected Void doInBackground(Void... args) {
+ while (isRecording) {
+ publishProgress();
+
+ try {
+ Thread.sleep(200);
+ }
+ catch (InterruptedException e) {
+ Log.d("RecordActivity", e.toString());
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ protected void onProgressUpdate(Void... values) {
+ record_volumn.setProgress((int) myRecoder.getAmplitudeEMA());
+ }
+
+ }
+
+ // 執行錄音並且可以取得麥克風音量的錄音物件
+ private class MyRecoder {
+
+ private static final double EMA_FILTER = 0.6;
+ private MediaRecorder recorder = null;
+ private double mEMA = 0.0;
+ private String output;
+
+ // 建立錄音物件,參數為錄音儲存的位置與檔名
+ MyRecoder(String output) {
+ this.output = output;
+ }
+
+ // 開始錄音
+ public void start() {
+ if (recorder == null) {
+ // 建立錄音用的MediaRecorder物件
+ recorder = new MediaRecorder();
+ // 設定錄音來源為麥克風,必須在setOutputFormat方法之前呼叫
+ recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
+ // 設定輸出格式為3GP壓縮格式,必須在setAudioSource方法之後,
+ // 在prepare方法之前呼叫
+ recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
+ // 設定錄音的編碼方式,必須在setOutputFormat方法之後,
+ // 在prepare方法之前呼叫
+ recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
+ // 設定輸出的檔案名稱,必須在setOutputFormat方法之後,
+ // 在prepare方法之前呼叫
+ recorder.setOutputFile(output);
+
+ try {
+ // 準備執行錄音工作,必須在所有設定之後呼叫
+ recorder.prepare();
+ }
+ catch (IOException e) {
+ Log.d("RecordActivity", e.toString());
+ }
+
+ // 開始錄音
+ recorder.start();
+ mEMA = 0.0;
+ }
+ }
+
+ // 停止錄音
+ public void stop() {
+ if (recorder != null) {
+ // 停止錄音
+ recorder.stop();
+ // 清除錄音資源
+ recorder.release();
+ recorder = null;
+ }
+ }
+
+ public double getAmplitude() {
+ if (recorder != null)
+ return (recorder.getMaxAmplitude() / 2700.0);
+ else
+ return 0;
+ }
+
+ // 取得麥克風音量
+ public double getAmplitudeEMA() {
+ double amp = getAmplitude();
+ mEMA = EMA_FILTER * amp + (1.0 - EMA_FILTER) * mEMA;
+ return mEMA;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0502/MyAndroidTutorial/app/src/main/res/drawable-hdpi/ic_launcher.png b/examples/0502/MyAndroidTutorial/app/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..96a442e
Binary files /dev/null and b/examples/0502/MyAndroidTutorial/app/src/main/res/drawable-hdpi/ic_launcher.png differ
diff --git a/examples/0502/MyAndroidTutorial/app/src/main/res/drawable-mdpi/ic_launcher.png b/examples/0502/MyAndroidTutorial/app/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..359047d
Binary files /dev/null and b/examples/0502/MyAndroidTutorial/app/src/main/res/drawable-mdpi/ic_launcher.png differ
diff --git a/examples/0502/MyAndroidTutorial/app/src/main/res/drawable-xhdpi/ic_launcher.png b/examples/0502/MyAndroidTutorial/app/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..71c6d76
Binary files /dev/null and b/examples/0502/MyAndroidTutorial/app/src/main/res/drawable-xhdpi/ic_launcher.png differ
diff --git a/examples/0502/MyAndroidTutorial/app/src/main/res/drawable-xxhdpi/ic_launcher.png b/examples/0502/MyAndroidTutorial/app/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..4df1894
Binary files /dev/null and b/examples/0502/MyAndroidTutorial/app/src/main/res/drawable-xxhdpi/ic_launcher.png differ
diff --git a/examples/0502/MyAndroidTutorial/app/src/main/res/drawable/alarm_icon.png b/examples/0502/MyAndroidTutorial/app/src/main/res/drawable/alarm_icon.png
new file mode 100644
index 0000000..c6cac88
Binary files /dev/null and b/examples/0502/MyAndroidTutorial/app/src/main/res/drawable/alarm_icon.png differ
diff --git a/examples/0502/MyAndroidTutorial/app/src/main/res/drawable/item_drawable.xml b/examples/0502/MyAndroidTutorial/app/src/main/res/drawable/item_drawable.xml
new file mode 100644
index 0000000..37607e2
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/app/src/main/res/drawable/item_drawable.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0502/MyAndroidTutorial/app/src/main/res/drawable/location_icon.png b/examples/0502/MyAndroidTutorial/app/src/main/res/drawable/location_icon.png
new file mode 100644
index 0000000..4c3c514
Binary files /dev/null and b/examples/0502/MyAndroidTutorial/app/src/main/res/drawable/location_icon.png differ
diff --git a/examples/0502/MyAndroidTutorial/app/src/main/res/drawable/pause_icon.png b/examples/0502/MyAndroidTutorial/app/src/main/res/drawable/pause_icon.png
new file mode 100755
index 0000000..a5aee6f
Binary files /dev/null and b/examples/0502/MyAndroidTutorial/app/src/main/res/drawable/pause_icon.png differ
diff --git a/examples/0502/MyAndroidTutorial/app/src/main/res/drawable/play_icon.png b/examples/0502/MyAndroidTutorial/app/src/main/res/drawable/play_icon.png
new file mode 100755
index 0000000..6a40cd5
Binary files /dev/null and b/examples/0502/MyAndroidTutorial/app/src/main/res/drawable/play_icon.png differ
diff --git a/examples/0502/MyAndroidTutorial/app/src/main/res/drawable/record_dark_icon.png b/examples/0502/MyAndroidTutorial/app/src/main/res/drawable/record_dark_icon.png
new file mode 100755
index 0000000..bcf83ca
Binary files /dev/null and b/examples/0502/MyAndroidTutorial/app/src/main/res/drawable/record_dark_icon.png differ
diff --git a/examples/0502/MyAndroidTutorial/app/src/main/res/drawable/record_red_icon.png b/examples/0502/MyAndroidTutorial/app/src/main/res/drawable/record_red_icon.png
new file mode 100755
index 0000000..2b44af0
Binary files /dev/null and b/examples/0502/MyAndroidTutorial/app/src/main/res/drawable/record_red_icon.png differ
diff --git a/examples/0502/MyAndroidTutorial/app/src/main/res/drawable/record_sound_icon.png b/examples/0502/MyAndroidTutorial/app/src/main/res/drawable/record_sound_icon.png
new file mode 100755
index 0000000..a1382ac
Binary files /dev/null and b/examples/0502/MyAndroidTutorial/app/src/main/res/drawable/record_sound_icon.png differ
diff --git a/examples/0502/MyAndroidTutorial/app/src/main/res/drawable/retangle_drawable.xml b/examples/0502/MyAndroidTutorial/app/src/main/res/drawable/retangle_drawable.xml
new file mode 100644
index 0000000..51d1e84
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/app/src/main/res/drawable/retangle_drawable.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0502/MyAndroidTutorial/app/src/main/res/drawable/select_color_icon.png b/examples/0502/MyAndroidTutorial/app/src/main/res/drawable/select_color_icon.png
new file mode 100644
index 0000000..8567d5e
Binary files /dev/null and b/examples/0502/MyAndroidTutorial/app/src/main/res/drawable/select_color_icon.png differ
diff --git a/examples/0502/MyAndroidTutorial/app/src/main/res/drawable/selected_icon.png b/examples/0502/MyAndroidTutorial/app/src/main/res/drawable/selected_icon.png
new file mode 100755
index 0000000..b891571
Binary files /dev/null and b/examples/0502/MyAndroidTutorial/app/src/main/res/drawable/selected_icon.png differ
diff --git a/examples/0502/MyAndroidTutorial/app/src/main/res/drawable/stop_icon.png b/examples/0502/MyAndroidTutorial/app/src/main/res/drawable/stop_icon.png
new file mode 100755
index 0000000..20df415
Binary files /dev/null and b/examples/0502/MyAndroidTutorial/app/src/main/res/drawable/stop_icon.png differ
diff --git a/examples/0502/MyAndroidTutorial/app/src/main/res/drawable/take_picture_icon.png b/examples/0502/MyAndroidTutorial/app/src/main/res/drawable/take_picture_icon.png
new file mode 100644
index 0000000..08fb514
Binary files /dev/null and b/examples/0502/MyAndroidTutorial/app/src/main/res/drawable/take_picture_icon.png differ
diff --git a/examples/0502/MyAndroidTutorial/app/src/main/res/layout/activity_about.xml b/examples/0502/MyAndroidTutorial/app/src/main/res/layout/activity_about.xml
new file mode 100644
index 0000000..8e78611
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/app/src/main/res/layout/activity_about.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0502/MyAndroidTutorial/app/src/main/res/layout/activity_color.xml b/examples/0502/MyAndroidTutorial/app/src/main/res/layout/activity_color.xml
new file mode 100644
index 0000000..d25bbc5
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/app/src/main/res/layout/activity_color.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
diff --git a/examples/0502/MyAndroidTutorial/app/src/main/res/layout/activity_item.xml b/examples/0502/MyAndroidTutorial/app/src/main/res/layout/activity_item.xml
new file mode 100644
index 0000000..4ec4362
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/app/src/main/res/layout/activity_item.xml
@@ -0,0 +1,125 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0502/MyAndroidTutorial/app/src/main/res/layout/activity_main.xml b/examples/0502/MyAndroidTutorial/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..121511b
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
diff --git a/examples/0502/MyAndroidTutorial/app/src/main/res/layout/activity_maps.xml b/examples/0502/MyAndroidTutorial/app/src/main/res/layout/activity_maps.xml
new file mode 100644
index 0000000..5de477b
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/app/src/main/res/layout/activity_maps.xml
@@ -0,0 +1,7 @@
+
diff --git a/examples/0502/MyAndroidTutorial/app/src/main/res/layout/activity_play.xml b/examples/0502/MyAndroidTutorial/app/src/main/res/layout/activity_play.xml
new file mode 100644
index 0000000..52db308
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/app/src/main/res/layout/activity_play.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0502/MyAndroidTutorial/app/src/main/res/layout/activity_record.xml b/examples/0502/MyAndroidTutorial/app/src/main/res/layout/activity_record.xml
new file mode 100644
index 0000000..63d9e36
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/app/src/main/res/layout/activity_record.xml
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0502/MyAndroidTutorial/app/src/main/res/layout/single_item.xml b/examples/0502/MyAndroidTutorial/app/src/main/res/layout/single_item.xml
new file mode 100644
index 0000000..40ddbc9
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/app/src/main/res/layout/single_item.xml
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0502/MyAndroidTutorial/app/src/main/res/menu/menu_about.xml b/examples/0502/MyAndroidTutorial/app/src/main/res/menu/menu_about.xml
new file mode 100644
index 0000000..d481100
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/app/src/main/res/menu/menu_about.xml
@@ -0,0 +1,7 @@
+
+
+
diff --git a/examples/0502/MyAndroidTutorial/app/src/main/res/menu/menu_color.xml b/examples/0502/MyAndroidTutorial/app/src/main/res/menu/menu_color.xml
new file mode 100644
index 0000000..8ff243b
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/app/src/main/res/menu/menu_color.xml
@@ -0,0 +1,7 @@
+
+
+
diff --git a/examples/0502/MyAndroidTutorial/app/src/main/res/menu/menu_item.xml b/examples/0502/MyAndroidTutorial/app/src/main/res/menu/menu_item.xml
new file mode 100644
index 0000000..cd2c9e4
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/app/src/main/res/menu/menu_item.xml
@@ -0,0 +1,7 @@
+
+
+
diff --git a/examples/0502/MyAndroidTutorial/app/src/main/res/menu/menu_main.xml b/examples/0502/MyAndroidTutorial/app/src/main/res/menu/menu_main.xml
new file mode 100644
index 0000000..0203cfa
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/app/src/main/res/menu/menu_main.xml
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
diff --git a/examples/0502/MyAndroidTutorial/app/src/main/res/values-en/strings.xml b/examples/0502/MyAndroidTutorial/app/src/main/res/values-en/strings.xml
new file mode 100644
index 0000000..c532533
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/app/src/main/res/values-en/strings.xml
@@ -0,0 +1,12 @@
+
+
+
+ MyAndroidTutorial
+ Hello world!
+ Settings
+
+ Title
+ Enter title
+ Content
+ Enter content
+
diff --git a/examples/0502/MyAndroidTutorial/app/src/main/res/values-w820dp/dimens.xml b/examples/0502/MyAndroidTutorial/app/src/main/res/values-w820dp/dimens.xml
new file mode 100644
index 0000000..63fc816
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/app/src/main/res/values-w820dp/dimens.xml
@@ -0,0 +1,6 @@
+
+
+ 64dp
+
diff --git a/examples/0502/MyAndroidTutorial/app/src/main/res/values/colors.xml b/examples/0502/MyAndroidTutorial/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..6b13c1d
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/app/src/main/res/values/colors.xml
@@ -0,0 +1,7 @@
+
+
+ #CCCCCC
+ #AAAAAA
+ #DD999999
+ #111111
+
\ No newline at end of file
diff --git a/examples/0502/MyAndroidTutorial/app/src/main/res/values/dimens.xml b/examples/0502/MyAndroidTutorial/app/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..02898ec
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/app/src/main/res/values/dimens.xml
@@ -0,0 +1,9 @@
+
+
+ 16dp
+ 16dp
+
+ 6dp
+ 24sp
+ 2dp
+
diff --git a/examples/0502/MyAndroidTutorial/app/src/main/res/values/strings.xml b/examples/0502/MyAndroidTutorial/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..89dcf0f
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/app/src/main/res/values/strings.xml
@@ -0,0 +1,56 @@
+
+
+
+ MyAndroidTutorial
+ Hello world!
+ Settings
+ 標題
+ 輸入標題
+ 內容
+ 輸入內容
+ 這是Android Tutorial應用程式
+ AboutActivity
+ 版本:AndroidTutorial_0.2.4
+ ItemActivity
+ ColorActivity
+ 刪除
+ 確定要刪除 %1$d 個項目?
+ 預設的顏色
+ 新增記事的預設顏色
+
+ 預設提醒時間
+ 在指定的時間之前通知
+
+
+ - 五分鐘
+ - 十分鐘
+ - 二十分鐘
+ - 三十分鐘
+ - 六十分鐘
+
+
+
+ - 5
+ - 10
+ - 20
+ - 30
+ - 60
+
+
+ 語音備忘
+ 播放語音備忘
+ 播放
+ 重新錄製
+ Map
+
+ 記事儲存的位置
+ 更新或清除儲存的位置資訊?
+ 更新
+ 清除
+
+ 目前位置
+ 是否儲存目前位置?
+
+ 裝置沒有安裝Google Play服務
+
+
diff --git a/examples/0502/MyAndroidTutorial/app/src/main/res/values/styles.xml b/examples/0502/MyAndroidTutorial/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..766ab99
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/app/src/main/res/values/styles.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
diff --git a/examples/0502/MyAndroidTutorial/app/src/main/res/xml/mypreference.xml b/examples/0502/MyAndroidTutorial/app/src/main/res/xml/mypreference.xml
new file mode 100644
index 0000000..33e714c
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/app/src/main/res/xml/mypreference.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0502/MyAndroidTutorial/app/src/release/res/values/google_maps_api.xml b/examples/0502/MyAndroidTutorial/app/src/release/res/values/google_maps_api.xml
new file mode 100644
index 0000000..c4e2431
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/app/src/release/res/values/google_maps_api.xml
@@ -0,0 +1,18 @@
+
+
+
+ YOUR_KEY_HERE
+
+
diff --git a/examples/0502/MyAndroidTutorial/build.gradle b/examples/0502/MyAndroidTutorial/build.gradle
new file mode 100644
index 0000000..6356aab
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/build.gradle
@@ -0,0 +1,19 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+ repositories {
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:1.0.0'
+
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+}
+
+allprojects {
+ repositories {
+ jcenter()
+ }
+}
diff --git a/examples/0502/MyAndroidTutorial/gradle.properties b/examples/0502/MyAndroidTutorial/gradle.properties
new file mode 100644
index 0000000..1d3591c
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/gradle.properties
@@ -0,0 +1,18 @@
+# Project-wide Gradle settings.
+
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+# Default value: -Xmx10248m -XX:MaxPermSize=256m
+# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
+
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
\ No newline at end of file
diff --git a/examples/0502/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.jar b/examples/0502/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
Binary files /dev/null and b/examples/0502/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/examples/0502/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.properties b/examples/0502/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..0c71e76
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
diff --git a/examples/0502/MyAndroidTutorial/gradlew b/examples/0502/MyAndroidTutorial/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/examples/0502/MyAndroidTutorial/gradlew.bat b/examples/0502/MyAndroidTutorial/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/examples/0502/MyAndroidTutorial/settings.gradle b/examples/0502/MyAndroidTutorial/settings.gradle
new file mode 100644
index 0000000..e7b4def
--- /dev/null
+++ b/examples/0502/MyAndroidTutorial/settings.gradle
@@ -0,0 +1 @@
+include ':app'
diff --git a/examples/0503/MyAndroidTutorial/.gitignore b/examples/0503/MyAndroidTutorial/.gitignore
new file mode 100644
index 0000000..afbdab3
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/.gitignore
@@ -0,0 +1,6 @@
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
diff --git a/examples/0503/MyAndroidTutorial/.idea/.name b/examples/0503/MyAndroidTutorial/.idea/.name
new file mode 100644
index 0000000..5bb7a85
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/.idea/.name
@@ -0,0 +1 @@
+MyAndroidTutorial
\ No newline at end of file
diff --git a/examples/0503/MyAndroidTutorial/.idea/compiler.xml b/examples/0503/MyAndroidTutorial/.idea/compiler.xml
new file mode 100644
index 0000000..217af47
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/.idea/compiler.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0503/MyAndroidTutorial/.idea/copyright/profiles_settings.xml b/examples/0503/MyAndroidTutorial/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..e7bedf3
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/examples/0503/MyAndroidTutorial/.idea/encodings.xml b/examples/0503/MyAndroidTutorial/.idea/encodings.xml
new file mode 100644
index 0000000..e206d70
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/.idea/encodings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/examples/0503/MyAndroidTutorial/.idea/gradle.xml b/examples/0503/MyAndroidTutorial/.idea/gradle.xml
new file mode 100644
index 0000000..fe865d3
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/.idea/gradle.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0503/MyAndroidTutorial/.idea/misc.xml b/examples/0503/MyAndroidTutorial/.idea/misc.xml
new file mode 100644
index 0000000..9076de5
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/.idea/misc.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0503/MyAndroidTutorial/.idea/modules.xml b/examples/0503/MyAndroidTutorial/.idea/modules.xml
new file mode 100644
index 0000000..327df67
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/.idea/modules.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0503/MyAndroidTutorial/.idea/scopes/scope_settings.xml b/examples/0503/MyAndroidTutorial/.idea/scopes/scope_settings.xml
new file mode 100644
index 0000000..922003b
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/.idea/scopes/scope_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0503/MyAndroidTutorial/.idea/vcs.xml b/examples/0503/MyAndroidTutorial/.idea/vcs.xml
new file mode 100644
index 0000000..def6a6a
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/.idea/vcs.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/examples/0503/MyAndroidTutorial/MyAndroidTutorial.iml b/examples/0503/MyAndroidTutorial/MyAndroidTutorial.iml
new file mode 100644
index 0000000..0bb6048
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/MyAndroidTutorial.iml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0503/MyAndroidTutorial/app/.gitignore b/examples/0503/MyAndroidTutorial/app/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/app/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/examples/0503/MyAndroidTutorial/app/app.iml b/examples/0503/MyAndroidTutorial/app/app.iml
new file mode 100644
index 0000000..b767e16
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/app/app.iml
@@ -0,0 +1,113 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0503/MyAndroidTutorial/app/build.gradle b/examples/0503/MyAndroidTutorial/app/build.gradle
new file mode 100644
index 0000000..9423d38
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/app/build.gradle
@@ -0,0 +1,26 @@
+apply plugin: 'com.android.application'
+
+android {
+ compileSdkVersion 21
+ buildToolsVersion "21.1.2"
+
+ defaultConfig {
+ applicationId "net.macdidi.myandroidtutorial"
+ minSdkVersion 16
+ targetSdkVersion 21
+ versionCode 1
+ versionName "1.0"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ compile fileTree(dir: 'libs', include: ['*.jar'])
+ compile 'com.android.support:appcompat-v7:22.0.0'
+ compile 'com.google.android.gms:play-services:7.0.0'
+}
diff --git a/examples/0503/MyAndroidTutorial/app/proguard-rules.pro b/examples/0503/MyAndroidTutorial/app/proguard-rules.pro
new file mode 100644
index 0000000..b5fa7ec
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/app/proguard-rules.pro
@@ -0,0 +1,17 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /Users/macdidi5/Library/Android/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
diff --git a/examples/0503/MyAndroidTutorial/app/src/androidTest/java/net/macdidi/myandroidtutorial/ApplicationTest.java b/examples/0503/MyAndroidTutorial/app/src/androidTest/java/net/macdidi/myandroidtutorial/ApplicationTest.java
new file mode 100644
index 0000000..2cb214e
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/app/src/androidTest/java/net/macdidi/myandroidtutorial/ApplicationTest.java
@@ -0,0 +1,13 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Application;
+import android.test.ApplicationTestCase;
+
+/**
+ * Testing Fundamentals
+ */
+public class ApplicationTest extends ApplicationTestCase {
+ public ApplicationTest() {
+ super(Application.class);
+ }
+}
\ No newline at end of file
diff --git a/examples/0503/MyAndroidTutorial/app/src/debug/res/values/google_maps_api.xml b/examples/0503/MyAndroidTutorial/app/src/debug/res/values/google_maps_api.xml
new file mode 100644
index 0000000..7341c8d
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/app/src/debug/res/values/google_maps_api.xml
@@ -0,0 +1,18 @@
+
+
+
+ AIzaSyCZg9YWlfokPA96VxWGYr6u4C12jL16VhM
+
+
diff --git a/examples/0503/MyAndroidTutorial/app/src/main/AndroidManifest.xml b/examples/0503/MyAndroidTutorial/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..50449c2
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/app/src/main/AndroidManifest.xml
@@ -0,0 +1,128 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0503/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/AboutActivity.java b/examples/0503/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/AboutActivity.java
new file mode 100644
index 0000000..42dddeb
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/AboutActivity.java
@@ -0,0 +1,24 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.view.Window;
+
+public class AboutActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ // 取消元件的應用程式標題
+ requestWindowFeature(Window.FEATURE_NO_TITLE);
+ setContentView(R.layout.activity_about);
+ }
+
+ // 結束按鈕
+ public void clickOk(View view) {
+ // 呼叫這個方法結束Activity元件
+ finish();
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0503/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/AlarmReceiver.java b/examples/0503/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/AlarmReceiver.java
new file mode 100644
index 0000000..368165c
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/AlarmReceiver.java
@@ -0,0 +1,86 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.support.v4.app.NotificationCompat;
+
+import java.io.File;
+
+public class AlarmReceiver extends BroadcastReceiver {
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ // 讀取記事標題
+ //String title = intent.getStringExtra("title");
+ // 顯示訊息框
+ //Toast.makeText(context, title, Toast.LENGTH_LONG).show();
+
+ // 讀取記事編號
+ long id = intent.getLongExtra("id", 0);
+
+ if (id != 0) {
+ sendNotify(context, id);
+ }
+ }
+
+ private void sendNotify(Context context, long id) {
+ // 建立資料庫物件
+ ItemDAO itemDAO = new ItemDAO(context.getApplicationContext());
+ // 讀取指定編號的記事物件
+ Item item = itemDAO.get(id);
+
+ // 建立照片檔案物件
+ File file = new File(FileUtil.getExternalStorageDir(FileUtil.APP_DIR),
+ "P" + item.getFileName() + ".jpg");
+
+ // 是否儲存照片檔案
+ boolean isPicture = (item.getFileName() != null &&
+ item.getFileName().length() > 0 &&
+ file.exists());
+
+ // 取得NotificationManager物件
+ NotificationManager nm = (NotificationManager)
+ context.getSystemService(Context.NOTIFICATION_SERVICE);
+
+ // 如果有儲存照片檔案
+ if (isPicture) {
+ // 建立Notification.Builder物件,因為要設定大型圖片樣式
+ // 所以不能使用NotificationCompat.Builder
+ Notification.Builder builder = new Notification.Builder(context);
+ builder.setSmallIcon(android.R.drawable.star_on)
+ .setWhen(System.currentTimeMillis())
+ .setContentTitle(context.getString(R.string.app_name));
+
+ // 建立大型圖片樣式物件
+ Notification.BigPictureStyle bigPictureStyle =
+ new Notification.BigPictureStyle();
+ // 設定圖片與簡介
+ Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
+ bigPictureStyle.bigPicture(bitmap)
+ .setSummaryText(item.getTitle());
+ // 設定樣式為大型圖片
+ builder.setStyle(bigPictureStyle);
+ // 發出通知
+ nm.notify((int)item.getId(), builder.build());
+ }
+ // 如果沒有儲存照片檔案
+ else {
+ // 建立NotificationCompat.Builder物件
+ NotificationCompat.Builder builder =
+ new NotificationCompat.Builder(context);
+ // 設定圖示、時間、內容標題和內容訊息
+ builder.setSmallIcon(android.R.drawable.star_big_on)
+ .setWhen(System.currentTimeMillis())
+ .setContentTitle(context.getString(R.string.app_name))
+ .setContentText(item.getTitle());
+ // 發出通知
+ nm.notify((int)item.getId(), builder.build());
+ }
+ }
+
+}
diff --git a/examples/0503/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ColorActivity.java b/examples/0503/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ColorActivity.java
new file mode 100644
index 0000000..182cd55
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ColorActivity.java
@@ -0,0 +1,75 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.LinearLayout;
+
+public class ColorActivity extends Activity {
+
+ private LinearLayout color_gallery;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_color);
+
+ processViews();
+
+ ColorListener listener = new ColorListener();
+
+ for (Colors c : Colors.values()) {
+ Button button = new Button(this);
+ button.setId(c.parseColor());
+ LinearLayout.LayoutParams layout =
+ new LinearLayout.LayoutParams(128, 128);
+ layout.setMargins(6, 6, 6, 6);
+ button.setLayoutParams(layout);
+ button.setBackgroundColor(c.parseColor());
+
+ button.setOnClickListener(listener);
+
+ color_gallery.addView(button);
+ }
+ }
+
+ private void processViews() {
+ color_gallery = (LinearLayout) findViewById(R.id.color_gallery);
+ }
+
+ private class ColorListener implements OnClickListener {
+
+ @Override
+ public void onClick(View view) {
+ String action = ColorActivity.this.getIntent().getAction();
+
+ // 經由設定元件啟動
+ if (action != null &&
+ action.equals("net.macdidi.myandroidtutorial.CHOOSE_COLOR")) {
+ // 建立SharedPreferences物件
+ SharedPreferences.Editor editor =
+ PreferenceManager.getDefaultSharedPreferences(
+ ColorActivity.this).edit();
+ // 儲存預設顏色
+ editor.putInt("DEFAULT_COLOR", view.getId());
+ // 寫入設定值
+ editor.commit();
+ finish();
+ }
+ // 經由新增或修改記事的元件啟動
+ else {
+ Intent result = getIntent();
+ result.putExtra("colorId", view.getId());
+ setResult(Activity.RESULT_OK, result);
+ finish();
+ }
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0503/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Colors.java b/examples/0503/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Colors.java
new file mode 100644
index 0000000..1462149
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Colors.java
@@ -0,0 +1,24 @@
+package net.macdidi.myandroidtutorial;
+
+import android.graphics.Color;
+
+public enum Colors {
+
+ LIGHTGREY("#D3D3D3"), BLUE("#33B5E5"), PURPLE("#AA66CC"),
+ GREEN("#99CC00"), ORANGE("#FFBB33"), RED("#FF4444");
+
+ private String code;
+
+ private Colors(String code) {
+ this.code = code;
+ }
+
+ public String getCode() {
+ return code;
+ }
+
+ public int parseColor() {
+ return Color.parseColor(code);
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0503/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/FileUtil.java b/examples/0503/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/FileUtil.java
new file mode 100644
index 0000000..1fb41be
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/FileUtil.java
@@ -0,0 +1,112 @@
+package net.macdidi.myandroidtutorial;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.os.Environment;
+import android.util.Log;
+import android.widget.ImageView;
+
+import java.io.File;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+public class FileUtil {
+
+ // 應用程式儲存檔案的目錄
+ public static final String APP_DIR = "androidtutorial";
+
+ // 外部儲存設備是否可寫入
+ public static boolean isExternalStorageWritable() {
+ // 取得目前外部儲存設備的狀態
+ String state = Environment.getExternalStorageState();
+
+ // 判斷是否可寫入
+ if (Environment.MEDIA_MOUNTED.equals(state)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ // 外部儲存設備是否可讀取
+ public static boolean isExternalStorageReadable() {
+ // 取得目前外部儲存設備的狀態
+ String state = Environment.getExternalStorageState();
+
+ // 判斷是否可讀取
+ if (Environment.MEDIA_MOUNTED.equals(state) ||
+ Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ // 建立並傳回在公用相簿下參數指定的路徑
+ public static File getPublicAlbumStorageDir(String albumName) {
+ // 取得公用的照片路徑
+ File pictures = Environment.getExternalStoragePublicDirectory(
+ Environment.DIRECTORY_PICTURES);
+ // 準備在照片路徑下建立一個指定的路徑
+ File file = new File(pictures, albumName);
+
+ // 如果建立路徑不成功
+ if (!file.mkdirs()) {
+ Log.e("getAlbumStorageDir", "Directory not created");
+ }
+
+ return file;
+ }
+
+ // 建立並傳回在應用程式專用相簿下參數指定的路徑
+ public static File getAlbumStorageDir(Context context, String albumName) {
+ // 取得應用程式專用的照片路徑
+ File pictures = context.getExternalFilesDir(
+ Environment.DIRECTORY_PICTURES);
+ // 準備在照片路徑下建立一個指定的路徑
+ File file = new File(pictures, albumName);
+
+ // 如果建立路徑不成功
+ if (!file.mkdirs()) {
+ Log.e("getAlbumStorageDir", "Directory not created");
+ }
+
+ return file;
+ }
+
+ // 建立並傳回外部儲存媒體參數指定的路徑
+ public static File getExternalStorageDir(String dir) {
+ File result = new File(
+ Environment.getExternalStorageDirectory(), dir);
+
+ if (!isExternalStorageWritable()) {
+ return null;
+ }
+
+ if (!result.exists() && !result.mkdirs()) {
+ return null;
+ }
+
+ return result;
+ }
+
+ // 讀取指定的照片檔案名稱設定給ImageView元件
+ public static void fileToImageView(String fileName, ImageView imageView) {
+ if (new File(fileName).exists()) {
+ Bitmap bitmap = BitmapFactory.decodeFile(fileName);
+ imageView.setImageBitmap(bitmap);
+ }
+ else {
+ Log.e("fileToImageView", fileName + " not found.");
+ }
+ }
+
+ // 產生唯一的檔案名稱
+ public static String getUniqueFileName() {
+ // 使用年月日_時分秒格式為檔案名稱
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
+ return sdf.format(new Date());
+ }
+
+}
diff --git a/examples/0503/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/InitAlarmReceiver.java b/examples/0503/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/InitAlarmReceiver.java
new file mode 100644
index 0000000..959785f
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/InitAlarmReceiver.java
@@ -0,0 +1,49 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+import java.util.Calendar;
+import java.util.List;
+
+public class InitAlarmReceiver extends BroadcastReceiver {
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ // 建立資料庫物件
+ ItemDAO itemDAO = new ItemDAO(context.getApplicationContext());
+ // 讀取資料庫所有記事資料
+ List- items = itemDAO.getAll();
+
+ // 讀取目前時間
+ long current = Calendar.getInstance().getTimeInMillis();
+
+ AlarmManager am = (AlarmManager)
+ context.getSystemService(Context.ALARM_SERVICE);
+
+ for (Item item : items) {
+ long alarm = item.getAlarmDatetime();
+
+ // 如果沒有設定提醒或是提醒已經過期
+ if (alarm == 0 || alarm <= current) {
+ continue;
+ }
+
+ // 設定提醒
+ Intent alarmIntent = new Intent(context, AlarmReceiver.class);
+ //alarmIntent.putExtra("title", item.getTitle());
+
+ // 加入記事編號
+ intent.putExtra("id", item.getId());
+
+ PendingIntent pi = PendingIntent.getBroadcast(
+ context, (int)item.getId(),
+ alarmIntent, PendingIntent.FLAG_ONE_SHOT);
+ am.set(AlarmManager.RTC_WAKEUP, item.getAlarmDatetime(), pi);
+ }
+ }
+
+}
diff --git a/examples/0503/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Item.java b/examples/0503/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Item.java
new file mode 100644
index 0000000..e2bc93d
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Item.java
@@ -0,0 +1,156 @@
+package net.macdidi.myandroidtutorial;
+
+import java.util.Date;
+import java.util.Locale;
+
+public class Item implements java.io.Serializable {
+
+ // 編號、日期時間、顏色、標題、內容、照片檔案名稱、錄音檔案名稱、經緯度、修改、已選擇
+ private long id;
+ private long datetime;
+ private Colors color;
+ private String title;
+ private String content;
+ private String fileName;
+ private String recFileName;
+ private double latitude;
+ private double longitude;
+ private long lastModify;
+ private boolean selected;
+
+ // 提醒日期時間
+ private long alarmDatetime;
+
+ public Item() {
+ title = "";
+ content = "";
+ color = Colors.LIGHTGREY;
+ }
+
+ public Item(long id, long datetime, Colors color, String title,
+ String content, String fileName, String recFileName,
+ double latitude, double longitude, long lastModify) {
+ this.id = id;
+ this.datetime = datetime;
+ this.color = color;
+ this.title = title;
+ this.content = content;
+ this.fileName = fileName;
+ this.recFileName = recFileName;
+ this.latitude = latitude;
+ this.longitude = longitude;
+ this.lastModify = lastModify;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public long getDatetime() {
+ return datetime;
+ }
+
+ // 裝置區域的日期時間
+ public String getLocaleDatetime() {
+ return String.format(Locale.getDefault(), "%tF %
0) {
+ // 照片檔案物件
+ File file = configFileName("P", ".jpg");
+
+ // 如果照片檔案存在
+ if (file.exists()) {
+ // 顯示照片元件
+ picture.setVisibility(View.VISIBLE);
+ // 設定照片
+ FileUtil.fileToImageView(file.getAbsolutePath(), picture);
+ }
+ }
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (resultCode == Activity.RESULT_OK) {
+ switch (requestCode) {
+ // 照像
+ case START_CAMERA:
+ // 設定照片檔案名稱
+ item.setFileName(fileName);
+ break;
+ case START_RECORD:
+ // 設定錄音檔案名稱
+ item.setRecFileName(fileName);
+ break;
+ case START_LOCATION:
+ // 讀取與設定座標
+ double lat = data.getDoubleExtra("lat", 0.0);
+ double lng = data.getDoubleExtra("lng", 0.0);
+ item.setLatitude(lat);
+ item.setLongitude(lng);
+ break;
+ case START_ALARM:
+ break;
+ // 設定顏色
+ case START_COLOR:
+ int colorId = data.getIntExtra(
+ "colorId", Colors.LIGHTGREY.parseColor());
+ item.setColor(getColors(colorId));
+ break;
+ }
+ }
+ }
+
+ public static Colors getColors(int color) {
+ Colors result = Colors.LIGHTGREY;
+
+ if (color == Colors.BLUE.parseColor()) {
+ result = Colors.BLUE;
+ }
+ else if (color == Colors.PURPLE.parseColor()) {
+ result = Colors.PURPLE;
+ }
+ else if (color == Colors.GREEN.parseColor()) {
+ result = Colors.GREEN;
+ }
+ else if (color == Colors.ORANGE.parseColor()) {
+ result = Colors.ORANGE;
+ }
+ else if (color == Colors.RED.parseColor()) {
+ result = Colors.RED;
+ }
+
+ return result;
+ }
+
+ private void processViews() {
+ title_text = (EditText) findViewById(R.id.title_text);
+ content_text = (EditText) findViewById(R.id.content_text);
+ // 取得顯示照片的ImageView元件
+ picture = (ImageView) findViewById(R.id.picture);
+ }
+
+ // 點擊確定與取消按鈕都會呼叫這個方法
+ public void onSubmit(View view) {
+
+ if (view.getId() == R.id.ok_teim) {
+ String titleText = title_text.getText().toString();
+ String contentText = content_text.getText().toString();
+
+ item.setTitle(titleText);
+ item.setContent(contentText);
+
+ if (getIntent().getAction().equals(
+ "net.macdidi.myandroidtutorial.EDIT_ITEM")) {
+ item.setLastModify(new Date().getTime());
+ }
+ // 新增記事
+ else {
+ item.setDatetime(new Date().getTime());
+ }
+
+ Intent result = getIntent();
+ result.putExtra("net.macdidi.myandroidtutorial.Item", item);
+ setResult(Activity.RESULT_OK, result);
+ }
+
+ // 結束
+ finish();
+ }
+
+ public void clickFunction(View view) {
+ int id = view.getId();
+
+ switch (id) {
+ case R.id.take_picture:
+ // 啟動相機元件用的Intent物件
+ Intent intentCamera =
+ new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
+
+ // 照片檔案名稱
+ File pictureFile = configFileName("P", ".jpg");
+ Uri uri = Uri.fromFile(pictureFile);
+ // 設定檔案名稱
+ intentCamera.putExtra(MediaStore.EXTRA_OUTPUT, uri);
+ // 啟動相機元件
+ startActivityForResult(intentCamera, START_CAMERA);
+ break;
+ case R.id.record_sound:
+ // 錄音檔案名稱
+ final File recordFile = configRecFileName("R", ".mp3");
+
+ // 如果已經有錄音檔,詢問播放或重新錄製
+ if (recordFile.exists()) {
+ // 詢問播放還是重新錄製的對話框
+ AlertDialog.Builder d = new AlertDialog.Builder(this);
+
+ d.setTitle(R.string.title_record)
+ .setCancelable(false);
+ d.setPositiveButton(R.string.record_play,
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ // 播放
+ Intent playIntent = new Intent(
+ ItemActivity.this, PlayActivity.class);
+ playIntent.putExtra("fileName",
+ recordFile.getAbsolutePath());
+ startActivity(playIntent);
+ }
+ });
+ d.setNeutralButton(R.string.record_new,
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ goToRecord(recordFile);
+ }
+ });
+ d.setNegativeButton(android.R.string.cancel, null);
+
+ // 顯示對話框
+ d.show();
+ }
+ // 如果沒有錄音檔,啟動錄音元件
+ else {
+ goToRecord(recordFile);
+ }
+
+ break;
+ case R.id.set_location:
+ // 啟動地圖元件用的Intent物件
+ Intent intentMap = new Intent(this, MapsActivity.class);
+
+ // 設定儲存的座標
+ intentMap.putExtra("lat", item.getLatitude());
+ intentMap.putExtra("lng", item.getLongitude());
+ intentMap.putExtra("title", item.getTitle());
+ intentMap.putExtra("datetime", item.getLocaleDatetime());
+
+ // 啟動地圖元件
+ startActivityForResult(intentMap, START_LOCATION);
+ break;
+ case R.id.set_alarm:
+ // 設定提醒日期時間
+ processSetAlarm();
+ break;
+ case R.id.select_color:
+ // 啟動設定顏色的Activity元件
+ startActivityForResult(
+ new Intent(this, ColorActivity.class), START_COLOR);
+ break;
+ }
+
+ }
+
+ // 設定提醒日期時間
+ private void processSetAlarm() {
+ Calendar calendar = Calendar.getInstance();
+
+ if (item.getAlarmDatetime() != 0) {
+ // 設定為已經儲存的提醒日期時間
+ calendar.setTimeInMillis(item.getAlarmDatetime());
+ }
+
+ // 讀取年、月、日、時、分
+ int year = calendar.get(Calendar.YEAR);
+ int month = calendar.get(Calendar.MONTH);
+ int day = calendar.get(Calendar.DAY_OF_MONTH);
+ int hour = calendar.get(Calendar.HOUR_OF_DAY);
+ int minute = calendar.get(Calendar.MINUTE);
+
+ // 儲存設定的提醒日期時間
+ final Calendar alarm = Calendar.getInstance();
+
+ // 設定提醒時間
+ TimePickerDialog.OnTimeSetListener timeSetListener =
+ new TimePickerDialog.OnTimeSetListener() {
+ @Override
+ public void onTimeSet(TimePicker view,
+ int hourOfDay, int minute) {
+ alarm.set(Calendar.HOUR_OF_DAY, hourOfDay);
+ alarm.set(Calendar.MINUTE, minute);
+
+ item.setAlarmDatetime(alarm.getTimeInMillis());
+ }
+ };
+
+ // 選擇時間對話框
+ final TimePickerDialog tpd = new TimePickerDialog(
+ this, timeSetListener, hour, minute, true);
+
+ // 設定提醒日期
+ DatePickerDialog.OnDateSetListener dateSetListener =
+ new DatePickerDialog.OnDateSetListener() {
+ @Override
+ public void onDateSet(DatePicker view,
+ int year,
+ int monthOfYear,
+ int dayOfMonth) {
+ alarm.set(Calendar.YEAR, year);
+ alarm.set(Calendar.MONTH, monthOfYear);
+ alarm.set(Calendar.DAY_OF_MONTH, dayOfMonth);
+
+ // 繼續選擇提醒時間
+ tpd.show();
+ }
+ };
+
+ // 建立與顯示選擇日期對話框
+ final DatePickerDialog dpd = new DatePickerDialog(
+ this, dateSetListener, year, month, day);
+ dpd.show();
+ }
+
+ private void goToRecord(File recordFile) {
+ // 錄音
+ Intent recordIntent = new Intent(this, RecordActivity.class);
+ recordIntent.putExtra("fileName", recordFile.getAbsolutePath());
+ startActivityForResult(recordIntent, START_RECORD);
+ }
+
+ private File configFileName(String prefix, String extension) {
+ // 如果記事資料已經有檔案名稱
+ if (item.getFileName() != null && item.getFileName().length() > 0) {
+ fileName = item.getFileName();
+ }
+ // 產生檔案名稱
+ else {
+ fileName = FileUtil.getUniqueFileName();
+ }
+
+ return new File(FileUtil.getExternalStorageDir(FileUtil.APP_DIR),
+ prefix + fileName + extension);
+ }
+
+ private File configRecFileName(String prefix, String extension) {
+ // 如果記事資料已經有檔案名稱
+ if (item.getRecFileName() != null && item.getRecFileName().length() > 0) {
+ recFileName = item.getRecFileName();
+ }
+ // 產生檔案名稱
+ else {
+ recFileName = FileUtil.getUniqueFileName();
+ }
+
+ return new File(FileUtil.getExternalStorageDir(FileUtil.APP_DIR),
+ prefix + recFileName + extension);
+ }
+
+}
diff --git a/examples/0503/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemAdapter.java b/examples/0503/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemAdapter.java
new file mode 100644
index 0000000..85b40ba
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemAdapter.java
@@ -0,0 +1,80 @@
+package net.macdidi.myandroidtutorial;
+
+import android.content.Context;
+import android.graphics.drawable.GradientDrawable;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+import java.util.List;
+
+public class ItemAdapter extends ArrayAdapter- {
+
+ // 畫面資源編號
+ private int resource;
+ // 包裝的記事資料
+ private List
- items;
+
+ public ItemAdapter(Context context, int resource, List
- items) {
+ super(context, resource, items);
+ this.resource = resource;
+ this.items = items;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ LinearLayout itemView;
+ // 讀取目前位置的記事物件
+ final Item item = getItem(position);
+
+ if (convertView == null) {
+ // 建立項目畫面元件
+ itemView = new LinearLayout(getContext());
+ String inflater = Context.LAYOUT_INFLATER_SERVICE;
+ LayoutInflater li = (LayoutInflater)
+ getContext().getSystemService(inflater);
+ li.inflate(resource, itemView, true);
+ }
+ else {
+ itemView = (LinearLayout) convertView;
+ }
+
+ // 讀取記事顏色、已選擇、標題與日期時間元件
+ RelativeLayout typeColor = (RelativeLayout) itemView.findViewById(R.id.type_color);
+ ImageView selectedItem = (ImageView) itemView.findViewById(R.id.selected_item);
+ TextView titleView = (TextView) itemView.findViewById(R.id.title_text);
+ TextView dateView = (TextView) itemView.findViewById(R.id.date_text);
+
+ // 設定記事顏色
+ GradientDrawable background = (GradientDrawable)typeColor.getBackground();
+ background.setColor(item.getColor().parseColor());
+
+ // 設定標題與日期時間
+ titleView.setText(item.getTitle());
+ dateView.setText(item.getLocaleDatetime());
+
+ // 設定是否已選擇
+ selectedItem.setVisibility(item.isSelected() ? View.VISIBLE : View.INVISIBLE);
+
+ return itemView;
+ }
+
+ // 設定指定編號的記事資料
+ public void set(int index, Item item) {
+ if (index >= 0 && index < items.size()) {
+ items.set(index, item);
+ notifyDataSetChanged();
+ }
+ }
+
+ // 讀取指定編號的記事資料
+ public Item get(int index) {
+ return items.get(index);
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0503/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemAppWidget.java b/examples/0503/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemAppWidget.java
new file mode 100644
index 0000000..9301f57
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemAppWidget.java
@@ -0,0 +1,72 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.PendingIntent;
+import android.appwidget.AppWidgetManager;
+import android.appwidget.AppWidgetProvider;
+import android.content.Context;
+import android.content.Intent;
+import android.widget.RemoteViews;
+
+
+public class ItemAppWidget extends AppWidgetProvider {
+
+ @Override
+ public void onUpdate(Context context,
+ AppWidgetManager appWidgetManager,
+ int[] appWidgetIds) {
+ final int N = appWidgetIds.length;
+
+ for (int i = 0; i < N; i++) {
+ updateAppWidget(context, appWidgetManager, appWidgetIds[i]);
+ }
+ }
+
+ @Override
+ public void onDeleted(Context context, int[] appWidgetIds) {
+ final int N = appWidgetIds.length;
+ for (int i = 0; i < N; i++) {
+ // 刪除小工具已經儲存的記事編號
+ ItemAppWidgetConfigureActivity.deleteItemPref(
+ context, appWidgetIds[i]);
+ }
+ }
+
+ @Override
+ public void onEnabled(Context context) {
+
+ }
+
+ @Override
+ public void onDisabled(Context context) {
+
+ }
+
+ static void updateAppWidget(Context context,
+ AppWidgetManager appWidgetManager,
+ int appWidgetId) {
+ // 讀取小工具儲存的記事編號
+ long id = ItemAppWidgetConfigureActivity.loadItemPref(
+ context, appWidgetId);
+ // 建立小工具畫面元件
+ RemoteViews views = new RemoteViews(
+ context.getPackageName(), R.layout.item_app_widget);
+ // 讀取指定編號的記事物件
+ ItemDAO itemDAO = new ItemDAO(context.getApplicationContext());
+ Item item = itemDAO.get(id);
+
+ // 設定小工具畫面顯示記事標題
+ views.setTextViewText(R.id.appwidget_text,
+ item != null ? item.getTitle() : "NA");
+
+ // 點選小工具畫面的記事標題後,啟動記事應用程式
+ Intent intent = new Intent(context, MainActivity.class);
+ PendingIntent pending = PendingIntent.getActivity(
+ context, 0, intent, 0);
+ views.setOnClickPendingIntent(R.id.appwidget_text, pending);
+
+ // 更新小工具
+ appWidgetManager.updateAppWidget(appWidgetId, views);
+ }
+}
+
+
diff --git a/examples/0503/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemAppWidgetConfigureActivity.java b/examples/0503/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemAppWidgetConfigureActivity.java
new file mode 100644
index 0000000..f83be71
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemAppWidgetConfigureActivity.java
@@ -0,0 +1,120 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.appwidget.AppWidgetManager;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.ListView;
+
+import java.util.List;
+
+
+public class ItemAppWidgetConfigureActivity extends Activity {
+
+ int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
+
+ private static final String PREFS_NAME =
+ "net.macdidi.myandroidtutorial.ItemAppWidget";
+ private static final String PREF_PREFIX_KEY = "appwidget_";
+
+ // 選擇小工具使用的記事項目
+ private ListView item_list;
+ private ItemAdapter itemAdapter;
+ private List
- items;
+ private ItemDAO itemDAO;
+
+ public ItemAppWidgetConfigureActivity() {
+ super();
+ }
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ setResult(RESULT_CANCELED);
+
+ // 改為使用應用程式主畫面
+ setContentView(R.layout.activity_main);
+
+ // 建立與設定選擇小工具使用的記事項目需要的物件
+ item_list = (ListView)findViewById(R.id.item_list);
+ itemDAO = new ItemDAO(getApplicationContext());
+ items = itemDAO.getAll();
+ itemAdapter = new ItemAdapter(this, R.layout.single_item, items);
+ item_list.setAdapter(itemAdapter);
+ item_list.setOnItemClickListener(itemListener);
+
+ Intent intent = getIntent();
+ Bundle extras = intent.getExtras();
+
+ if (extras != null) {
+ mAppWidgetId = extras.getInt(
+ AppWidgetManager.EXTRA_APPWIDGET_ID,
+ AppWidgetManager.INVALID_APPWIDGET_ID);
+ }
+
+ if (mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
+ finish();
+ return;
+ }
+
+ }
+
+ // 選擇記事項目
+ AdapterView.OnItemClickListener itemListener =
+ new AdapterView.OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView> parent, View view,
+ int position, long id) {
+ final Context context = ItemAppWidgetConfigureActivity.this;
+
+ // 讀取與儲存選擇的記事物件
+ Item item = itemAdapter.getItem(position);
+ saveItemPref(context, mAppWidgetId, item.getId());
+
+ AppWidgetManager appWidgetManager =
+ AppWidgetManager.getInstance(context);
+ ItemAppWidget.updateAppWidget(
+ context, appWidgetManager, mAppWidgetId);
+ Intent resultValue = new Intent();
+ resultValue.putExtra(
+ AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
+ setResult(RESULT_OK, resultValue);
+
+ finish();
+ }
+ };
+
+ // 儲存選擇的記事編號
+ static void saveItemPref(Context context, int appWidgetId, long id) {
+ SharedPreferences.Editor prefs =
+ context.getSharedPreferences(PREFS_NAME, 0).edit();
+ prefs.putLong(PREF_PREFIX_KEY + appWidgetId, id);
+ prefs.commit();
+ }
+
+ // 讀取記事編號
+ static long loadItemPref(Context context, int appWidgetId) {
+ SharedPreferences prefs =
+ context.getSharedPreferences(PREFS_NAME, 0);
+ long idValue = prefs.getLong(PREF_PREFIX_KEY + appWidgetId, 0);
+
+ return idValue;
+ }
+
+ // 刪除記事編號
+ static void deleteItemPref(Context context, int appWidgetId) {
+ SharedPreferences.Editor prefs =
+ context.getSharedPreferences(PREFS_NAME, 0).edit();
+ prefs.remove(PREF_PREFIX_KEY + appWidgetId);
+ prefs.commit();
+ }
+
+}
+
+
+
diff --git a/examples/0503/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemDAO.java b/examples/0503/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemDAO.java
new file mode 100644
index 0000000..b3c7b49
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemDAO.java
@@ -0,0 +1,214 @@
+package net.macdidi.myandroidtutorial;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+// 資料功能類別
+public class ItemDAO {
+ // 表格名稱
+ public static final String TABLE_NAME = "item";
+
+ // 編號表格欄位名稱,固定不變
+ public static final String KEY_ID = "_id";
+
+ // 其它表格欄位名稱
+ public static final String DATETIME_COLUMN = "datetime";
+ public static final String COLOR_COLUMN = "color";
+ public static final String TITLE_COLUMN = "title";
+ public static final String CONTENT_COLUMN = "content";
+ public static final String FILENAME_COLUMN = "filename";
+ public static final String RECFILENAME_COLUMN = "recfilename";
+ public static final String LATITUDE_COLUMN = "latitude";
+ public static final String LONGITUDE_COLUMN = "longitude";
+ public static final String LASTMODIFY_COLUMN = "lastmodify";
+
+ // 提醒日期時間
+ public static final String ALARMDATETIME_COLUMN = "alarmdatetime";
+
+ // 使用上面宣告的變數建立表格的SQL指令
+ public static final String CREATE_TABLE =
+ "CREATE TABLE " + TABLE_NAME + " (" +
+ KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
+ DATETIME_COLUMN + " INTEGER NOT NULL, " +
+ COLOR_COLUMN + " INTEGER NOT NULL, " +
+ TITLE_COLUMN + " TEXT NOT NULL, " +
+ CONTENT_COLUMN + " TEXT NOT NULL, " +
+ FILENAME_COLUMN + " TEXT, " +
+ RECFILENAME_COLUMN + " TEXT, " +
+ LATITUDE_COLUMN + " REAL, " +
+ LONGITUDE_COLUMN + " REAL, " +
+ LASTMODIFY_COLUMN + " INTEGER, " +
+ ALARMDATETIME_COLUMN + " INTEGER)";
+
+ // 資料庫物件
+ private SQLiteDatabase db;
+
+ // 建構子,一般的應用都不需要修改
+ public ItemDAO(Context context) {
+ db = MyDBHelper.getDatabase(context);
+ }
+
+ // 關閉資料庫,一般的應用都不需要修改
+ public void close() {
+ db.close();
+ }
+
+ // 新增參數指定的物件
+ public Item insert(Item item) {
+ // 建立準備新增資料的ContentValues物件
+ ContentValues cv = new ContentValues();
+
+ // 加入ContentValues物件包裝的新增資料
+ // 第一個參數是欄位名稱, 第二個參數是欄位的資料
+ cv.put(DATETIME_COLUMN, item.getDatetime());
+ cv.put(COLOR_COLUMN, item.getColor().parseColor());
+ cv.put(TITLE_COLUMN, item.getTitle());
+ cv.put(CONTENT_COLUMN, item.getContent());
+ cv.put(FILENAME_COLUMN, item.getFileName());
+ cv.put(RECFILENAME_COLUMN, item.getRecFileName());
+ cv.put(LATITUDE_COLUMN, item.getLatitude());
+ cv.put(LONGITUDE_COLUMN, item.getLongitude());
+ cv.put(LASTMODIFY_COLUMN, item.getLastModify());
+
+ // 提醒日期時間
+ cv.put(ALARMDATETIME_COLUMN, item.getAlarmDatetime());
+
+ // 新增一筆資料並取得編號
+ // 第一個參數是表格名稱
+ // 第二個參數是沒有指定欄位值的預設值
+ // 第三個參數是包裝新增資料的ContentValues物件
+ long id = db.insert(TABLE_NAME, null, cv);
+
+ // 設定編號
+ item.setId(id);
+ // 回傳結果
+ return item;
+ }
+
+ // 修改參數指定的物件
+ public boolean update(Item item) {
+ // 建立準備修改資料的ContentValues物件
+ ContentValues cv = new ContentValues();
+
+ // 加入ContentValues物件包裝的修改資料
+ // 第一個參數是欄位名稱, 第二個參數是欄位的資料
+ cv.put(DATETIME_COLUMN, item.getDatetime());
+ cv.put(COLOR_COLUMN, item.getColor().parseColor());
+ cv.put(TITLE_COLUMN, item.getTitle());
+ cv.put(CONTENT_COLUMN, item.getContent());
+ cv.put(FILENAME_COLUMN, item.getFileName());
+ cv.put(RECFILENAME_COLUMN, item.getRecFileName());
+ cv.put(LATITUDE_COLUMN, item.getLatitude());
+ cv.put(LONGITUDE_COLUMN, item.getLongitude());
+ cv.put(LASTMODIFY_COLUMN, item.getLastModify());
+
+ // 提醒日期時間
+ cv.put(ALARMDATETIME_COLUMN, item.getAlarmDatetime());
+
+ // 設定修改資料的條件為編號
+ // 格式為「欄位名稱=資料」
+ String where = KEY_ID + "=" + item.getId();
+
+ // 執行修改資料並回傳修改的資料數量是否成功
+ return db.update(TABLE_NAME, cv, where, null) > 0;
+ }
+
+ // 刪除參數指定編號的資料
+ public boolean delete(long id){
+ // 設定條件為編號,格式為「欄位名稱=資料」
+ String where = KEY_ID + "=" + id;
+ // 刪除指定編號資料並回傳刪除是否成功
+ return db.delete(TABLE_NAME, where , null) > 0;
+ }
+
+ // 讀取所有記事資料
+ public List
- getAll() {
+ List
- result = new ArrayList<>();
+ Cursor cursor = db.query(
+ TABLE_NAME, null, null, null, null, null, null, null);
+
+ while (cursor.moveToNext()) {
+ result.add(getRecord(cursor));
+ }
+
+ cursor.close();
+ return result;
+ }
+
+ // 取得指定編號的資料物件
+ public Item get(long id) {
+ // 準備回傳結果用的物件
+ Item item = null;
+ // 使用編號為查詢條件
+ String where = KEY_ID + "=" + id;
+ // 執行查詢
+ Cursor result = db.query(
+ TABLE_NAME, null, where, null, null, null, null, null);
+
+ // 如果有查詢結果
+ if (result.moveToFirst()) {
+ // 讀取包裝一筆資料的物件
+ item = getRecord(result);
+ }
+
+ // 關閉Cursor物件
+ result.close();
+ // 回傳結果
+ return item;
+ }
+
+ // 把Cursor目前的資料包裝為物件
+ public Item getRecord(Cursor cursor) {
+ // 準備回傳結果用的物件
+ Item result = new Item();
+
+ result.setId(cursor.getLong(0));
+ result.setDatetime(cursor.getLong(1));
+ result.setColor(ItemActivity.getColors(cursor.getInt(2)));
+ result.setTitle(cursor.getString(3));
+ result.setContent(cursor.getString(4));
+ result.setFileName(cursor.getString(5));
+ result.setRecFileName(cursor.getString(6));
+ result.setLatitude(cursor.getDouble(7));
+ result.setLongitude(cursor.getDouble(8));
+ result.setLastModify(cursor.getLong(9));
+
+ // 提醒日期時間
+ result.setAlarmDatetime(cursor.getLong(9));
+
+ // 回傳結果
+ return result;
+ }
+
+ // 取得資料數量
+ public int getCount() {
+ int result = 0;
+ Cursor cursor = db.rawQuery("SELECT COUNT(*) FROM " + TABLE_NAME, null);
+
+ if (cursor.moveToNext()) {
+ result = cursor.getInt(0);
+ }
+
+ return result;
+ }
+
+ // 建立範例資料
+ public void sample() {
+ Item item = new Item(0, new Date().getTime(), Colors.RED, "關於Android Tutorial的事情.", "Hello content", "", "", 0, 0, 0);
+ Item item2 = new Item(0, new Date().getTime(), Colors.BLUE, "一隻非常可愛的小狗狗!", "她的名字叫「大熱狗」,又叫\n作「奶嘴」,是一隻非常可愛\n的小狗。", "", "", 25.04719, 121.516981, 0);
+ Item item3 = new Item(0, new Date().getTime(), Colors.GREEN, "一首非常好聽的音樂!", "Hello content", "", "", 0, 0, 0);
+ Item item4 = new Item(0, new Date().getTime(), Colors.ORANGE, "儲存在資料庫的資料", "Hello content", "", "", 0, 0, 0);
+
+ insert(item);
+ insert(item2);
+ insert(item3);
+ insert(item4);
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0503/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MainActivity.java b/examples/0503/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MainActivity.java
new file mode 100644
index 0000000..41853df
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MainActivity.java
@@ -0,0 +1,331 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.app.AlarmManager;
+import android.app.AlertDialog;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.v7.app.ActionBarActivity;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import java.util.List;
+
+public class MainActivity extends ActionBarActivity {
+
+ private ListView item_list;
+ private TextView show_app_name;
+
+ // ListView使用的自定Adapter物件
+ private ItemAdapter itemAdapter;
+ // 儲存所有記事本的List物件
+ private List
- items;
+
+ // 選單項目物件
+ private MenuItem add_item, search_item, revert_item, share_item, delete_item;
+
+ // 已選擇項目數量
+ private int selectedCount = 0;
+
+ // 宣告資料庫功能類別欄位變數
+ private ItemDAO itemDAO;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ processViews();
+ processControllers();
+
+ // 建立資料庫物件
+ itemDAO = new ItemDAO(getApplicationContext());
+
+ // 如果資料庫是空的,就建立一些範例資料
+ // 這是為了方便測試用的,完成應用程式以後可以拿掉
+ if (itemDAO.getCount() == 0) {
+ itemDAO.sample();
+ }
+
+ // 取得所有記事資料
+ items = itemDAO.getAll();
+
+ itemAdapter = new ItemAdapter(this, R.layout.single_item, items);
+ item_list.setAdapter(itemAdapter);
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (resultCode == Activity.RESULT_OK) {
+ Item item = (Item) data.getExtras().getSerializable(
+ "net.macdidi.myandroidtutorial.Item");
+
+ // 是否修改提醒設定
+ boolean updateAlarm = false;
+
+ if (requestCode == 0) {
+ // 新增記事資料到資料庫
+ item = itemDAO.insert(item);
+
+ items.add(item);
+ itemAdapter.notifyDataSetChanged();
+ }
+ else if (requestCode == 1) {
+ int position = data.getIntExtra("position", -1);
+
+ if (position != -1) {
+ // 讀取原來的提醒設定
+ Item ori = itemDAO.get(item.getId());
+ // 判斷是否需要設定提醒
+ updateAlarm = (item.getAlarmDatetime() != ori.getAlarmDatetime());
+
+ // 修改資料庫中的記事資料
+ itemDAO.update(item);
+
+ items.set(position, item);
+ itemAdapter.notifyDataSetChanged();
+ }
+ }
+
+ // 設定提醒
+ if (item.getAlarmDatetime() != 0 && updateAlarm) {
+ Intent intent = new Intent(this, AlarmReceiver.class);
+ //intent.putExtra("title", item.getTitle());
+
+ // 加入記事編號
+ intent.putExtra("id", item.getId());
+
+ PendingIntent pi = PendingIntent.getBroadcast(
+ this, (int)item.getId(),
+ intent, PendingIntent.FLAG_ONE_SHOT);
+
+ AlarmManager am = (AlarmManager)
+ getSystemService(Context.ALARM_SERVICE);
+ am.set(AlarmManager.RTC_WAKEUP, item.getAlarmDatetime(), pi);
+ }
+ }
+ }
+
+ private void processViews() {
+ item_list = (ListView)findViewById(R.id.item_list);
+ show_app_name = (TextView) findViewById(R.id.show_app_name);
+ }
+
+ private void processControllers() {
+
+ // 建立選單項目點擊監聽物件
+ AdapterView.OnItemClickListener itemListener = new AdapterView.OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView> parent, View view,
+ int position, long id) {
+ // 讀取選擇的記事物件
+ Item item = itemAdapter.getItem(position);
+
+ // 如果已經有勾選的項目
+ if (selectedCount > 0) {
+ // 處理是否顯示已選擇項目
+ processMenu(item);
+ // 重新設定記事項目
+ itemAdapter.set(position, item);
+ }
+ else {
+ Intent intent = new Intent(
+ "net.macdidi.myandroidtutorial.EDIT_ITEM");
+
+ // 設定記事編號與記事物件
+ intent.putExtra("position", position);
+ intent.putExtra("net.macdidi.myandroidtutorial.Item", item);
+
+ startActivityForResult(intent, 1);
+ }
+ }
+ };
+
+ // 註冊選單項目點擊監聽物件
+ item_list.setOnItemClickListener(itemListener);
+
+ // 建立記事項目長按監聽物件
+ AdapterView.OnItemLongClickListener itemLongListener = new AdapterView.OnItemLongClickListener() {
+ @Override
+ public boolean onItemLongClick(AdapterView> parent, View view,
+ int position, long id) {
+ // 讀取選擇的記事物件
+ Item item = itemAdapter.getItem(position);
+ // 處理是否顯示已選擇項目
+ processMenu(item);
+ // 重新設定記事項目
+ itemAdapter.set(position, item);
+ return true;
+ }
+ };
+
+ // 註冊記事項目長按監聽物件
+ item_list.setOnItemLongClickListener(itemLongListener);
+
+ // 建立長按監聽物件
+ View.OnLongClickListener listener = new View.OnLongClickListener() {
+
+ @Override
+ public boolean onLongClick(View view) {
+ AlertDialog.Builder dialog =
+ new AlertDialog.Builder(MainActivity.this);
+ dialog.setTitle(R.string.app_name)
+ .setMessage(R.string.about)
+ .show();
+ return false;
+ }
+
+ };
+
+ // 註冊長按監聽物件
+ show_app_name.setOnLongClickListener(listener);
+ }
+
+ // 處理是否顯示已選擇項目
+ private void processMenu(Item item) {
+ // 如果需要設定記事項目
+ if (item != null) {
+ // 設定已勾選的狀態
+ item.setSelected(!item.isSelected());
+
+ // 計算已勾選數量
+ if (item.isSelected()) {
+ selectedCount++;
+ }
+ else {
+ selectedCount--;
+ }
+ }
+
+ // 根據選擇的狀況,設定是否顯示選單項目
+ add_item.setVisible(selectedCount == 0);
+ search_item.setVisible(selectedCount == 0);
+ revert_item.setVisible(selectedCount > 0);
+ share_item.setVisible(selectedCount > 0);
+ delete_item.setVisible(selectedCount > 0);
+ }
+
+ // 載入選單資源
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ MenuInflater menuInflater = getMenuInflater();
+ menuInflater.inflate(R.menu.menu_main, menu);
+
+ // 取得選單項目物件
+ add_item = menu.findItem(R.id.add_item);
+ search_item = menu.findItem(R.id.search_item);
+ revert_item = menu.findItem(R.id.revert_item);
+ share_item = menu.findItem(R.id.share_item);
+ delete_item = menu.findItem(R.id.delete_item);
+
+ // 設定選單項目
+ processMenu(null);
+
+ return true;
+ }
+
+ // 使用者選擇所有的選單項目都會呼叫這個方法
+ public void clickMenuItem(MenuItem item) {
+ // 使用參數取得使用者選擇的選單項目元件編號
+ int itemId = item.getItemId();
+
+ // 判斷該執行什麼工作,目前還沒有加入需要執行的工作
+ switch (itemId) {
+ case R.id.search_item:
+ break;
+ // 使用者選擇新增選單項目
+ case R.id.add_item:
+ // 使用Action名稱建立啟動另一個Activity元件需要的Intent物件
+ Intent intent = new Intent("net.macdidi.myandroidtutorial.ADD_ITEM");
+ // 呼叫「startActivityForResult」,,第二個參數「0」表示執行新增
+ startActivityForResult(intent, 0);
+ break;
+ // 取消所有已勾選的項目
+ case R.id.revert_item:
+ for (int i = 0; i < itemAdapter.getCount(); i++) {
+ Item ri = itemAdapter.getItem(i);
+
+ if (ri.isSelected()) {
+ ri.setSelected(false);
+ itemAdapter.set(i, ri);
+ }
+ }
+
+ selectedCount = 0;
+ processMenu(null);
+
+ break;
+ // 刪除
+ case R.id.delete_item:
+ if (selectedCount == 0) {
+ break;
+ }
+
+ AlertDialog.Builder d = new AlertDialog.Builder(this);
+ String message = getString(R.string.delete_item);
+ d.setTitle(R.string.delete)
+ .setMessage(String.format(message, selectedCount));
+ d.setPositiveButton(android.R.string.yes,
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ // 取得最後一個元素的編號
+ int index = itemAdapter.getCount() - 1;
+
+ while (index > -1) {
+ Item item = itemAdapter.get(index);
+
+ if (item.isSelected()) {
+ itemAdapter.remove(item);
+ // 刪除資料庫中的記事資料
+ itemDAO.delete(item.getId());
+ }
+
+ index--;
+ }
+
+ itemAdapter.notifyDataSetChanged();
+ selectedCount = 0;
+ processMenu(null);
+ }
+ });
+ d.setNegativeButton(android.R.string.no, null);
+ d.show();
+
+ break;
+ case R.id.googleplus_item:
+ break;
+ case R.id.facebook_item:
+ break;
+ }
+
+ }
+
+ // 方法名稱與onClick的設定一樣,參數的型態是android.view.View
+ public void aboutApp(View view) {
+ // 建立啟動另一個Activity元件需要的Intent物件
+ // 建構式的第一個參數:「this」
+ // 建構式的第二個參數:「Activity元件類別名稱.class」
+ Intent intent = new Intent(this, AboutActivity.class);
+ // 呼叫「startActivity」,參數為一個建立好的Intent物件
+ // 這行敘述執行以後,如果沒有任何錯誤,就會啟動指定的元件
+ startActivity(intent);
+ }
+
+ // 設定
+ public void clickPreferences(MenuItem item) {
+ // 啟動設定元件
+ startActivity(new Intent(this, PrefActivity.class));
+ }
+
+}
+
+
diff --git a/examples/0503/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MapsActivity.java b/examples/0503/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MapsActivity.java
new file mode 100644
index 0000000..abab911
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MapsActivity.java
@@ -0,0 +1,338 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.location.Location;
+import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
+import android.widget.Toast;
+
+import com.google.android.gms.common.ConnectionResult;
+import com.google.android.gms.common.api.GoogleApiClient;
+import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
+import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
+
+import com.google.android.gms.location.LocationListener;
+import com.google.android.gms.location.LocationRequest;
+import com.google.android.gms.location.LocationServices;
+
+import com.google.android.gms.maps.CameraUpdateFactory;
+import com.google.android.gms.maps.GoogleMap;
+import com.google.android.gms.maps.SupportMapFragment;
+import com.google.android.gms.maps.model.BitmapDescriptor;
+import com.google.android.gms.maps.model.BitmapDescriptorFactory;
+import com.google.android.gms.maps.model.CameraPosition;
+import com.google.android.gms.maps.model.LatLng;
+import com.google.android.gms.maps.model.Marker;
+import com.google.android.gms.maps.model.MarkerOptions;
+
+public class MapsActivity extends FragmentActivity
+ implements ConnectionCallbacks,
+ OnConnectionFailedListener,
+ LocationListener {
+
+ private GoogleMap mMap;
+
+ // Google API用戶端物件
+ private GoogleApiClient googleApiClient;
+
+ // Location請求物件
+ private LocationRequest locationRequest;
+
+ // 記錄目前最新的位置
+ private Location currentLocation;
+
+ // 顯示目前與儲存位置的標記物件
+ private Marker currentMarker, itemMarker;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_maps);
+ setUpMapIfNeeded();
+
+ // 建立Google API用戶端物件
+ configGoogleApiClient();
+
+ // 建立Location請求物件
+ configLocationRequest();
+
+ // 讀取記事儲存的座標
+ Intent intent = getIntent();
+ double lat = intent.getDoubleExtra("lat", 0.0);
+ double lng = intent.getDoubleExtra("lng", 0.0);
+
+ // 如果記事已經儲存座標
+ if (lat != 0.0 && lng != 0.0) {
+ // 建立座標物件
+ LatLng itemPlace = new LatLng(lat, lng);
+ // 加入地圖標記
+ addMarker(itemPlace, intent.getStringExtra("title"),
+ intent.getStringExtra("datetime"));
+ // 移動地圖
+ moveMap(itemPlace);
+ }
+ else {
+ // 連線到Google API用戶端
+ if (!googleApiClient.isConnected()) {
+ googleApiClient.connect();
+ }
+ }
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ setUpMapIfNeeded();
+
+ // 連線到Google API用戶端
+ if (!googleApiClient.isConnected() && currentMarker != null) {
+ googleApiClient.connect();
+ }
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+
+ // 移除位置請求服務
+ if (googleApiClient.isConnected()) {
+ LocationServices.FusedLocationApi.removeLocationUpdates(
+ googleApiClient, this);
+ }
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+
+ // 移除Google API用戶端連線
+ if (googleApiClient.isConnected()) {
+ googleApiClient.disconnect();
+ }
+ }
+
+ // 建立Google API用戶端物件
+ private synchronized void configGoogleApiClient() {
+ googleApiClient = new GoogleApiClient.Builder(this)
+ .addConnectionCallbacks(this)
+ .addOnConnectionFailedListener(this)
+ .addApi(LocationServices.API)
+ .build();
+ }
+
+ // 建立Location請求物件
+ private void configLocationRequest() {
+ locationRequest = new LocationRequest();
+ // 設定讀取位置資訊的間隔時間為一秒(1000ms)
+ locationRequest.setInterval(1000);
+ // 設定讀取位置資訊最快的間隔時間為一秒(1000ms)
+ locationRequest.setFastestInterval(1000);
+ // 設定優先讀取高精確度的位置資訊(GPS)
+ locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
+ }
+
+ private void setUpMapIfNeeded() {
+ if (mMap == null) {
+ mMap = ((SupportMapFragment) getSupportFragmentManager().
+ findFragmentById(R.id.map)).getMap();
+
+ if (mMap != null) {
+ // 移除地圖設定
+ //setUpMap();
+ processController();
+ }
+ }
+ }
+
+ // 移除地圖設定方法
+ private void setUpMap() {
+ // 建立位置的座標物件
+ LatLng place = new LatLng(25.033408, 121.564099);
+ // 移動地圖
+ moveMap(place);
+
+ // 加入地圖標記
+ addMarker(place, "Hello!", " Google Maps v2!");
+ }
+
+ private void processController() {
+ // 對話框按鈕事件
+ final DialogInterface.OnClickListener listener =
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ switch (which) {
+ // 更新位置資訊
+ case DialogInterface.BUTTON_POSITIVE:
+ // 連線到Google API用戶端
+ if (!googleApiClient.isConnected()) {
+ googleApiClient.connect();
+ }
+ break;
+ // 清除位置資訊
+ case DialogInterface.BUTTON_NEUTRAL:
+ Intent result = new Intent();
+ result.putExtra("lat", 0);
+ result.putExtra("lng", 0);
+ setResult(Activity.RESULT_OK, result);
+ finish();
+ break;
+ // 取消
+ case DialogInterface.BUTTON_NEGATIVE:
+ break;
+ }
+ }
+ };
+
+ // 標記訊息框點擊事件
+ mMap.setOnInfoWindowClickListener(new GoogleMap.OnInfoWindowClickListener() {
+ @Override
+ public void onInfoWindowClick(Marker marker) {
+ // 如果是記事儲存的標記
+ if (marker.equals(itemMarker)) {
+ AlertDialog.Builder ab = new AlertDialog.Builder(MapsActivity.this);
+
+ ab.setTitle(R.string.title_update_location)
+ .setMessage(R.string.message_update_location)
+ .setCancelable(true);
+
+ ab.setPositiveButton(R.string.update, listener);
+ ab.setNeutralButton(R.string.clear, listener);
+ ab.setNegativeButton(android.R.string.cancel, listener);
+
+ ab.show();
+ }
+ }
+ });
+
+ // 標記點擊事件
+ mMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
+ @Override
+ public boolean onMarkerClick(Marker marker) {
+ // 如果是目前位置標記
+ if (marker.equals(currentMarker)) {
+ AlertDialog.Builder ab = new AlertDialog.Builder(MapsActivity.this);
+
+ ab.setTitle(R.string.title_current_location)
+ .setMessage(R.string.message_current_location)
+ .setCancelable(true);
+
+ ab.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ Intent result = new Intent();
+ result.putExtra("lat", currentLocation.getLatitude());
+ result.putExtra("lng", currentLocation.getLongitude());
+ setResult(Activity.RESULT_OK, result);
+ finish();
+ }
+ });
+ ab.setNegativeButton(android.R.string.cancel, null);
+
+ ab.show();
+
+ return true;
+ }
+
+ return false;
+ }
+ });
+ }
+
+ // 移動地圖到參數指定的位置
+ private void moveMap(LatLng place) {
+ // 建立地圖攝影機的位置物件
+ CameraPosition cameraPosition =
+ new CameraPosition.Builder()
+ .target(place)
+ .zoom(17)
+ .build();
+
+ // 使用動畫的效果移動地圖
+ mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition),
+ new GoogleMap.CancelableCallback() {
+ @Override
+ public void onFinish() {
+ if (itemMarker != null) {
+ itemMarker.showInfoWindow();
+ }
+ }
+
+ @Override
+ public void onCancel() {
+
+ }
+ });
+ }
+
+ // 在地圖加入指定位置與標題的標記
+ private void addMarker(LatLng place, String title, String snippet) {
+ BitmapDescriptor icon =
+ BitmapDescriptorFactory.fromResource(R.drawable.ic_launcher);
+
+ MarkerOptions markerOptions = new MarkerOptions();
+ markerOptions.position(place)
+ .title(title)
+ .snippet(snippet)
+ .icon(icon);
+
+ // 加入並設定記事儲存的位置標記
+ itemMarker = mMap.addMarker(markerOptions);
+ }
+
+ // ConnectionCallbacks
+ @Override
+ public void onConnected(Bundle bundle) {
+ // 已經連線到Google Services
+ // 啟動位置更新服務
+ // 位置資訊更新的時候,應用程式會自動呼叫LocationListener.onLocationChanged
+ LocationServices.FusedLocationApi.requestLocationUpdates(
+ googleApiClient, locationRequest, MapsActivity.this);
+ }
+
+ // ConnectionCallbacks
+ @Override
+ public void onConnectionSuspended(int i) {
+ // Google Services連線中斷
+ // int參數是連線中斷的代號
+ }
+
+ // OnConnectionFailedListener
+ @Override
+ public void onConnectionFailed(ConnectionResult connectionResult) {
+ // Google Services連線失敗
+ // ConnectionResult參數是連線失敗的資訊
+ int errorCode = connectionResult.getErrorCode();
+
+ // 裝置沒有安裝Google Play服務
+ if (errorCode == ConnectionResult.SERVICE_MISSING) {
+ Toast.makeText(this, R.string.google_play_service_missing,
+ Toast.LENGTH_LONG).show();
+ }
+ }
+
+ // LocationListener
+ @Override
+ public void onLocationChanged(Location location) {
+ // 位置改變
+ // Location參數是目前的位置
+ currentLocation = location;
+ LatLng latLng = new LatLng(
+ location.getLatitude(), location.getLongitude());
+
+ // 設定目前位置的標記
+ if (currentMarker == null) {
+ currentMarker = mMap.addMarker(new MarkerOptions().position(latLng));
+ }
+ else {
+ currentMarker.setPosition(latLng);
+ }
+
+ // 移動地圖到目前的位置
+ moveMap(latLng);
+ }
+
+}
diff --git a/examples/0503/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MyDBHelper.java b/examples/0503/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MyDBHelper.java
new file mode 100644
index 0000000..9350577
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MyDBHelper.java
@@ -0,0 +1,47 @@
+package net.macdidi.myandroidtutorial;
+
+import android.content.Context;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteDatabase.CursorFactory;
+import android.database.sqlite.SQLiteOpenHelper;
+
+public class MyDBHelper extends SQLiteOpenHelper {
+
+ // 資料庫名稱
+ public static final String DATABASE_NAME = "mydata.db";
+ // 資料庫版本,資料結構改變的時候要更改這個數字,通常是加一
+ public static final int VERSION = 3;
+ // 資料庫物件,固定的欄位變數
+ private static SQLiteDatabase database;
+
+ // 建構子,在一般的應用都不需要修改
+ public MyDBHelper(Context context, String name, CursorFactory factory,
+ int version) {
+ super(context, name, factory, version);
+ }
+
+ // 需要資料庫的元件呼叫這個方法,這個方法在一般的應用都不需要修改
+ public static SQLiteDatabase getDatabase(Context context) {
+ if (database == null || !database.isOpen()) {
+ database = new MyDBHelper(context, DATABASE_NAME,
+ null, VERSION).getWritableDatabase();
+ }
+
+ return database;
+ }
+
+ @Override
+ public void onCreate(SQLiteDatabase db) {
+ // 建立應用程式需要的表格
+ db.execSQL(ItemDAO.CREATE_TABLE);
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ // 刪除原有的表格
+ db.execSQL("DROP TABLE IF EXISTS " + ItemDAO.TABLE_NAME);
+ // 呼叫onCreate建立新版的表格
+ onCreate(db);
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0503/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PlayActivity.java b/examples/0503/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PlayActivity.java
new file mode 100644
index 0000000..5cfb523
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PlayActivity.java
@@ -0,0 +1,64 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.media.MediaPlayer;
+import android.net.Uri;
+import android.os.Bundle;
+import android.view.View;
+
+public class PlayActivity extends Activity {
+
+ private MediaPlayer mediaPlayer;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_play);
+
+ Intent intent = getIntent();
+ String fileName = intent.getStringExtra("fileName");
+
+ // 建立指定資源的MediaPlayer物件
+ Uri uri = Uri.parse(fileName);
+ mediaPlayer = MediaPlayer.create(this, uri);
+ }
+
+ @Override
+ protected void onStop() {
+ if (mediaPlayer.isPlaying()) {
+ // 停止播放
+ mediaPlayer.stop();
+ }
+
+ // 清除MediaPlayer物件
+ mediaPlayer.release();
+ super.onStop();
+ }
+
+ public void onSubmit(View view) {
+ // 結束Activity元件
+ finish();
+ }
+
+ public void clickPlay(View view) {
+ // 開始播放
+ mediaPlayer.start();
+ }
+
+ public void clickPause(View view) {
+ // 暫停播放
+ mediaPlayer.pause();
+ }
+
+ public void clickStop(View view) {
+ // 停止播放
+ if (mediaPlayer.isPlaying()) {
+ mediaPlayer.stop();
+ }
+
+ // 回到開始的位置
+ mediaPlayer.seekTo(0);
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0503/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PrefActivity.java b/examples/0503/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PrefActivity.java
new file mode 100644
index 0000000..b2dcc4a
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PrefActivity.java
@@ -0,0 +1,38 @@
+package net.macdidi.myandroidtutorial;
+
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceManager;
+
+public class PrefActivity extends PreferenceActivity {
+
+ private SharedPreferences sharedPreferences;
+ private Preference defaultColor;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ // 指定使用的設定畫面配置資源
+ addPreferencesFromResource(R.xml.mypreference);
+ defaultColor = (Preference)findPreference("DEFAULT_COLOR");
+ // 建立SharedPreferences物件
+ sharedPreferences =
+ PreferenceManager.getDefaultSharedPreferences(this);
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ // 讀取設定的預設顏色
+ int color = sharedPreferences.getInt("DEFAULT_COLOR", -1);
+
+ if (color != -1) {
+ // 設定顏色說明
+ defaultColor.setSummary(getString(R.string.default_color_summary) +
+ ": " + ItemActivity.getColors(color));
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0503/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/RecordActivity.java b/examples/0503/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/RecordActivity.java
new file mode 100644
index 0000000..62b5e93
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/RecordActivity.java
@@ -0,0 +1,180 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.media.MediaRecorder;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.widget.ImageButton;
+import android.widget.ProgressBar;
+
+import java.io.IOException;
+
+public class RecordActivity extends Activity {
+
+ private ImageButton record_button;
+ private boolean isRecording = false;
+ private ProgressBar record_volumn;
+
+ private MyRecoder myRecoder;
+
+ private String fileName;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_record);
+
+ processViews();
+
+ // 讀取檔案名稱
+ Intent intent = getIntent();
+ fileName = intent.getStringExtra("fileName");
+ }
+
+ public void onSubmit(View view) {
+ if (isRecording) {
+ // 停止錄音
+ myRecoder.stop();
+ }
+
+ // 確定
+ if (view.getId() == R.id.record_ok) {
+ Intent result = getIntent();
+ setResult(Activity.RESULT_OK, result);
+ }
+
+ finish();
+ }
+
+ private void processViews() {
+ record_button = (ImageButton) findViewById(R.id.record_button);
+ record_volumn = (ProgressBar) findViewById(R.id.record_volumn);
+ // 隱藏狀態列ProgressBar
+ setProgressBarIndeterminateVisibility(false);
+ }
+
+ public void clickRecord(View view) {
+ // 切換
+ isRecording = !isRecording;
+
+ // 開始錄音
+ if (isRecording) {
+ // 設定按鈕圖示為錄音中
+ record_button.setImageResource(R.drawable.record_red_icon);
+ // 建立錄音物件
+ myRecoder = new MyRecoder(fileName);
+ // 開始錄音
+ myRecoder.start();
+ // 建立並執行顯示麥克風音量的AsyncTask物件
+ new MicLevelTask().execute();
+ }
+ // 停止錄音
+ else {
+ // 設定按鈕圖示為停止錄音
+ record_button.setImageResource(R.drawable.record_dark_icon);
+ // 麥克風音量歸零
+ record_volumn.setProgress(0);
+ // 停止錄音
+ myRecoder.stop();
+ }
+ }
+
+ // 在錄音過程中顯示麥克風音量
+ private class MicLevelTask extends AsyncTask
{
+ @Override
+ protected Void doInBackground(Void... args) {
+ while (isRecording) {
+ publishProgress();
+
+ try {
+ Thread.sleep(200);
+ }
+ catch (InterruptedException e) {
+ Log.d("RecordActivity", e.toString());
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ protected void onProgressUpdate(Void... values) {
+ record_volumn.setProgress((int) myRecoder.getAmplitudeEMA());
+ }
+
+ }
+
+ // 執行錄音並且可以取得麥克風音量的錄音物件
+ private class MyRecoder {
+
+ private static final double EMA_FILTER = 0.6;
+ private MediaRecorder recorder = null;
+ private double mEMA = 0.0;
+ private String output;
+
+ // 建立錄音物件,參數為錄音儲存的位置與檔名
+ MyRecoder(String output) {
+ this.output = output;
+ }
+
+ // 開始錄音
+ public void start() {
+ if (recorder == null) {
+ // 建立錄音用的MediaRecorder物件
+ recorder = new MediaRecorder();
+ // 設定錄音來源為麥克風,必須在setOutputFormat方法之前呼叫
+ recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
+ // 設定輸出格式為3GP壓縮格式,必須在setAudioSource方法之後,
+ // 在prepare方法之前呼叫
+ recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
+ // 設定錄音的編碼方式,必須在setOutputFormat方法之後,
+ // 在prepare方法之前呼叫
+ recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
+ // 設定輸出的檔案名稱,必須在setOutputFormat方法之後,
+ // 在prepare方法之前呼叫
+ recorder.setOutputFile(output);
+
+ try {
+ // 準備執行錄音工作,必須在所有設定之後呼叫
+ recorder.prepare();
+ }
+ catch (IOException e) {
+ Log.d("RecordActivity", e.toString());
+ }
+
+ // 開始錄音
+ recorder.start();
+ mEMA = 0.0;
+ }
+ }
+
+ // 停止錄音
+ public void stop() {
+ if (recorder != null) {
+ // 停止錄音
+ recorder.stop();
+ // 清除錄音資源
+ recorder.release();
+ recorder = null;
+ }
+ }
+
+ public double getAmplitude() {
+ if (recorder != null)
+ return (recorder.getMaxAmplitude() / 2700.0);
+ else
+ return 0;
+ }
+
+ // 取得麥克風音量
+ public double getAmplitudeEMA() {
+ double amp = getAmplitude();
+ mEMA = EMA_FILTER * amp + (1.0 - EMA_FILTER) * mEMA;
+ return mEMA;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0503/MyAndroidTutorial/app/src/main/res/drawable-hdpi/ic_launcher.png b/examples/0503/MyAndroidTutorial/app/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..96a442e
Binary files /dev/null and b/examples/0503/MyAndroidTutorial/app/src/main/res/drawable-hdpi/ic_launcher.png differ
diff --git a/examples/0503/MyAndroidTutorial/app/src/main/res/drawable-mdpi/ic_launcher.png b/examples/0503/MyAndroidTutorial/app/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..359047d
Binary files /dev/null and b/examples/0503/MyAndroidTutorial/app/src/main/res/drawable-mdpi/ic_launcher.png differ
diff --git a/examples/0503/MyAndroidTutorial/app/src/main/res/drawable-nodpi/example_appwidget_preview.png b/examples/0503/MyAndroidTutorial/app/src/main/res/drawable-nodpi/example_appwidget_preview.png
new file mode 100644
index 0000000..894b069
Binary files /dev/null and b/examples/0503/MyAndroidTutorial/app/src/main/res/drawable-nodpi/example_appwidget_preview.png differ
diff --git a/examples/0503/MyAndroidTutorial/app/src/main/res/drawable-xhdpi/ic_launcher.png b/examples/0503/MyAndroidTutorial/app/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..71c6d76
Binary files /dev/null and b/examples/0503/MyAndroidTutorial/app/src/main/res/drawable-xhdpi/ic_launcher.png differ
diff --git a/examples/0503/MyAndroidTutorial/app/src/main/res/drawable-xxhdpi/ic_launcher.png b/examples/0503/MyAndroidTutorial/app/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..4df1894
Binary files /dev/null and b/examples/0503/MyAndroidTutorial/app/src/main/res/drawable-xxhdpi/ic_launcher.png differ
diff --git a/examples/0503/MyAndroidTutorial/app/src/main/res/drawable/alarm_icon.png b/examples/0503/MyAndroidTutorial/app/src/main/res/drawable/alarm_icon.png
new file mode 100644
index 0000000..c6cac88
Binary files /dev/null and b/examples/0503/MyAndroidTutorial/app/src/main/res/drawable/alarm_icon.png differ
diff --git a/examples/0503/MyAndroidTutorial/app/src/main/res/drawable/item_drawable.xml b/examples/0503/MyAndroidTutorial/app/src/main/res/drawable/item_drawable.xml
new file mode 100644
index 0000000..37607e2
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/app/src/main/res/drawable/item_drawable.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0503/MyAndroidTutorial/app/src/main/res/drawable/location_icon.png b/examples/0503/MyAndroidTutorial/app/src/main/res/drawable/location_icon.png
new file mode 100644
index 0000000..4c3c514
Binary files /dev/null and b/examples/0503/MyAndroidTutorial/app/src/main/res/drawable/location_icon.png differ
diff --git a/examples/0503/MyAndroidTutorial/app/src/main/res/drawable/pause_icon.png b/examples/0503/MyAndroidTutorial/app/src/main/res/drawable/pause_icon.png
new file mode 100755
index 0000000..a5aee6f
Binary files /dev/null and b/examples/0503/MyAndroidTutorial/app/src/main/res/drawable/pause_icon.png differ
diff --git a/examples/0503/MyAndroidTutorial/app/src/main/res/drawable/play_icon.png b/examples/0503/MyAndroidTutorial/app/src/main/res/drawable/play_icon.png
new file mode 100755
index 0000000..6a40cd5
Binary files /dev/null and b/examples/0503/MyAndroidTutorial/app/src/main/res/drawable/play_icon.png differ
diff --git a/examples/0503/MyAndroidTutorial/app/src/main/res/drawable/record_dark_icon.png b/examples/0503/MyAndroidTutorial/app/src/main/res/drawable/record_dark_icon.png
new file mode 100755
index 0000000..bcf83ca
Binary files /dev/null and b/examples/0503/MyAndroidTutorial/app/src/main/res/drawable/record_dark_icon.png differ
diff --git a/examples/0503/MyAndroidTutorial/app/src/main/res/drawable/record_red_icon.png b/examples/0503/MyAndroidTutorial/app/src/main/res/drawable/record_red_icon.png
new file mode 100755
index 0000000..2b44af0
Binary files /dev/null and b/examples/0503/MyAndroidTutorial/app/src/main/res/drawable/record_red_icon.png differ
diff --git a/examples/0503/MyAndroidTutorial/app/src/main/res/drawable/record_sound_icon.png b/examples/0503/MyAndroidTutorial/app/src/main/res/drawable/record_sound_icon.png
new file mode 100755
index 0000000..a1382ac
Binary files /dev/null and b/examples/0503/MyAndroidTutorial/app/src/main/res/drawable/record_sound_icon.png differ
diff --git a/examples/0503/MyAndroidTutorial/app/src/main/res/drawable/retangle_drawable.xml b/examples/0503/MyAndroidTutorial/app/src/main/res/drawable/retangle_drawable.xml
new file mode 100644
index 0000000..51d1e84
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/app/src/main/res/drawable/retangle_drawable.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0503/MyAndroidTutorial/app/src/main/res/drawable/select_color_icon.png b/examples/0503/MyAndroidTutorial/app/src/main/res/drawable/select_color_icon.png
new file mode 100644
index 0000000..8567d5e
Binary files /dev/null and b/examples/0503/MyAndroidTutorial/app/src/main/res/drawable/select_color_icon.png differ
diff --git a/examples/0503/MyAndroidTutorial/app/src/main/res/drawable/selected_icon.png b/examples/0503/MyAndroidTutorial/app/src/main/res/drawable/selected_icon.png
new file mode 100755
index 0000000..b891571
Binary files /dev/null and b/examples/0503/MyAndroidTutorial/app/src/main/res/drawable/selected_icon.png differ
diff --git a/examples/0503/MyAndroidTutorial/app/src/main/res/drawable/stop_icon.png b/examples/0503/MyAndroidTutorial/app/src/main/res/drawable/stop_icon.png
new file mode 100755
index 0000000..20df415
Binary files /dev/null and b/examples/0503/MyAndroidTutorial/app/src/main/res/drawable/stop_icon.png differ
diff --git a/examples/0503/MyAndroidTutorial/app/src/main/res/drawable/take_picture_icon.png b/examples/0503/MyAndroidTutorial/app/src/main/res/drawable/take_picture_icon.png
new file mode 100644
index 0000000..08fb514
Binary files /dev/null and b/examples/0503/MyAndroidTutorial/app/src/main/res/drawable/take_picture_icon.png differ
diff --git a/examples/0503/MyAndroidTutorial/app/src/main/res/layout/activity_about.xml b/examples/0503/MyAndroidTutorial/app/src/main/res/layout/activity_about.xml
new file mode 100644
index 0000000..8e78611
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/app/src/main/res/layout/activity_about.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0503/MyAndroidTutorial/app/src/main/res/layout/activity_color.xml b/examples/0503/MyAndroidTutorial/app/src/main/res/layout/activity_color.xml
new file mode 100644
index 0000000..d25bbc5
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/app/src/main/res/layout/activity_color.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
diff --git a/examples/0503/MyAndroidTutorial/app/src/main/res/layout/activity_item.xml b/examples/0503/MyAndroidTutorial/app/src/main/res/layout/activity_item.xml
new file mode 100644
index 0000000..4ec4362
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/app/src/main/res/layout/activity_item.xml
@@ -0,0 +1,125 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0503/MyAndroidTutorial/app/src/main/res/layout/activity_main.xml b/examples/0503/MyAndroidTutorial/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..121511b
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
diff --git a/examples/0503/MyAndroidTutorial/app/src/main/res/layout/activity_maps.xml b/examples/0503/MyAndroidTutorial/app/src/main/res/layout/activity_maps.xml
new file mode 100644
index 0000000..5de477b
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/app/src/main/res/layout/activity_maps.xml
@@ -0,0 +1,7 @@
+
diff --git a/examples/0503/MyAndroidTutorial/app/src/main/res/layout/activity_play.xml b/examples/0503/MyAndroidTutorial/app/src/main/res/layout/activity_play.xml
new file mode 100644
index 0000000..52db308
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/app/src/main/res/layout/activity_play.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0503/MyAndroidTutorial/app/src/main/res/layout/activity_record.xml b/examples/0503/MyAndroidTutorial/app/src/main/res/layout/activity_record.xml
new file mode 100644
index 0000000..63d9e36
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/app/src/main/res/layout/activity_record.xml
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0503/MyAndroidTutorial/app/src/main/res/layout/item_app_widget.xml b/examples/0503/MyAndroidTutorial/app/src/main/res/layout/item_app_widget.xml
new file mode 100644
index 0000000..92bb45a
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/app/src/main/res/layout/item_app_widget.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0503/MyAndroidTutorial/app/src/main/res/layout/single_item.xml b/examples/0503/MyAndroidTutorial/app/src/main/res/layout/single_item.xml
new file mode 100644
index 0000000..40ddbc9
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/app/src/main/res/layout/single_item.xml
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0503/MyAndroidTutorial/app/src/main/res/menu/menu_about.xml b/examples/0503/MyAndroidTutorial/app/src/main/res/menu/menu_about.xml
new file mode 100644
index 0000000..d481100
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/app/src/main/res/menu/menu_about.xml
@@ -0,0 +1,7 @@
+
+
+
diff --git a/examples/0503/MyAndroidTutorial/app/src/main/res/menu/menu_color.xml b/examples/0503/MyAndroidTutorial/app/src/main/res/menu/menu_color.xml
new file mode 100644
index 0000000..8ff243b
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/app/src/main/res/menu/menu_color.xml
@@ -0,0 +1,7 @@
+
+
+
diff --git a/examples/0503/MyAndroidTutorial/app/src/main/res/menu/menu_item.xml b/examples/0503/MyAndroidTutorial/app/src/main/res/menu/menu_item.xml
new file mode 100644
index 0000000..cd2c9e4
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/app/src/main/res/menu/menu_item.xml
@@ -0,0 +1,7 @@
+
+
+
diff --git a/examples/0503/MyAndroidTutorial/app/src/main/res/menu/menu_main.xml b/examples/0503/MyAndroidTutorial/app/src/main/res/menu/menu_main.xml
new file mode 100644
index 0000000..0203cfa
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/app/src/main/res/menu/menu_main.xml
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
diff --git a/examples/0503/MyAndroidTutorial/app/src/main/res/values-en/strings.xml b/examples/0503/MyAndroidTutorial/app/src/main/res/values-en/strings.xml
new file mode 100644
index 0000000..c532533
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/app/src/main/res/values-en/strings.xml
@@ -0,0 +1,12 @@
+
+
+
+ MyAndroidTutorial
+ Hello world!
+ Settings
+
+ Title
+ Enter title
+ Content
+ Enter content
+
diff --git a/examples/0503/MyAndroidTutorial/app/src/main/res/values-v14/dimens.xml b/examples/0503/MyAndroidTutorial/app/src/main/res/values-v14/dimens.xml
new file mode 100644
index 0000000..4db8c59
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/app/src/main/res/values-v14/dimens.xml
@@ -0,0 +1,10 @@
+
+
+
+
+ 0dp
+
+
\ No newline at end of file
diff --git a/examples/0503/MyAndroidTutorial/app/src/main/res/values-w820dp/dimens.xml b/examples/0503/MyAndroidTutorial/app/src/main/res/values-w820dp/dimens.xml
new file mode 100644
index 0000000..63fc816
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/app/src/main/res/values-w820dp/dimens.xml
@@ -0,0 +1,6 @@
+
+
+ 64dp
+
diff --git a/examples/0503/MyAndroidTutorial/app/src/main/res/values/colors.xml b/examples/0503/MyAndroidTutorial/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..6b13c1d
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/app/src/main/res/values/colors.xml
@@ -0,0 +1,7 @@
+
+
+ #CCCCCC
+ #AAAAAA
+ #DD999999
+ #111111
+
\ No newline at end of file
diff --git a/examples/0503/MyAndroidTutorial/app/src/main/res/values/dimens.xml b/examples/0503/MyAndroidTutorial/app/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..9923269
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/app/src/main/res/values/dimens.xml
@@ -0,0 +1,15 @@
+
+
+ 16dp
+ 16dp
+
+ 6dp
+ 24sp
+ 2dp
+
+
+ 8dp
+
diff --git a/examples/0503/MyAndroidTutorial/app/src/main/res/values/strings.xml b/examples/0503/MyAndroidTutorial/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..a59f440
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/app/src/main/res/values/strings.xml
@@ -0,0 +1,59 @@
+
+
+
+ MyAndroidTutorial
+ Hello world!
+ Settings
+ 標題
+ 輸入標題
+ 內容
+ 輸入內容
+ 這是Android Tutorial應用程式
+ AboutActivity
+ 版本:AndroidTutorial_0.2.4
+ ItemActivity
+ ColorActivity
+ 刪除
+ 確定要刪除 %1$d 個項目?
+ 預設的顏色
+ 新增記事的預設顏色
+
+ 預設提醒時間
+ 在指定的時間之前通知
+
+
+ - 五分鐘
+ - 十分鐘
+ - 二十分鐘
+ - 三十分鐘
+ - 六十分鐘
+
+
+
+ - 5
+ - 10
+ - 20
+ - 30
+ - 60
+
+
+ 語音備忘
+ 播放語音備忘
+ 播放
+ 重新錄製
+ Map
+
+ 記事儲存的位置
+ 更新或清除儲存的位置資訊?
+ 更新
+ 清除
+
+ 目前位置
+ 是否儲存目前位置?
+
+ 裝置沒有安裝Google Play服務
+ EXAMPLE
+ Configure
+ Add widget
+
+
diff --git a/examples/0503/MyAndroidTutorial/app/src/main/res/values/styles.xml b/examples/0503/MyAndroidTutorial/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..766ab99
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/app/src/main/res/values/styles.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
diff --git a/examples/0503/MyAndroidTutorial/app/src/main/res/xml/item_app_widget_info.xml b/examples/0503/MyAndroidTutorial/app/src/main/res/xml/item_app_widget_info.xml
new file mode 100644
index 0000000..043d27b
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/app/src/main/res/xml/item_app_widget_info.xml
@@ -0,0 +1,15 @@
+
+
+
\ No newline at end of file
diff --git a/examples/0503/MyAndroidTutorial/app/src/main/res/xml/mypreference.xml b/examples/0503/MyAndroidTutorial/app/src/main/res/xml/mypreference.xml
new file mode 100644
index 0000000..33e714c
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/app/src/main/res/xml/mypreference.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0503/MyAndroidTutorial/app/src/release/res/values/google_maps_api.xml b/examples/0503/MyAndroidTutorial/app/src/release/res/values/google_maps_api.xml
new file mode 100644
index 0000000..c4e2431
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/app/src/release/res/values/google_maps_api.xml
@@ -0,0 +1,18 @@
+
+
+
+ YOUR_KEY_HERE
+
+
diff --git a/examples/0503/MyAndroidTutorial/build.gradle b/examples/0503/MyAndroidTutorial/build.gradle
new file mode 100644
index 0000000..6356aab
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/build.gradle
@@ -0,0 +1,19 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+ repositories {
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:1.0.0'
+
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+}
+
+allprojects {
+ repositories {
+ jcenter()
+ }
+}
diff --git a/examples/0503/MyAndroidTutorial/gradle.properties b/examples/0503/MyAndroidTutorial/gradle.properties
new file mode 100644
index 0000000..1d3591c
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/gradle.properties
@@ -0,0 +1,18 @@
+# Project-wide Gradle settings.
+
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+# Default value: -Xmx10248m -XX:MaxPermSize=256m
+# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
+
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
\ No newline at end of file
diff --git a/examples/0503/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.jar b/examples/0503/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
Binary files /dev/null and b/examples/0503/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/examples/0503/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.properties b/examples/0503/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..0c71e76
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
diff --git a/examples/0503/MyAndroidTutorial/gradlew b/examples/0503/MyAndroidTutorial/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/examples/0503/MyAndroidTutorial/gradlew.bat b/examples/0503/MyAndroidTutorial/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/examples/0503/MyAndroidTutorial/settings.gradle b/examples/0503/MyAndroidTutorial/settings.gradle
new file mode 100644
index 0000000..e7b4def
--- /dev/null
+++ b/examples/0503/MyAndroidTutorial/settings.gradle
@@ -0,0 +1 @@
+include ':app'
diff --git a/examples/0601/MyAndroidTutorial/.gitignore b/examples/0601/MyAndroidTutorial/.gitignore
new file mode 100644
index 0000000..afbdab3
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/.gitignore
@@ -0,0 +1,6 @@
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
diff --git a/examples/0601/MyAndroidTutorial/.idea/.name b/examples/0601/MyAndroidTutorial/.idea/.name
new file mode 100644
index 0000000..5bb7a85
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/.idea/.name
@@ -0,0 +1 @@
+MyAndroidTutorial
\ No newline at end of file
diff --git a/examples/0601/MyAndroidTutorial/.idea/compiler.xml b/examples/0601/MyAndroidTutorial/.idea/compiler.xml
new file mode 100644
index 0000000..9a8b7e5
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/.idea/compiler.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0601/MyAndroidTutorial/.idea/copyright/profiles_settings.xml b/examples/0601/MyAndroidTutorial/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..e7bedf3
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/examples/0601/MyAndroidTutorial/.idea/gradle.xml b/examples/0601/MyAndroidTutorial/.idea/gradle.xml
new file mode 100644
index 0000000..c595ad9
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/.idea/gradle.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0601/MyAndroidTutorial/.idea/misc.xml b/examples/0601/MyAndroidTutorial/.idea/misc.xml
new file mode 100644
index 0000000..b0c0cbc
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/.idea/misc.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0601/MyAndroidTutorial/.idea/modules.xml b/examples/0601/MyAndroidTutorial/.idea/modules.xml
new file mode 100644
index 0000000..5edca7e
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/.idea/modules.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0601/MyAndroidTutorial/.idea/vcs.xml b/examples/0601/MyAndroidTutorial/.idea/vcs.xml
new file mode 100644
index 0000000..6564d52
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0601/MyAndroidTutorial/MyAndroidTutorial.iml b/examples/0601/MyAndroidTutorial/MyAndroidTutorial.iml
new file mode 100644
index 0000000..62d899f
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/MyAndroidTutorial.iml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0601/MyAndroidTutorial/app/.gitignore b/examples/0601/MyAndroidTutorial/app/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/app/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/examples/0601/MyAndroidTutorial/app/app.iml b/examples/0601/MyAndroidTutorial/app/app.iml
new file mode 100644
index 0000000..486024a
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/app/app.iml
@@ -0,0 +1,113 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0601/MyAndroidTutorial/app/build.gradle b/examples/0601/MyAndroidTutorial/app/build.gradle
new file mode 100644
index 0000000..9423d38
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/app/build.gradle
@@ -0,0 +1,26 @@
+apply plugin: 'com.android.application'
+
+android {
+ compileSdkVersion 21
+ buildToolsVersion "21.1.2"
+
+ defaultConfig {
+ applicationId "net.macdidi.myandroidtutorial"
+ minSdkVersion 16
+ targetSdkVersion 21
+ versionCode 1
+ versionName "1.0"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ compile fileTree(dir: 'libs', include: ['*.jar'])
+ compile 'com.android.support:appcompat-v7:22.0.0'
+ compile 'com.google.android.gms:play-services:7.0.0'
+}
diff --git a/examples/0601/MyAndroidTutorial/app/proguard-rules.pro b/examples/0601/MyAndroidTutorial/app/proguard-rules.pro
new file mode 100644
index 0000000..b5fa7ec
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/app/proguard-rules.pro
@@ -0,0 +1,17 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /Users/macdidi5/Library/Android/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
diff --git a/examples/0601/MyAndroidTutorial/app/src/androidTest/java/net/macdidi/myandroidtutorial/ApplicationTest.java b/examples/0601/MyAndroidTutorial/app/src/androidTest/java/net/macdidi/myandroidtutorial/ApplicationTest.java
new file mode 100644
index 0000000..2cb214e
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/app/src/androidTest/java/net/macdidi/myandroidtutorial/ApplicationTest.java
@@ -0,0 +1,13 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Application;
+import android.test.ApplicationTestCase;
+
+/**
+ * Testing Fundamentals
+ */
+public class ApplicationTest extends ApplicationTestCase {
+ public ApplicationTest() {
+ super(Application.class);
+ }
+}
\ No newline at end of file
diff --git a/examples/0601/MyAndroidTutorial/app/src/debug/res/values/google_maps_api.xml b/examples/0601/MyAndroidTutorial/app/src/debug/res/values/google_maps_api.xml
new file mode 100644
index 0000000..7341c8d
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/app/src/debug/res/values/google_maps_api.xml
@@ -0,0 +1,18 @@
+
+
+
+ AIzaSyCZg9YWlfokPA96VxWGYr6u4C12jL16VhM
+
+
diff --git a/examples/0601/MyAndroidTutorial/app/src/main/AndroidManifest.xml b/examples/0601/MyAndroidTutorial/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..50449c2
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/app/src/main/AndroidManifest.xml
@@ -0,0 +1,128 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0601/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/AboutActivity.java b/examples/0601/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/AboutActivity.java
new file mode 100644
index 0000000..42dddeb
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/AboutActivity.java
@@ -0,0 +1,24 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.view.Window;
+
+public class AboutActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ // 取消元件的應用程式標題
+ requestWindowFeature(Window.FEATURE_NO_TITLE);
+ setContentView(R.layout.activity_about);
+ }
+
+ // 結束按鈕
+ public void clickOk(View view) {
+ // 呼叫這個方法結束Activity元件
+ finish();
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0601/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/AlarmReceiver.java b/examples/0601/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/AlarmReceiver.java
new file mode 100644
index 0000000..368165c
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/AlarmReceiver.java
@@ -0,0 +1,86 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.support.v4.app.NotificationCompat;
+
+import java.io.File;
+
+public class AlarmReceiver extends BroadcastReceiver {
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ // 讀取記事標題
+ //String title = intent.getStringExtra("title");
+ // 顯示訊息框
+ //Toast.makeText(context, title, Toast.LENGTH_LONG).show();
+
+ // 讀取記事編號
+ long id = intent.getLongExtra("id", 0);
+
+ if (id != 0) {
+ sendNotify(context, id);
+ }
+ }
+
+ private void sendNotify(Context context, long id) {
+ // 建立資料庫物件
+ ItemDAO itemDAO = new ItemDAO(context.getApplicationContext());
+ // 讀取指定編號的記事物件
+ Item item = itemDAO.get(id);
+
+ // 建立照片檔案物件
+ File file = new File(FileUtil.getExternalStorageDir(FileUtil.APP_DIR),
+ "P" + item.getFileName() + ".jpg");
+
+ // 是否儲存照片檔案
+ boolean isPicture = (item.getFileName() != null &&
+ item.getFileName().length() > 0 &&
+ file.exists());
+
+ // 取得NotificationManager物件
+ NotificationManager nm = (NotificationManager)
+ context.getSystemService(Context.NOTIFICATION_SERVICE);
+
+ // 如果有儲存照片檔案
+ if (isPicture) {
+ // 建立Notification.Builder物件,因為要設定大型圖片樣式
+ // 所以不能使用NotificationCompat.Builder
+ Notification.Builder builder = new Notification.Builder(context);
+ builder.setSmallIcon(android.R.drawable.star_on)
+ .setWhen(System.currentTimeMillis())
+ .setContentTitle(context.getString(R.string.app_name));
+
+ // 建立大型圖片樣式物件
+ Notification.BigPictureStyle bigPictureStyle =
+ new Notification.BigPictureStyle();
+ // 設定圖片與簡介
+ Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
+ bigPictureStyle.bigPicture(bitmap)
+ .setSummaryText(item.getTitle());
+ // 設定樣式為大型圖片
+ builder.setStyle(bigPictureStyle);
+ // 發出通知
+ nm.notify((int)item.getId(), builder.build());
+ }
+ // 如果沒有儲存照片檔案
+ else {
+ // 建立NotificationCompat.Builder物件
+ NotificationCompat.Builder builder =
+ new NotificationCompat.Builder(context);
+ // 設定圖示、時間、內容標題和內容訊息
+ builder.setSmallIcon(android.R.drawable.star_big_on)
+ .setWhen(System.currentTimeMillis())
+ .setContentTitle(context.getString(R.string.app_name))
+ .setContentText(item.getTitle());
+ // 發出通知
+ nm.notify((int)item.getId(), builder.build());
+ }
+ }
+
+}
diff --git a/examples/0601/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ColorActivity.java b/examples/0601/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ColorActivity.java
new file mode 100644
index 0000000..182cd55
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ColorActivity.java
@@ -0,0 +1,75 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.LinearLayout;
+
+public class ColorActivity extends Activity {
+
+ private LinearLayout color_gallery;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_color);
+
+ processViews();
+
+ ColorListener listener = new ColorListener();
+
+ for (Colors c : Colors.values()) {
+ Button button = new Button(this);
+ button.setId(c.parseColor());
+ LinearLayout.LayoutParams layout =
+ new LinearLayout.LayoutParams(128, 128);
+ layout.setMargins(6, 6, 6, 6);
+ button.setLayoutParams(layout);
+ button.setBackgroundColor(c.parseColor());
+
+ button.setOnClickListener(listener);
+
+ color_gallery.addView(button);
+ }
+ }
+
+ private void processViews() {
+ color_gallery = (LinearLayout) findViewById(R.id.color_gallery);
+ }
+
+ private class ColorListener implements OnClickListener {
+
+ @Override
+ public void onClick(View view) {
+ String action = ColorActivity.this.getIntent().getAction();
+
+ // 經由設定元件啟動
+ if (action != null &&
+ action.equals("net.macdidi.myandroidtutorial.CHOOSE_COLOR")) {
+ // 建立SharedPreferences物件
+ SharedPreferences.Editor editor =
+ PreferenceManager.getDefaultSharedPreferences(
+ ColorActivity.this).edit();
+ // 儲存預設顏色
+ editor.putInt("DEFAULT_COLOR", view.getId());
+ // 寫入設定值
+ editor.commit();
+ finish();
+ }
+ // 經由新增或修改記事的元件啟動
+ else {
+ Intent result = getIntent();
+ result.putExtra("colorId", view.getId());
+ setResult(Activity.RESULT_OK, result);
+ finish();
+ }
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0601/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Colors.java b/examples/0601/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Colors.java
new file mode 100644
index 0000000..1462149
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Colors.java
@@ -0,0 +1,24 @@
+package net.macdidi.myandroidtutorial;
+
+import android.graphics.Color;
+
+public enum Colors {
+
+ LIGHTGREY("#D3D3D3"), BLUE("#33B5E5"), PURPLE("#AA66CC"),
+ GREEN("#99CC00"), ORANGE("#FFBB33"), RED("#FF4444");
+
+ private String code;
+
+ private Colors(String code) {
+ this.code = code;
+ }
+
+ public String getCode() {
+ return code;
+ }
+
+ public int parseColor() {
+ return Color.parseColor(code);
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0601/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/FileUtil.java b/examples/0601/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/FileUtil.java
new file mode 100644
index 0000000..1fb41be
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/FileUtil.java
@@ -0,0 +1,112 @@
+package net.macdidi.myandroidtutorial;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.os.Environment;
+import android.util.Log;
+import android.widget.ImageView;
+
+import java.io.File;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+public class FileUtil {
+
+ // 應用程式儲存檔案的目錄
+ public static final String APP_DIR = "androidtutorial";
+
+ // 外部儲存設備是否可寫入
+ public static boolean isExternalStorageWritable() {
+ // 取得目前外部儲存設備的狀態
+ String state = Environment.getExternalStorageState();
+
+ // 判斷是否可寫入
+ if (Environment.MEDIA_MOUNTED.equals(state)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ // 外部儲存設備是否可讀取
+ public static boolean isExternalStorageReadable() {
+ // 取得目前外部儲存設備的狀態
+ String state = Environment.getExternalStorageState();
+
+ // 判斷是否可讀取
+ if (Environment.MEDIA_MOUNTED.equals(state) ||
+ Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ // 建立並傳回在公用相簿下參數指定的路徑
+ public static File getPublicAlbumStorageDir(String albumName) {
+ // 取得公用的照片路徑
+ File pictures = Environment.getExternalStoragePublicDirectory(
+ Environment.DIRECTORY_PICTURES);
+ // 準備在照片路徑下建立一個指定的路徑
+ File file = new File(pictures, albumName);
+
+ // 如果建立路徑不成功
+ if (!file.mkdirs()) {
+ Log.e("getAlbumStorageDir", "Directory not created");
+ }
+
+ return file;
+ }
+
+ // 建立並傳回在應用程式專用相簿下參數指定的路徑
+ public static File getAlbumStorageDir(Context context, String albumName) {
+ // 取得應用程式專用的照片路徑
+ File pictures = context.getExternalFilesDir(
+ Environment.DIRECTORY_PICTURES);
+ // 準備在照片路徑下建立一個指定的路徑
+ File file = new File(pictures, albumName);
+
+ // 如果建立路徑不成功
+ if (!file.mkdirs()) {
+ Log.e("getAlbumStorageDir", "Directory not created");
+ }
+
+ return file;
+ }
+
+ // 建立並傳回外部儲存媒體參數指定的路徑
+ public static File getExternalStorageDir(String dir) {
+ File result = new File(
+ Environment.getExternalStorageDirectory(), dir);
+
+ if (!isExternalStorageWritable()) {
+ return null;
+ }
+
+ if (!result.exists() && !result.mkdirs()) {
+ return null;
+ }
+
+ return result;
+ }
+
+ // 讀取指定的照片檔案名稱設定給ImageView元件
+ public static void fileToImageView(String fileName, ImageView imageView) {
+ if (new File(fileName).exists()) {
+ Bitmap bitmap = BitmapFactory.decodeFile(fileName);
+ imageView.setImageBitmap(bitmap);
+ }
+ else {
+ Log.e("fileToImageView", fileName + " not found.");
+ }
+ }
+
+ // 產生唯一的檔案名稱
+ public static String getUniqueFileName() {
+ // 使用年月日_時分秒格式為檔案名稱
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
+ return sdf.format(new Date());
+ }
+
+}
diff --git a/examples/0601/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/InitAlarmReceiver.java b/examples/0601/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/InitAlarmReceiver.java
new file mode 100644
index 0000000..959785f
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/InitAlarmReceiver.java
@@ -0,0 +1,49 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+import java.util.Calendar;
+import java.util.List;
+
+public class InitAlarmReceiver extends BroadcastReceiver {
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ // 建立資料庫物件
+ ItemDAO itemDAO = new ItemDAO(context.getApplicationContext());
+ // 讀取資料庫所有記事資料
+ List- items = itemDAO.getAll();
+
+ // 讀取目前時間
+ long current = Calendar.getInstance().getTimeInMillis();
+
+ AlarmManager am = (AlarmManager)
+ context.getSystemService(Context.ALARM_SERVICE);
+
+ for (Item item : items) {
+ long alarm = item.getAlarmDatetime();
+
+ // 如果沒有設定提醒或是提醒已經過期
+ if (alarm == 0 || alarm <= current) {
+ continue;
+ }
+
+ // 設定提醒
+ Intent alarmIntent = new Intent(context, AlarmReceiver.class);
+ //alarmIntent.putExtra("title", item.getTitle());
+
+ // 加入記事編號
+ intent.putExtra("id", item.getId());
+
+ PendingIntent pi = PendingIntent.getBroadcast(
+ context, (int)item.getId(),
+ alarmIntent, PendingIntent.FLAG_ONE_SHOT);
+ am.set(AlarmManager.RTC_WAKEUP, item.getAlarmDatetime(), pi);
+ }
+ }
+
+}
diff --git a/examples/0601/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Item.java b/examples/0601/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Item.java
new file mode 100644
index 0000000..e2bc93d
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Item.java
@@ -0,0 +1,156 @@
+package net.macdidi.myandroidtutorial;
+
+import java.util.Date;
+import java.util.Locale;
+
+public class Item implements java.io.Serializable {
+
+ // 編號、日期時間、顏色、標題、內容、照片檔案名稱、錄音檔案名稱、經緯度、修改、已選擇
+ private long id;
+ private long datetime;
+ private Colors color;
+ private String title;
+ private String content;
+ private String fileName;
+ private String recFileName;
+ private double latitude;
+ private double longitude;
+ private long lastModify;
+ private boolean selected;
+
+ // 提醒日期時間
+ private long alarmDatetime;
+
+ public Item() {
+ title = "";
+ content = "";
+ color = Colors.LIGHTGREY;
+ }
+
+ public Item(long id, long datetime, Colors color, String title,
+ String content, String fileName, String recFileName,
+ double latitude, double longitude, long lastModify) {
+ this.id = id;
+ this.datetime = datetime;
+ this.color = color;
+ this.title = title;
+ this.content = content;
+ this.fileName = fileName;
+ this.recFileName = recFileName;
+ this.latitude = latitude;
+ this.longitude = longitude;
+ this.lastModify = lastModify;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public long getDatetime() {
+ return datetime;
+ }
+
+ // 裝置區域的日期時間
+ public String getLocaleDatetime() {
+ return String.format(Locale.getDefault(), "%tF %
0) {
+ // 照片檔案物件
+ File file = configFileName("P", ".jpg");
+
+ // 如果照片檔案存在
+ if (file.exists()) {
+ // 顯示照片元件
+ picture.setVisibility(View.VISIBLE);
+ // 設定照片
+ FileUtil.fileToImageView(file.getAbsolutePath(), picture);
+ }
+ }
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (resultCode == Activity.RESULT_OK) {
+ switch (requestCode) {
+ // 照像
+ case START_CAMERA:
+ // 設定照片檔案名稱
+ item.setFileName(fileName);
+ break;
+ case START_RECORD:
+ // 設定錄音檔案名稱
+ item.setRecFileName(fileName);
+ break;
+ case START_LOCATION:
+ // 讀取與設定座標
+ double lat = data.getDoubleExtra("lat", 0.0);
+ double lng = data.getDoubleExtra("lng", 0.0);
+ item.setLatitude(lat);
+ item.setLongitude(lng);
+ break;
+ case START_ALARM:
+ break;
+ // 設定顏色
+ case START_COLOR:
+ int colorId = data.getIntExtra(
+ "colorId", Colors.LIGHTGREY.parseColor());
+ item.setColor(getColors(colorId));
+ break;
+ }
+ }
+ }
+
+ public static Colors getColors(int color) {
+ Colors result = Colors.LIGHTGREY;
+
+ if (color == Colors.BLUE.parseColor()) {
+ result = Colors.BLUE;
+ }
+ else if (color == Colors.PURPLE.parseColor()) {
+ result = Colors.PURPLE;
+ }
+ else if (color == Colors.GREEN.parseColor()) {
+ result = Colors.GREEN;
+ }
+ else if (color == Colors.ORANGE.parseColor()) {
+ result = Colors.ORANGE;
+ }
+ else if (color == Colors.RED.parseColor()) {
+ result = Colors.RED;
+ }
+
+ return result;
+ }
+
+ private void processViews() {
+ title_text = (EditText) findViewById(R.id.title_text);
+ content_text = (EditText) findViewById(R.id.content_text);
+ // 取得顯示照片的ImageView元件
+ picture = (ImageView) findViewById(R.id.picture);
+ }
+
+ // 點擊確定與取消按鈕都會呼叫這個方法
+ public void onSubmit(View view) {
+
+ if (view.getId() == R.id.ok_teim) {
+ String titleText = title_text.getText().toString();
+ String contentText = content_text.getText().toString();
+
+ item.setTitle(titleText);
+ item.setContent(contentText);
+
+ if (getIntent().getAction().equals(
+ "net.macdidi.myandroidtutorial.EDIT_ITEM")) {
+ item.setLastModify(new Date().getTime());
+ }
+ // 新增記事
+ else {
+ item.setDatetime(new Date().getTime());
+ }
+
+ Intent result = getIntent();
+ result.putExtra("net.macdidi.myandroidtutorial.Item", item);
+ setResult(Activity.RESULT_OK, result);
+ }
+
+ // 結束
+ finish();
+ }
+
+ public void clickFunction(View view) {
+ int id = view.getId();
+
+ switch (id) {
+ case R.id.take_picture:
+ // 啟動相機元件用的Intent物件
+ Intent intentCamera =
+ new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
+
+ // 照片檔案名稱
+ File pictureFile = configFileName("P", ".jpg");
+ Uri uri = Uri.fromFile(pictureFile);
+ // 設定檔案名稱
+ intentCamera.putExtra(MediaStore.EXTRA_OUTPUT, uri);
+ // 啟動相機元件
+ startActivityForResult(intentCamera, START_CAMERA);
+ break;
+ case R.id.record_sound:
+ // 錄音檔案名稱
+ final File recordFile = configRecFileName("R", ".mp3");
+
+ // 如果已經有錄音檔,詢問播放或重新錄製
+ if (recordFile.exists()) {
+ // 詢問播放還是重新錄製的對話框
+ AlertDialog.Builder d = new AlertDialog.Builder(this);
+
+ d.setTitle(R.string.title_record)
+ .setCancelable(false);
+ d.setPositiveButton(R.string.record_play,
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ // 播放
+ Intent playIntent = new Intent(
+ ItemActivity.this, PlayActivity.class);
+ playIntent.putExtra("fileName",
+ recordFile.getAbsolutePath());
+ startActivity(playIntent);
+ }
+ });
+ d.setNeutralButton(R.string.record_new,
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ goToRecord(recordFile);
+ }
+ });
+ d.setNegativeButton(android.R.string.cancel, null);
+
+ // 顯示對話框
+ d.show();
+ }
+ // 如果沒有錄音檔,啟動錄音元件
+ else {
+ goToRecord(recordFile);
+ }
+
+ break;
+ case R.id.set_location:
+ // 啟動地圖元件用的Intent物件
+ Intent intentMap = new Intent(this, MapsActivity.class);
+
+ // 設定儲存的座標
+ intentMap.putExtra("lat", item.getLatitude());
+ intentMap.putExtra("lng", item.getLongitude());
+ intentMap.putExtra("title", item.getTitle());
+ intentMap.putExtra("datetime", item.getLocaleDatetime());
+
+ // 啟動地圖元件
+ startActivityForResult(intentMap, START_LOCATION);
+ break;
+ case R.id.set_alarm:
+ // 設定提醒日期時間
+ processSetAlarm();
+ break;
+ case R.id.select_color:
+ // 啟動設定顏色的Activity元件
+ startActivityForResult(
+ new Intent(this, ColorActivity.class), START_COLOR);
+ break;
+ }
+
+ }
+
+ // 設定提醒日期時間
+ private void processSetAlarm() {
+ Calendar calendar = Calendar.getInstance();
+
+ if (item.getAlarmDatetime() != 0) {
+ // 設定為已經儲存的提醒日期時間
+ calendar.setTimeInMillis(item.getAlarmDatetime());
+ }
+
+ // 讀取年、月、日、時、分
+ int year = calendar.get(Calendar.YEAR);
+ int month = calendar.get(Calendar.MONTH);
+ int day = calendar.get(Calendar.DAY_OF_MONTH);
+ int hour = calendar.get(Calendar.HOUR_OF_DAY);
+ int minute = calendar.get(Calendar.MINUTE);
+
+ // 儲存設定的提醒日期時間
+ final Calendar alarm = Calendar.getInstance();
+
+ // 設定提醒時間
+ TimePickerDialog.OnTimeSetListener timeSetListener =
+ new TimePickerDialog.OnTimeSetListener() {
+ @Override
+ public void onTimeSet(TimePicker view,
+ int hourOfDay, int minute) {
+ alarm.set(Calendar.HOUR_OF_DAY, hourOfDay);
+ alarm.set(Calendar.MINUTE, minute);
+
+ item.setAlarmDatetime(alarm.getTimeInMillis());
+ }
+ };
+
+ // 選擇時間對話框
+ final TimePickerDialog tpd = new TimePickerDialog(
+ this, timeSetListener, hour, minute, true);
+
+ // 設定提醒日期
+ DatePickerDialog.OnDateSetListener dateSetListener =
+ new DatePickerDialog.OnDateSetListener() {
+ @Override
+ public void onDateSet(DatePicker view,
+ int year,
+ int monthOfYear,
+ int dayOfMonth) {
+ alarm.set(Calendar.YEAR, year);
+ alarm.set(Calendar.MONTH, monthOfYear);
+ alarm.set(Calendar.DAY_OF_MONTH, dayOfMonth);
+
+ // 繼續選擇提醒時間
+ tpd.show();
+ }
+ };
+
+ // 建立與顯示選擇日期對話框
+ final DatePickerDialog dpd = new DatePickerDialog(
+ this, dateSetListener, year, month, day);
+ dpd.show();
+ }
+
+ private void goToRecord(File recordFile) {
+ // 錄音
+ Intent recordIntent = new Intent(this, RecordActivity.class);
+ recordIntent.putExtra("fileName", recordFile.getAbsolutePath());
+ startActivityForResult(recordIntent, START_RECORD);
+ }
+
+ private File configFileName(String prefix, String extension) {
+ // 如果記事資料已經有檔案名稱
+ if (item.getFileName() != null && item.getFileName().length() > 0) {
+ fileName = item.getFileName();
+ }
+ // 產生檔案名稱
+ else {
+ fileName = FileUtil.getUniqueFileName();
+ }
+
+ return new File(FileUtil.getExternalStorageDir(FileUtil.APP_DIR),
+ prefix + fileName + extension);
+ }
+
+ private File configRecFileName(String prefix, String extension) {
+ // 如果記事資料已經有檔案名稱
+ if (item.getRecFileName() != null && item.getRecFileName().length() > 0) {
+ recFileName = item.getRecFileName();
+ }
+ // 產生檔案名稱
+ else {
+ recFileName = FileUtil.getUniqueFileName();
+ }
+
+ return new File(FileUtil.getExternalStorageDir(FileUtil.APP_DIR),
+ prefix + recFileName + extension);
+ }
+
+}
diff --git a/examples/0601/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemAdapter.java b/examples/0601/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemAdapter.java
new file mode 100644
index 0000000..85b40ba
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemAdapter.java
@@ -0,0 +1,80 @@
+package net.macdidi.myandroidtutorial;
+
+import android.content.Context;
+import android.graphics.drawable.GradientDrawable;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+import java.util.List;
+
+public class ItemAdapter extends ArrayAdapter- {
+
+ // 畫面資源編號
+ private int resource;
+ // 包裝的記事資料
+ private List
- items;
+
+ public ItemAdapter(Context context, int resource, List
- items) {
+ super(context, resource, items);
+ this.resource = resource;
+ this.items = items;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ LinearLayout itemView;
+ // 讀取目前位置的記事物件
+ final Item item = getItem(position);
+
+ if (convertView == null) {
+ // 建立項目畫面元件
+ itemView = new LinearLayout(getContext());
+ String inflater = Context.LAYOUT_INFLATER_SERVICE;
+ LayoutInflater li = (LayoutInflater)
+ getContext().getSystemService(inflater);
+ li.inflate(resource, itemView, true);
+ }
+ else {
+ itemView = (LinearLayout) convertView;
+ }
+
+ // 讀取記事顏色、已選擇、標題與日期時間元件
+ RelativeLayout typeColor = (RelativeLayout) itemView.findViewById(R.id.type_color);
+ ImageView selectedItem = (ImageView) itemView.findViewById(R.id.selected_item);
+ TextView titleView = (TextView) itemView.findViewById(R.id.title_text);
+ TextView dateView = (TextView) itemView.findViewById(R.id.date_text);
+
+ // 設定記事顏色
+ GradientDrawable background = (GradientDrawable)typeColor.getBackground();
+ background.setColor(item.getColor().parseColor());
+
+ // 設定標題與日期時間
+ titleView.setText(item.getTitle());
+ dateView.setText(item.getLocaleDatetime());
+
+ // 設定是否已選擇
+ selectedItem.setVisibility(item.isSelected() ? View.VISIBLE : View.INVISIBLE);
+
+ return itemView;
+ }
+
+ // 設定指定編號的記事資料
+ public void set(int index, Item item) {
+ if (index >= 0 && index < items.size()) {
+ items.set(index, item);
+ notifyDataSetChanged();
+ }
+ }
+
+ // 讀取指定編號的記事資料
+ public Item get(int index) {
+ return items.get(index);
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0601/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemAppWidget.java b/examples/0601/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemAppWidget.java
new file mode 100644
index 0000000..9301f57
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemAppWidget.java
@@ -0,0 +1,72 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.PendingIntent;
+import android.appwidget.AppWidgetManager;
+import android.appwidget.AppWidgetProvider;
+import android.content.Context;
+import android.content.Intent;
+import android.widget.RemoteViews;
+
+
+public class ItemAppWidget extends AppWidgetProvider {
+
+ @Override
+ public void onUpdate(Context context,
+ AppWidgetManager appWidgetManager,
+ int[] appWidgetIds) {
+ final int N = appWidgetIds.length;
+
+ for (int i = 0; i < N; i++) {
+ updateAppWidget(context, appWidgetManager, appWidgetIds[i]);
+ }
+ }
+
+ @Override
+ public void onDeleted(Context context, int[] appWidgetIds) {
+ final int N = appWidgetIds.length;
+ for (int i = 0; i < N; i++) {
+ // 刪除小工具已經儲存的記事編號
+ ItemAppWidgetConfigureActivity.deleteItemPref(
+ context, appWidgetIds[i]);
+ }
+ }
+
+ @Override
+ public void onEnabled(Context context) {
+
+ }
+
+ @Override
+ public void onDisabled(Context context) {
+
+ }
+
+ static void updateAppWidget(Context context,
+ AppWidgetManager appWidgetManager,
+ int appWidgetId) {
+ // 讀取小工具儲存的記事編號
+ long id = ItemAppWidgetConfigureActivity.loadItemPref(
+ context, appWidgetId);
+ // 建立小工具畫面元件
+ RemoteViews views = new RemoteViews(
+ context.getPackageName(), R.layout.item_app_widget);
+ // 讀取指定編號的記事物件
+ ItemDAO itemDAO = new ItemDAO(context.getApplicationContext());
+ Item item = itemDAO.get(id);
+
+ // 設定小工具畫面顯示記事標題
+ views.setTextViewText(R.id.appwidget_text,
+ item != null ? item.getTitle() : "NA");
+
+ // 點選小工具畫面的記事標題後,啟動記事應用程式
+ Intent intent = new Intent(context, MainActivity.class);
+ PendingIntent pending = PendingIntent.getActivity(
+ context, 0, intent, 0);
+ views.setOnClickPendingIntent(R.id.appwidget_text, pending);
+
+ // 更新小工具
+ appWidgetManager.updateAppWidget(appWidgetId, views);
+ }
+}
+
+
diff --git a/examples/0601/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemAppWidgetConfigureActivity.java b/examples/0601/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemAppWidgetConfigureActivity.java
new file mode 100644
index 0000000..f83be71
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemAppWidgetConfigureActivity.java
@@ -0,0 +1,120 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.appwidget.AppWidgetManager;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.ListView;
+
+import java.util.List;
+
+
+public class ItemAppWidgetConfigureActivity extends Activity {
+
+ int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
+
+ private static final String PREFS_NAME =
+ "net.macdidi.myandroidtutorial.ItemAppWidget";
+ private static final String PREF_PREFIX_KEY = "appwidget_";
+
+ // 選擇小工具使用的記事項目
+ private ListView item_list;
+ private ItemAdapter itemAdapter;
+ private List
- items;
+ private ItemDAO itemDAO;
+
+ public ItemAppWidgetConfigureActivity() {
+ super();
+ }
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ setResult(RESULT_CANCELED);
+
+ // 改為使用應用程式主畫面
+ setContentView(R.layout.activity_main);
+
+ // 建立與設定選擇小工具使用的記事項目需要的物件
+ item_list = (ListView)findViewById(R.id.item_list);
+ itemDAO = new ItemDAO(getApplicationContext());
+ items = itemDAO.getAll();
+ itemAdapter = new ItemAdapter(this, R.layout.single_item, items);
+ item_list.setAdapter(itemAdapter);
+ item_list.setOnItemClickListener(itemListener);
+
+ Intent intent = getIntent();
+ Bundle extras = intent.getExtras();
+
+ if (extras != null) {
+ mAppWidgetId = extras.getInt(
+ AppWidgetManager.EXTRA_APPWIDGET_ID,
+ AppWidgetManager.INVALID_APPWIDGET_ID);
+ }
+
+ if (mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
+ finish();
+ return;
+ }
+
+ }
+
+ // 選擇記事項目
+ AdapterView.OnItemClickListener itemListener =
+ new AdapterView.OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView> parent, View view,
+ int position, long id) {
+ final Context context = ItemAppWidgetConfigureActivity.this;
+
+ // 讀取與儲存選擇的記事物件
+ Item item = itemAdapter.getItem(position);
+ saveItemPref(context, mAppWidgetId, item.getId());
+
+ AppWidgetManager appWidgetManager =
+ AppWidgetManager.getInstance(context);
+ ItemAppWidget.updateAppWidget(
+ context, appWidgetManager, mAppWidgetId);
+ Intent resultValue = new Intent();
+ resultValue.putExtra(
+ AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
+ setResult(RESULT_OK, resultValue);
+
+ finish();
+ }
+ };
+
+ // 儲存選擇的記事編號
+ static void saveItemPref(Context context, int appWidgetId, long id) {
+ SharedPreferences.Editor prefs =
+ context.getSharedPreferences(PREFS_NAME, 0).edit();
+ prefs.putLong(PREF_PREFIX_KEY + appWidgetId, id);
+ prefs.commit();
+ }
+
+ // 讀取記事編號
+ static long loadItemPref(Context context, int appWidgetId) {
+ SharedPreferences prefs =
+ context.getSharedPreferences(PREFS_NAME, 0);
+ long idValue = prefs.getLong(PREF_PREFIX_KEY + appWidgetId, 0);
+
+ return idValue;
+ }
+
+ // 刪除記事編號
+ static void deleteItemPref(Context context, int appWidgetId) {
+ SharedPreferences.Editor prefs =
+ context.getSharedPreferences(PREFS_NAME, 0).edit();
+ prefs.remove(PREF_PREFIX_KEY + appWidgetId);
+ prefs.commit();
+ }
+
+}
+
+
+
diff --git a/examples/0601/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemDAO.java b/examples/0601/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemDAO.java
new file mode 100644
index 0000000..b3c7b49
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemDAO.java
@@ -0,0 +1,214 @@
+package net.macdidi.myandroidtutorial;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+// 資料功能類別
+public class ItemDAO {
+ // 表格名稱
+ public static final String TABLE_NAME = "item";
+
+ // 編號表格欄位名稱,固定不變
+ public static final String KEY_ID = "_id";
+
+ // 其它表格欄位名稱
+ public static final String DATETIME_COLUMN = "datetime";
+ public static final String COLOR_COLUMN = "color";
+ public static final String TITLE_COLUMN = "title";
+ public static final String CONTENT_COLUMN = "content";
+ public static final String FILENAME_COLUMN = "filename";
+ public static final String RECFILENAME_COLUMN = "recfilename";
+ public static final String LATITUDE_COLUMN = "latitude";
+ public static final String LONGITUDE_COLUMN = "longitude";
+ public static final String LASTMODIFY_COLUMN = "lastmodify";
+
+ // 提醒日期時間
+ public static final String ALARMDATETIME_COLUMN = "alarmdatetime";
+
+ // 使用上面宣告的變數建立表格的SQL指令
+ public static final String CREATE_TABLE =
+ "CREATE TABLE " + TABLE_NAME + " (" +
+ KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
+ DATETIME_COLUMN + " INTEGER NOT NULL, " +
+ COLOR_COLUMN + " INTEGER NOT NULL, " +
+ TITLE_COLUMN + " TEXT NOT NULL, " +
+ CONTENT_COLUMN + " TEXT NOT NULL, " +
+ FILENAME_COLUMN + " TEXT, " +
+ RECFILENAME_COLUMN + " TEXT, " +
+ LATITUDE_COLUMN + " REAL, " +
+ LONGITUDE_COLUMN + " REAL, " +
+ LASTMODIFY_COLUMN + " INTEGER, " +
+ ALARMDATETIME_COLUMN + " INTEGER)";
+
+ // 資料庫物件
+ private SQLiteDatabase db;
+
+ // 建構子,一般的應用都不需要修改
+ public ItemDAO(Context context) {
+ db = MyDBHelper.getDatabase(context);
+ }
+
+ // 關閉資料庫,一般的應用都不需要修改
+ public void close() {
+ db.close();
+ }
+
+ // 新增參數指定的物件
+ public Item insert(Item item) {
+ // 建立準備新增資料的ContentValues物件
+ ContentValues cv = new ContentValues();
+
+ // 加入ContentValues物件包裝的新增資料
+ // 第一個參數是欄位名稱, 第二個參數是欄位的資料
+ cv.put(DATETIME_COLUMN, item.getDatetime());
+ cv.put(COLOR_COLUMN, item.getColor().parseColor());
+ cv.put(TITLE_COLUMN, item.getTitle());
+ cv.put(CONTENT_COLUMN, item.getContent());
+ cv.put(FILENAME_COLUMN, item.getFileName());
+ cv.put(RECFILENAME_COLUMN, item.getRecFileName());
+ cv.put(LATITUDE_COLUMN, item.getLatitude());
+ cv.put(LONGITUDE_COLUMN, item.getLongitude());
+ cv.put(LASTMODIFY_COLUMN, item.getLastModify());
+
+ // 提醒日期時間
+ cv.put(ALARMDATETIME_COLUMN, item.getAlarmDatetime());
+
+ // 新增一筆資料並取得編號
+ // 第一個參數是表格名稱
+ // 第二個參數是沒有指定欄位值的預設值
+ // 第三個參數是包裝新增資料的ContentValues物件
+ long id = db.insert(TABLE_NAME, null, cv);
+
+ // 設定編號
+ item.setId(id);
+ // 回傳結果
+ return item;
+ }
+
+ // 修改參數指定的物件
+ public boolean update(Item item) {
+ // 建立準備修改資料的ContentValues物件
+ ContentValues cv = new ContentValues();
+
+ // 加入ContentValues物件包裝的修改資料
+ // 第一個參數是欄位名稱, 第二個參數是欄位的資料
+ cv.put(DATETIME_COLUMN, item.getDatetime());
+ cv.put(COLOR_COLUMN, item.getColor().parseColor());
+ cv.put(TITLE_COLUMN, item.getTitle());
+ cv.put(CONTENT_COLUMN, item.getContent());
+ cv.put(FILENAME_COLUMN, item.getFileName());
+ cv.put(RECFILENAME_COLUMN, item.getRecFileName());
+ cv.put(LATITUDE_COLUMN, item.getLatitude());
+ cv.put(LONGITUDE_COLUMN, item.getLongitude());
+ cv.put(LASTMODIFY_COLUMN, item.getLastModify());
+
+ // 提醒日期時間
+ cv.put(ALARMDATETIME_COLUMN, item.getAlarmDatetime());
+
+ // 設定修改資料的條件為編號
+ // 格式為「欄位名稱=資料」
+ String where = KEY_ID + "=" + item.getId();
+
+ // 執行修改資料並回傳修改的資料數量是否成功
+ return db.update(TABLE_NAME, cv, where, null) > 0;
+ }
+
+ // 刪除參數指定編號的資料
+ public boolean delete(long id){
+ // 設定條件為編號,格式為「欄位名稱=資料」
+ String where = KEY_ID + "=" + id;
+ // 刪除指定編號資料並回傳刪除是否成功
+ return db.delete(TABLE_NAME, where , null) > 0;
+ }
+
+ // 讀取所有記事資料
+ public List
- getAll() {
+ List
- result = new ArrayList<>();
+ Cursor cursor = db.query(
+ TABLE_NAME, null, null, null, null, null, null, null);
+
+ while (cursor.moveToNext()) {
+ result.add(getRecord(cursor));
+ }
+
+ cursor.close();
+ return result;
+ }
+
+ // 取得指定編號的資料物件
+ public Item get(long id) {
+ // 準備回傳結果用的物件
+ Item item = null;
+ // 使用編號為查詢條件
+ String where = KEY_ID + "=" + id;
+ // 執行查詢
+ Cursor result = db.query(
+ TABLE_NAME, null, where, null, null, null, null, null);
+
+ // 如果有查詢結果
+ if (result.moveToFirst()) {
+ // 讀取包裝一筆資料的物件
+ item = getRecord(result);
+ }
+
+ // 關閉Cursor物件
+ result.close();
+ // 回傳結果
+ return item;
+ }
+
+ // 把Cursor目前的資料包裝為物件
+ public Item getRecord(Cursor cursor) {
+ // 準備回傳結果用的物件
+ Item result = new Item();
+
+ result.setId(cursor.getLong(0));
+ result.setDatetime(cursor.getLong(1));
+ result.setColor(ItemActivity.getColors(cursor.getInt(2)));
+ result.setTitle(cursor.getString(3));
+ result.setContent(cursor.getString(4));
+ result.setFileName(cursor.getString(5));
+ result.setRecFileName(cursor.getString(6));
+ result.setLatitude(cursor.getDouble(7));
+ result.setLongitude(cursor.getDouble(8));
+ result.setLastModify(cursor.getLong(9));
+
+ // 提醒日期時間
+ result.setAlarmDatetime(cursor.getLong(9));
+
+ // 回傳結果
+ return result;
+ }
+
+ // 取得資料數量
+ public int getCount() {
+ int result = 0;
+ Cursor cursor = db.rawQuery("SELECT COUNT(*) FROM " + TABLE_NAME, null);
+
+ if (cursor.moveToNext()) {
+ result = cursor.getInt(0);
+ }
+
+ return result;
+ }
+
+ // 建立範例資料
+ public void sample() {
+ Item item = new Item(0, new Date().getTime(), Colors.RED, "關於Android Tutorial的事情.", "Hello content", "", "", 0, 0, 0);
+ Item item2 = new Item(0, new Date().getTime(), Colors.BLUE, "一隻非常可愛的小狗狗!", "她的名字叫「大熱狗」,又叫\n作「奶嘴」,是一隻非常可愛\n的小狗。", "", "", 25.04719, 121.516981, 0);
+ Item item3 = new Item(0, new Date().getTime(), Colors.GREEN, "一首非常好聽的音樂!", "Hello content", "", "", 0, 0, 0);
+ Item item4 = new Item(0, new Date().getTime(), Colors.ORANGE, "儲存在資料庫的資料", "Hello content", "", "", 0, 0, 0);
+
+ insert(item);
+ insert(item2);
+ insert(item3);
+ insert(item4);
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0601/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MainActivity.java b/examples/0601/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MainActivity.java
new file mode 100644
index 0000000..3434bdd
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MainActivity.java
@@ -0,0 +1,351 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.app.ActivityOptions;
+import android.app.AlarmManager;
+import android.app.AlertDialog;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.os.Build;
+import android.os.Bundle;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import java.util.List;
+
+public class MainActivity extends Activity {
+
+ private ListView item_list;
+ private TextView show_app_name;
+
+ // ListView使用的自定Adapter物件
+ private ItemAdapter itemAdapter;
+ // 儲存所有記事本的List物件
+ private List
- items;
+
+ // 選單項目物件
+ private MenuItem add_item, search_item, revert_item, share_item, delete_item;
+
+ // 已選擇項目數量
+ private int selectedCount = 0;
+
+ // 宣告資料庫功能類別欄位變數
+ private ItemDAO itemDAO;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ processViews();
+ processControllers();
+
+ // 建立資料庫物件
+ itemDAO = new ItemDAO(getApplicationContext());
+
+ // 如果資料庫是空的,就建立一些範例資料
+ // 這是為了方便測試用的,完成應用程式以後可以拿掉
+ if (itemDAO.getCount() == 0) {
+ itemDAO.sample();
+ }
+
+ // 取得所有記事資料
+ items = itemDAO.getAll();
+
+ itemAdapter = new ItemAdapter(this, R.layout.single_item, items);
+ item_list.setAdapter(itemAdapter);
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (resultCode == Activity.RESULT_OK) {
+ Item item = (Item) data.getExtras().getSerializable(
+ "net.macdidi.myandroidtutorial.Item");
+
+ // 是否修改提醒設定
+ boolean updateAlarm = false;
+
+ if (requestCode == 0) {
+ // 新增記事資料到資料庫
+ item = itemDAO.insert(item);
+
+ items.add(item);
+ itemAdapter.notifyDataSetChanged();
+ }
+ else if (requestCode == 1) {
+ int position = data.getIntExtra("position", -1);
+
+ if (position != -1) {
+ // 讀取原來的提醒設定
+ Item ori = itemDAO.get(item.getId());
+ // 判斷是否需要設定提醒
+ updateAlarm = (item.getAlarmDatetime() != ori.getAlarmDatetime());
+
+ // 修改資料庫中的記事資料
+ itemDAO.update(item);
+
+ items.set(position, item);
+ itemAdapter.notifyDataSetChanged();
+ }
+ }
+
+ // 設定提醒
+ if (item.getAlarmDatetime() != 0 && updateAlarm) {
+ Intent intent = new Intent(this, AlarmReceiver.class);
+ //intent.putExtra("title", item.getTitle());
+
+ // 加入記事編號
+ intent.putExtra("id", item.getId());
+
+ PendingIntent pi = PendingIntent.getBroadcast(
+ this, (int)item.getId(),
+ intent, PendingIntent.FLAG_ONE_SHOT);
+
+ AlarmManager am = (AlarmManager)
+ getSystemService(Context.ALARM_SERVICE);
+ am.set(AlarmManager.RTC_WAKEUP, item.getAlarmDatetime(), pi);
+ }
+ }
+ }
+
+ private void processViews() {
+ item_list = (ListView)findViewById(R.id.item_list);
+ show_app_name = (TextView) findViewById(R.id.show_app_name);
+ }
+
+ private void processControllers() {
+
+ // 建立選單項目點擊監聽物件
+ AdapterView.OnItemClickListener itemListener = new AdapterView.OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView> parent, View view,
+ int position, long id) {
+ // 讀取選擇的記事物件
+ Item item = itemAdapter.getItem(position);
+
+ // 如果已經有勾選的項目
+ if (selectedCount > 0) {
+ // 處理是否顯示已選擇項目
+ processMenu(item);
+ // 重新設定記事項目
+ itemAdapter.set(position, item);
+ }
+ else {
+ Intent intent = new Intent(
+ "net.macdidi.myandroidtutorial.EDIT_ITEM");
+
+ // 設定記事編號與記事物件
+ intent.putExtra("position", position);
+ intent.putExtra("net.macdidi.myandroidtutorial.Item", item);
+
+ // 依照版本啟動Acvitity元件
+ startActivityForVersion(intent, 1);
+ }
+ }
+ };
+
+ // 註冊選單項目點擊監聽物件
+ item_list.setOnItemClickListener(itemListener);
+
+ // 建立記事項目長按監聽物件
+ AdapterView.OnItemLongClickListener itemLongListener = new AdapterView.OnItemLongClickListener() {
+ @Override
+ public boolean onItemLongClick(AdapterView> parent, View view,
+ int position, long id) {
+ // 讀取選擇的記事物件
+ Item item = itemAdapter.getItem(position);
+ // 處理是否顯示已選擇項目
+ processMenu(item);
+ // 重新設定記事項目
+ itemAdapter.set(position, item);
+ return true;
+ }
+ };
+
+ // 註冊記事項目長按監聽物件
+ item_list.setOnItemLongClickListener(itemLongListener);
+
+ // 建立長按監聽物件
+ View.OnLongClickListener listener = new View.OnLongClickListener() {
+
+ @Override
+ public boolean onLongClick(View view) {
+ AlertDialog.Builder dialog =
+ new AlertDialog.Builder(MainActivity.this);
+ dialog.setTitle(R.string.app_name)
+ .setMessage(R.string.about)
+ .show();
+ return false;
+ }
+
+ };
+
+ // 註冊長按監聽物件
+ show_app_name.setOnLongClickListener(listener);
+ }
+
+ // 處理是否顯示已選擇項目
+ private void processMenu(Item item) {
+ // 如果需要設定記事項目
+ if (item != null) {
+ // 設定已勾選的狀態
+ item.setSelected(!item.isSelected());
+
+ // 計算已勾選數量
+ if (item.isSelected()) {
+ selectedCount++;
+ }
+ else {
+ selectedCount--;
+ }
+ }
+
+ // 根據選擇的狀況,設定是否顯示選單項目
+ add_item.setVisible(selectedCount == 0);
+ search_item.setVisible(selectedCount == 0);
+ revert_item.setVisible(selectedCount > 0);
+ share_item.setVisible(selectedCount > 0);
+ delete_item.setVisible(selectedCount > 0);
+ }
+
+ // 載入選單資源
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ MenuInflater menuInflater = getMenuInflater();
+ menuInflater.inflate(R.menu.menu_main, menu);
+
+ // 取得選單項目物件
+ add_item = menu.findItem(R.id.add_item);
+ search_item = menu.findItem(R.id.search_item);
+ revert_item = menu.findItem(R.id.revert_item);
+ share_item = menu.findItem(R.id.share_item);
+ delete_item = menu.findItem(R.id.delete_item);
+
+ // 設定選單項目
+ processMenu(null);
+
+ return true;
+ }
+
+ // 使用者選擇所有的選單項目都會呼叫這個方法
+ public void clickMenuItem(MenuItem item) {
+ // 使用參數取得使用者選擇的選單項目元件編號
+ int itemId = item.getItemId();
+
+ switch (itemId) {
+ case R.id.search_item:
+ break;
+ // 使用者選擇新增選單項目
+ case R.id.add_item:
+ // 使用Action名稱建立啟動另一個Activity元件需要的Intent物件
+ Intent intent = new Intent("net.macdidi.myandroidtutorial.ADD_ITEM");
+ // 依照版本啟動Acvitity元件
+ startActivityForVersion(intent, 0);
+ break;
+ // 取消所有已勾選的項目
+ case R.id.revert_item:
+ for (int i = 0; i < itemAdapter.getCount(); i++) {
+ Item ri = itemAdapter.getItem(i);
+
+ if (ri.isSelected()) {
+ ri.setSelected(false);
+ itemAdapter.set(i, ri);
+ }
+ }
+
+ selectedCount = 0;
+ processMenu(null);
+
+ break;
+ // 刪除
+ case R.id.delete_item:
+ if (selectedCount == 0) {
+ break;
+ }
+
+ AlertDialog.Builder d = new AlertDialog.Builder(this);
+ String message = getString(R.string.delete_item);
+ d.setTitle(R.string.delete)
+ .setMessage(String.format(message, selectedCount));
+ d.setPositiveButton(android.R.string.yes,
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ // 取得最後一個元素的編號
+ int index = itemAdapter.getCount() - 1;
+
+ while (index > -1) {
+ Item item = itemAdapter.get(index);
+
+ if (item.isSelected()) {
+ itemAdapter.remove(item);
+ // 刪除資料庫中的記事資料
+ itemDAO.delete(item.getId());
+ }
+
+ index--;
+ }
+
+ itemAdapter.notifyDataSetChanged();
+ selectedCount = 0;
+ processMenu(null);
+ }
+ });
+ d.setNegativeButton(android.R.string.no, null);
+ d.show();
+
+ break;
+ case R.id.googleplus_item:
+ break;
+ case R.id.facebook_item:
+ break;
+ }
+
+ }
+
+ public void aboutApp(View view) {
+ Intent intent = new Intent(this, AboutActivity.class);
+ startActivity(intent);
+ }
+
+ public void clickPreferences(MenuItem item) {
+ // 依照版本啟動Acvitity元件
+ startActivityForVersion(new Intent(this, PrefActivity.class));
+ }
+
+ private void startActivityForVersion(Intent intent, int requestCode) {
+ // 如果裝置的版本是LOLLIPOP
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ // 加入畫面轉換設定
+ startActivityForResult(intent, requestCode,
+ ActivityOptions.makeSceneTransitionAnimation(
+ MainActivity.this).toBundle());
+ }
+ else {
+ startActivityForResult(intent, requestCode);
+ }
+ }
+
+ private void startActivityForVersion(Intent intent) {
+ // 如果裝置的版本是LOLLIPOP
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ // 加入畫面轉換設定
+ startActivity(intent,
+ ActivityOptions.makeSceneTransitionAnimation(
+ MainActivity.this).toBundle());
+ }
+ else {
+ startActivity(intent);
+ }
+ }
+
+}
+
+
diff --git a/examples/0601/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MapsActivity.java b/examples/0601/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MapsActivity.java
new file mode 100644
index 0000000..abab911
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MapsActivity.java
@@ -0,0 +1,338 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.location.Location;
+import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
+import android.widget.Toast;
+
+import com.google.android.gms.common.ConnectionResult;
+import com.google.android.gms.common.api.GoogleApiClient;
+import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
+import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
+
+import com.google.android.gms.location.LocationListener;
+import com.google.android.gms.location.LocationRequest;
+import com.google.android.gms.location.LocationServices;
+
+import com.google.android.gms.maps.CameraUpdateFactory;
+import com.google.android.gms.maps.GoogleMap;
+import com.google.android.gms.maps.SupportMapFragment;
+import com.google.android.gms.maps.model.BitmapDescriptor;
+import com.google.android.gms.maps.model.BitmapDescriptorFactory;
+import com.google.android.gms.maps.model.CameraPosition;
+import com.google.android.gms.maps.model.LatLng;
+import com.google.android.gms.maps.model.Marker;
+import com.google.android.gms.maps.model.MarkerOptions;
+
+public class MapsActivity extends FragmentActivity
+ implements ConnectionCallbacks,
+ OnConnectionFailedListener,
+ LocationListener {
+
+ private GoogleMap mMap;
+
+ // Google API用戶端物件
+ private GoogleApiClient googleApiClient;
+
+ // Location請求物件
+ private LocationRequest locationRequest;
+
+ // 記錄目前最新的位置
+ private Location currentLocation;
+
+ // 顯示目前與儲存位置的標記物件
+ private Marker currentMarker, itemMarker;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_maps);
+ setUpMapIfNeeded();
+
+ // 建立Google API用戶端物件
+ configGoogleApiClient();
+
+ // 建立Location請求物件
+ configLocationRequest();
+
+ // 讀取記事儲存的座標
+ Intent intent = getIntent();
+ double lat = intent.getDoubleExtra("lat", 0.0);
+ double lng = intent.getDoubleExtra("lng", 0.0);
+
+ // 如果記事已經儲存座標
+ if (lat != 0.0 && lng != 0.0) {
+ // 建立座標物件
+ LatLng itemPlace = new LatLng(lat, lng);
+ // 加入地圖標記
+ addMarker(itemPlace, intent.getStringExtra("title"),
+ intent.getStringExtra("datetime"));
+ // 移動地圖
+ moveMap(itemPlace);
+ }
+ else {
+ // 連線到Google API用戶端
+ if (!googleApiClient.isConnected()) {
+ googleApiClient.connect();
+ }
+ }
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ setUpMapIfNeeded();
+
+ // 連線到Google API用戶端
+ if (!googleApiClient.isConnected() && currentMarker != null) {
+ googleApiClient.connect();
+ }
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+
+ // 移除位置請求服務
+ if (googleApiClient.isConnected()) {
+ LocationServices.FusedLocationApi.removeLocationUpdates(
+ googleApiClient, this);
+ }
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+
+ // 移除Google API用戶端連線
+ if (googleApiClient.isConnected()) {
+ googleApiClient.disconnect();
+ }
+ }
+
+ // 建立Google API用戶端物件
+ private synchronized void configGoogleApiClient() {
+ googleApiClient = new GoogleApiClient.Builder(this)
+ .addConnectionCallbacks(this)
+ .addOnConnectionFailedListener(this)
+ .addApi(LocationServices.API)
+ .build();
+ }
+
+ // 建立Location請求物件
+ private void configLocationRequest() {
+ locationRequest = new LocationRequest();
+ // 設定讀取位置資訊的間隔時間為一秒(1000ms)
+ locationRequest.setInterval(1000);
+ // 設定讀取位置資訊最快的間隔時間為一秒(1000ms)
+ locationRequest.setFastestInterval(1000);
+ // 設定優先讀取高精確度的位置資訊(GPS)
+ locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
+ }
+
+ private void setUpMapIfNeeded() {
+ if (mMap == null) {
+ mMap = ((SupportMapFragment) getSupportFragmentManager().
+ findFragmentById(R.id.map)).getMap();
+
+ if (mMap != null) {
+ // 移除地圖設定
+ //setUpMap();
+ processController();
+ }
+ }
+ }
+
+ // 移除地圖設定方法
+ private void setUpMap() {
+ // 建立位置的座標物件
+ LatLng place = new LatLng(25.033408, 121.564099);
+ // 移動地圖
+ moveMap(place);
+
+ // 加入地圖標記
+ addMarker(place, "Hello!", " Google Maps v2!");
+ }
+
+ private void processController() {
+ // 對話框按鈕事件
+ final DialogInterface.OnClickListener listener =
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ switch (which) {
+ // 更新位置資訊
+ case DialogInterface.BUTTON_POSITIVE:
+ // 連線到Google API用戶端
+ if (!googleApiClient.isConnected()) {
+ googleApiClient.connect();
+ }
+ break;
+ // 清除位置資訊
+ case DialogInterface.BUTTON_NEUTRAL:
+ Intent result = new Intent();
+ result.putExtra("lat", 0);
+ result.putExtra("lng", 0);
+ setResult(Activity.RESULT_OK, result);
+ finish();
+ break;
+ // 取消
+ case DialogInterface.BUTTON_NEGATIVE:
+ break;
+ }
+ }
+ };
+
+ // 標記訊息框點擊事件
+ mMap.setOnInfoWindowClickListener(new GoogleMap.OnInfoWindowClickListener() {
+ @Override
+ public void onInfoWindowClick(Marker marker) {
+ // 如果是記事儲存的標記
+ if (marker.equals(itemMarker)) {
+ AlertDialog.Builder ab = new AlertDialog.Builder(MapsActivity.this);
+
+ ab.setTitle(R.string.title_update_location)
+ .setMessage(R.string.message_update_location)
+ .setCancelable(true);
+
+ ab.setPositiveButton(R.string.update, listener);
+ ab.setNeutralButton(R.string.clear, listener);
+ ab.setNegativeButton(android.R.string.cancel, listener);
+
+ ab.show();
+ }
+ }
+ });
+
+ // 標記點擊事件
+ mMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
+ @Override
+ public boolean onMarkerClick(Marker marker) {
+ // 如果是目前位置標記
+ if (marker.equals(currentMarker)) {
+ AlertDialog.Builder ab = new AlertDialog.Builder(MapsActivity.this);
+
+ ab.setTitle(R.string.title_current_location)
+ .setMessage(R.string.message_current_location)
+ .setCancelable(true);
+
+ ab.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ Intent result = new Intent();
+ result.putExtra("lat", currentLocation.getLatitude());
+ result.putExtra("lng", currentLocation.getLongitude());
+ setResult(Activity.RESULT_OK, result);
+ finish();
+ }
+ });
+ ab.setNegativeButton(android.R.string.cancel, null);
+
+ ab.show();
+
+ return true;
+ }
+
+ return false;
+ }
+ });
+ }
+
+ // 移動地圖到參數指定的位置
+ private void moveMap(LatLng place) {
+ // 建立地圖攝影機的位置物件
+ CameraPosition cameraPosition =
+ new CameraPosition.Builder()
+ .target(place)
+ .zoom(17)
+ .build();
+
+ // 使用動畫的效果移動地圖
+ mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition),
+ new GoogleMap.CancelableCallback() {
+ @Override
+ public void onFinish() {
+ if (itemMarker != null) {
+ itemMarker.showInfoWindow();
+ }
+ }
+
+ @Override
+ public void onCancel() {
+
+ }
+ });
+ }
+
+ // 在地圖加入指定位置與標題的標記
+ private void addMarker(LatLng place, String title, String snippet) {
+ BitmapDescriptor icon =
+ BitmapDescriptorFactory.fromResource(R.drawable.ic_launcher);
+
+ MarkerOptions markerOptions = new MarkerOptions();
+ markerOptions.position(place)
+ .title(title)
+ .snippet(snippet)
+ .icon(icon);
+
+ // 加入並設定記事儲存的位置標記
+ itemMarker = mMap.addMarker(markerOptions);
+ }
+
+ // ConnectionCallbacks
+ @Override
+ public void onConnected(Bundle bundle) {
+ // 已經連線到Google Services
+ // 啟動位置更新服務
+ // 位置資訊更新的時候,應用程式會自動呼叫LocationListener.onLocationChanged
+ LocationServices.FusedLocationApi.requestLocationUpdates(
+ googleApiClient, locationRequest, MapsActivity.this);
+ }
+
+ // ConnectionCallbacks
+ @Override
+ public void onConnectionSuspended(int i) {
+ // Google Services連線中斷
+ // int參數是連線中斷的代號
+ }
+
+ // OnConnectionFailedListener
+ @Override
+ public void onConnectionFailed(ConnectionResult connectionResult) {
+ // Google Services連線失敗
+ // ConnectionResult參數是連線失敗的資訊
+ int errorCode = connectionResult.getErrorCode();
+
+ // 裝置沒有安裝Google Play服務
+ if (errorCode == ConnectionResult.SERVICE_MISSING) {
+ Toast.makeText(this, R.string.google_play_service_missing,
+ Toast.LENGTH_LONG).show();
+ }
+ }
+
+ // LocationListener
+ @Override
+ public void onLocationChanged(Location location) {
+ // 位置改變
+ // Location參數是目前的位置
+ currentLocation = location;
+ LatLng latLng = new LatLng(
+ location.getLatitude(), location.getLongitude());
+
+ // 設定目前位置的標記
+ if (currentMarker == null) {
+ currentMarker = mMap.addMarker(new MarkerOptions().position(latLng));
+ }
+ else {
+ currentMarker.setPosition(latLng);
+ }
+
+ // 移動地圖到目前的位置
+ moveMap(latLng);
+ }
+
+}
diff --git a/examples/0601/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MyDBHelper.java b/examples/0601/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MyDBHelper.java
new file mode 100644
index 0000000..9350577
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MyDBHelper.java
@@ -0,0 +1,47 @@
+package net.macdidi.myandroidtutorial;
+
+import android.content.Context;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteDatabase.CursorFactory;
+import android.database.sqlite.SQLiteOpenHelper;
+
+public class MyDBHelper extends SQLiteOpenHelper {
+
+ // 資料庫名稱
+ public static final String DATABASE_NAME = "mydata.db";
+ // 資料庫版本,資料結構改變的時候要更改這個數字,通常是加一
+ public static final int VERSION = 3;
+ // 資料庫物件,固定的欄位變數
+ private static SQLiteDatabase database;
+
+ // 建構子,在一般的應用都不需要修改
+ public MyDBHelper(Context context, String name, CursorFactory factory,
+ int version) {
+ super(context, name, factory, version);
+ }
+
+ // 需要資料庫的元件呼叫這個方法,這個方法在一般的應用都不需要修改
+ public static SQLiteDatabase getDatabase(Context context) {
+ if (database == null || !database.isOpen()) {
+ database = new MyDBHelper(context, DATABASE_NAME,
+ null, VERSION).getWritableDatabase();
+ }
+
+ return database;
+ }
+
+ @Override
+ public void onCreate(SQLiteDatabase db) {
+ // 建立應用程式需要的表格
+ db.execSQL(ItemDAO.CREATE_TABLE);
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ // 刪除原有的表格
+ db.execSQL("DROP TABLE IF EXISTS " + ItemDAO.TABLE_NAME);
+ // 呼叫onCreate建立新版的表格
+ onCreate(db);
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0601/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PlayActivity.java b/examples/0601/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PlayActivity.java
new file mode 100644
index 0000000..5cfb523
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PlayActivity.java
@@ -0,0 +1,64 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.media.MediaPlayer;
+import android.net.Uri;
+import android.os.Bundle;
+import android.view.View;
+
+public class PlayActivity extends Activity {
+
+ private MediaPlayer mediaPlayer;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_play);
+
+ Intent intent = getIntent();
+ String fileName = intent.getStringExtra("fileName");
+
+ // 建立指定資源的MediaPlayer物件
+ Uri uri = Uri.parse(fileName);
+ mediaPlayer = MediaPlayer.create(this, uri);
+ }
+
+ @Override
+ protected void onStop() {
+ if (mediaPlayer.isPlaying()) {
+ // 停止播放
+ mediaPlayer.stop();
+ }
+
+ // 清除MediaPlayer物件
+ mediaPlayer.release();
+ super.onStop();
+ }
+
+ public void onSubmit(View view) {
+ // 結束Activity元件
+ finish();
+ }
+
+ public void clickPlay(View view) {
+ // 開始播放
+ mediaPlayer.start();
+ }
+
+ public void clickPause(View view) {
+ // 暫停播放
+ mediaPlayer.pause();
+ }
+
+ public void clickStop(View view) {
+ // 停止播放
+ if (mediaPlayer.isPlaying()) {
+ mediaPlayer.stop();
+ }
+
+ // 回到開始的位置
+ mediaPlayer.seekTo(0);
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0601/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PrefActivity.java b/examples/0601/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PrefActivity.java
new file mode 100644
index 0000000..b2dcc4a
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PrefActivity.java
@@ -0,0 +1,38 @@
+package net.macdidi.myandroidtutorial;
+
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceManager;
+
+public class PrefActivity extends PreferenceActivity {
+
+ private SharedPreferences sharedPreferences;
+ private Preference defaultColor;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ // 指定使用的設定畫面配置資源
+ addPreferencesFromResource(R.xml.mypreference);
+ defaultColor = (Preference)findPreference("DEFAULT_COLOR");
+ // 建立SharedPreferences物件
+ sharedPreferences =
+ PreferenceManager.getDefaultSharedPreferences(this);
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ // 讀取設定的預設顏色
+ int color = sharedPreferences.getInt("DEFAULT_COLOR", -1);
+
+ if (color != -1) {
+ // 設定顏色說明
+ defaultColor.setSummary(getString(R.string.default_color_summary) +
+ ": " + ItemActivity.getColors(color));
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0601/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/RecordActivity.java b/examples/0601/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/RecordActivity.java
new file mode 100644
index 0000000..62b5e93
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/RecordActivity.java
@@ -0,0 +1,180 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.media.MediaRecorder;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.widget.ImageButton;
+import android.widget.ProgressBar;
+
+import java.io.IOException;
+
+public class RecordActivity extends Activity {
+
+ private ImageButton record_button;
+ private boolean isRecording = false;
+ private ProgressBar record_volumn;
+
+ private MyRecoder myRecoder;
+
+ private String fileName;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_record);
+
+ processViews();
+
+ // 讀取檔案名稱
+ Intent intent = getIntent();
+ fileName = intent.getStringExtra("fileName");
+ }
+
+ public void onSubmit(View view) {
+ if (isRecording) {
+ // 停止錄音
+ myRecoder.stop();
+ }
+
+ // 確定
+ if (view.getId() == R.id.record_ok) {
+ Intent result = getIntent();
+ setResult(Activity.RESULT_OK, result);
+ }
+
+ finish();
+ }
+
+ private void processViews() {
+ record_button = (ImageButton) findViewById(R.id.record_button);
+ record_volumn = (ProgressBar) findViewById(R.id.record_volumn);
+ // 隱藏狀態列ProgressBar
+ setProgressBarIndeterminateVisibility(false);
+ }
+
+ public void clickRecord(View view) {
+ // 切換
+ isRecording = !isRecording;
+
+ // 開始錄音
+ if (isRecording) {
+ // 設定按鈕圖示為錄音中
+ record_button.setImageResource(R.drawable.record_red_icon);
+ // 建立錄音物件
+ myRecoder = new MyRecoder(fileName);
+ // 開始錄音
+ myRecoder.start();
+ // 建立並執行顯示麥克風音量的AsyncTask物件
+ new MicLevelTask().execute();
+ }
+ // 停止錄音
+ else {
+ // 設定按鈕圖示為停止錄音
+ record_button.setImageResource(R.drawable.record_dark_icon);
+ // 麥克風音量歸零
+ record_volumn.setProgress(0);
+ // 停止錄音
+ myRecoder.stop();
+ }
+ }
+
+ // 在錄音過程中顯示麥克風音量
+ private class MicLevelTask extends AsyncTask
{
+ @Override
+ protected Void doInBackground(Void... args) {
+ while (isRecording) {
+ publishProgress();
+
+ try {
+ Thread.sleep(200);
+ }
+ catch (InterruptedException e) {
+ Log.d("RecordActivity", e.toString());
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ protected void onProgressUpdate(Void... values) {
+ record_volumn.setProgress((int) myRecoder.getAmplitudeEMA());
+ }
+
+ }
+
+ // 執行錄音並且可以取得麥克風音量的錄音物件
+ private class MyRecoder {
+
+ private static final double EMA_FILTER = 0.6;
+ private MediaRecorder recorder = null;
+ private double mEMA = 0.0;
+ private String output;
+
+ // 建立錄音物件,參數為錄音儲存的位置與檔名
+ MyRecoder(String output) {
+ this.output = output;
+ }
+
+ // 開始錄音
+ public void start() {
+ if (recorder == null) {
+ // 建立錄音用的MediaRecorder物件
+ recorder = new MediaRecorder();
+ // 設定錄音來源為麥克風,必須在setOutputFormat方法之前呼叫
+ recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
+ // 設定輸出格式為3GP壓縮格式,必須在setAudioSource方法之後,
+ // 在prepare方法之前呼叫
+ recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
+ // 設定錄音的編碼方式,必須在setOutputFormat方法之後,
+ // 在prepare方法之前呼叫
+ recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
+ // 設定輸出的檔案名稱,必須在setOutputFormat方法之後,
+ // 在prepare方法之前呼叫
+ recorder.setOutputFile(output);
+
+ try {
+ // 準備執行錄音工作,必須在所有設定之後呼叫
+ recorder.prepare();
+ }
+ catch (IOException e) {
+ Log.d("RecordActivity", e.toString());
+ }
+
+ // 開始錄音
+ recorder.start();
+ mEMA = 0.0;
+ }
+ }
+
+ // 停止錄音
+ public void stop() {
+ if (recorder != null) {
+ // 停止錄音
+ recorder.stop();
+ // 清除錄音資源
+ recorder.release();
+ recorder = null;
+ }
+ }
+
+ public double getAmplitude() {
+ if (recorder != null)
+ return (recorder.getMaxAmplitude() / 2700.0);
+ else
+ return 0;
+ }
+
+ // 取得麥克風音量
+ public double getAmplitudeEMA() {
+ double amp = getAmplitude();
+ mEMA = EMA_FILTER * amp + (1.0 - EMA_FILTER) * mEMA;
+ return mEMA;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0601/MyAndroidTutorial/app/src/main/res/drawable-hdpi/ic_launcher.png b/examples/0601/MyAndroidTutorial/app/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..96a442e
Binary files /dev/null and b/examples/0601/MyAndroidTutorial/app/src/main/res/drawable-hdpi/ic_launcher.png differ
diff --git a/examples/0601/MyAndroidTutorial/app/src/main/res/drawable-mdpi/ic_launcher.png b/examples/0601/MyAndroidTutorial/app/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..359047d
Binary files /dev/null and b/examples/0601/MyAndroidTutorial/app/src/main/res/drawable-mdpi/ic_launcher.png differ
diff --git a/examples/0601/MyAndroidTutorial/app/src/main/res/drawable-nodpi/example_appwidget_preview.png b/examples/0601/MyAndroidTutorial/app/src/main/res/drawable-nodpi/example_appwidget_preview.png
new file mode 100644
index 0000000..894b069
Binary files /dev/null and b/examples/0601/MyAndroidTutorial/app/src/main/res/drawable-nodpi/example_appwidget_preview.png differ
diff --git a/examples/0601/MyAndroidTutorial/app/src/main/res/drawable-xhdpi/ic_launcher.png b/examples/0601/MyAndroidTutorial/app/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..71c6d76
Binary files /dev/null and b/examples/0601/MyAndroidTutorial/app/src/main/res/drawable-xhdpi/ic_launcher.png differ
diff --git a/examples/0601/MyAndroidTutorial/app/src/main/res/drawable-xxhdpi/ic_launcher.png b/examples/0601/MyAndroidTutorial/app/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..4df1894
Binary files /dev/null and b/examples/0601/MyAndroidTutorial/app/src/main/res/drawable-xxhdpi/ic_launcher.png differ
diff --git a/examples/0601/MyAndroidTutorial/app/src/main/res/drawable/alarm_icon.png b/examples/0601/MyAndroidTutorial/app/src/main/res/drawable/alarm_icon.png
new file mode 100644
index 0000000..c6cac88
Binary files /dev/null and b/examples/0601/MyAndroidTutorial/app/src/main/res/drawable/alarm_icon.png differ
diff --git a/examples/0601/MyAndroidTutorial/app/src/main/res/drawable/item_drawable.xml b/examples/0601/MyAndroidTutorial/app/src/main/res/drawable/item_drawable.xml
new file mode 100644
index 0000000..37607e2
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/app/src/main/res/drawable/item_drawable.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0601/MyAndroidTutorial/app/src/main/res/drawable/location_icon.png b/examples/0601/MyAndroidTutorial/app/src/main/res/drawable/location_icon.png
new file mode 100644
index 0000000..4c3c514
Binary files /dev/null and b/examples/0601/MyAndroidTutorial/app/src/main/res/drawable/location_icon.png differ
diff --git a/examples/0601/MyAndroidTutorial/app/src/main/res/drawable/pause_icon.png b/examples/0601/MyAndroidTutorial/app/src/main/res/drawable/pause_icon.png
new file mode 100755
index 0000000..a5aee6f
Binary files /dev/null and b/examples/0601/MyAndroidTutorial/app/src/main/res/drawable/pause_icon.png differ
diff --git a/examples/0601/MyAndroidTutorial/app/src/main/res/drawable/play_icon.png b/examples/0601/MyAndroidTutorial/app/src/main/res/drawable/play_icon.png
new file mode 100755
index 0000000..6a40cd5
Binary files /dev/null and b/examples/0601/MyAndroidTutorial/app/src/main/res/drawable/play_icon.png differ
diff --git a/examples/0601/MyAndroidTutorial/app/src/main/res/drawable/record_dark_icon.png b/examples/0601/MyAndroidTutorial/app/src/main/res/drawable/record_dark_icon.png
new file mode 100755
index 0000000..bcf83ca
Binary files /dev/null and b/examples/0601/MyAndroidTutorial/app/src/main/res/drawable/record_dark_icon.png differ
diff --git a/examples/0601/MyAndroidTutorial/app/src/main/res/drawable/record_red_icon.png b/examples/0601/MyAndroidTutorial/app/src/main/res/drawable/record_red_icon.png
new file mode 100755
index 0000000..2b44af0
Binary files /dev/null and b/examples/0601/MyAndroidTutorial/app/src/main/res/drawable/record_red_icon.png differ
diff --git a/examples/0601/MyAndroidTutorial/app/src/main/res/drawable/record_sound_icon.png b/examples/0601/MyAndroidTutorial/app/src/main/res/drawable/record_sound_icon.png
new file mode 100755
index 0000000..a1382ac
Binary files /dev/null and b/examples/0601/MyAndroidTutorial/app/src/main/res/drawable/record_sound_icon.png differ
diff --git a/examples/0601/MyAndroidTutorial/app/src/main/res/drawable/retangle_drawable.xml b/examples/0601/MyAndroidTutorial/app/src/main/res/drawable/retangle_drawable.xml
new file mode 100644
index 0000000..51d1e84
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/app/src/main/res/drawable/retangle_drawable.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0601/MyAndroidTutorial/app/src/main/res/drawable/select_color_icon.png b/examples/0601/MyAndroidTutorial/app/src/main/res/drawable/select_color_icon.png
new file mode 100644
index 0000000..8567d5e
Binary files /dev/null and b/examples/0601/MyAndroidTutorial/app/src/main/res/drawable/select_color_icon.png differ
diff --git a/examples/0601/MyAndroidTutorial/app/src/main/res/drawable/selected_icon.png b/examples/0601/MyAndroidTutorial/app/src/main/res/drawable/selected_icon.png
new file mode 100755
index 0000000..b891571
Binary files /dev/null and b/examples/0601/MyAndroidTutorial/app/src/main/res/drawable/selected_icon.png differ
diff --git a/examples/0601/MyAndroidTutorial/app/src/main/res/drawable/stop_icon.png b/examples/0601/MyAndroidTutorial/app/src/main/res/drawable/stop_icon.png
new file mode 100755
index 0000000..20df415
Binary files /dev/null and b/examples/0601/MyAndroidTutorial/app/src/main/res/drawable/stop_icon.png differ
diff --git a/examples/0601/MyAndroidTutorial/app/src/main/res/drawable/take_picture_icon.png b/examples/0601/MyAndroidTutorial/app/src/main/res/drawable/take_picture_icon.png
new file mode 100644
index 0000000..08fb514
Binary files /dev/null and b/examples/0601/MyAndroidTutorial/app/src/main/res/drawable/take_picture_icon.png differ
diff --git a/examples/0601/MyAndroidTutorial/app/src/main/res/layout/activity_about.xml b/examples/0601/MyAndroidTutorial/app/src/main/res/layout/activity_about.xml
new file mode 100644
index 0000000..211a9b6
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/app/src/main/res/layout/activity_about.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0601/MyAndroidTutorial/app/src/main/res/layout/activity_color.xml b/examples/0601/MyAndroidTutorial/app/src/main/res/layout/activity_color.xml
new file mode 100644
index 0000000..d25bbc5
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/app/src/main/res/layout/activity_color.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
diff --git a/examples/0601/MyAndroidTutorial/app/src/main/res/layout/activity_item.xml b/examples/0601/MyAndroidTutorial/app/src/main/res/layout/activity_item.xml
new file mode 100644
index 0000000..4ec4362
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/app/src/main/res/layout/activity_item.xml
@@ -0,0 +1,125 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0601/MyAndroidTutorial/app/src/main/res/layout/activity_main.xml b/examples/0601/MyAndroidTutorial/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..121511b
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
diff --git a/examples/0601/MyAndroidTutorial/app/src/main/res/layout/activity_maps.xml b/examples/0601/MyAndroidTutorial/app/src/main/res/layout/activity_maps.xml
new file mode 100644
index 0000000..5de477b
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/app/src/main/res/layout/activity_maps.xml
@@ -0,0 +1,7 @@
+
diff --git a/examples/0601/MyAndroidTutorial/app/src/main/res/layout/activity_play.xml b/examples/0601/MyAndroidTutorial/app/src/main/res/layout/activity_play.xml
new file mode 100644
index 0000000..52db308
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/app/src/main/res/layout/activity_play.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0601/MyAndroidTutorial/app/src/main/res/layout/activity_record.xml b/examples/0601/MyAndroidTutorial/app/src/main/res/layout/activity_record.xml
new file mode 100644
index 0000000..63d9e36
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/app/src/main/res/layout/activity_record.xml
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0601/MyAndroidTutorial/app/src/main/res/layout/item_app_widget.xml b/examples/0601/MyAndroidTutorial/app/src/main/res/layout/item_app_widget.xml
new file mode 100644
index 0000000..92bb45a
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/app/src/main/res/layout/item_app_widget.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0601/MyAndroidTutorial/app/src/main/res/layout/single_item.xml b/examples/0601/MyAndroidTutorial/app/src/main/res/layout/single_item.xml
new file mode 100644
index 0000000..40ddbc9
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/app/src/main/res/layout/single_item.xml
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0601/MyAndroidTutorial/app/src/main/res/menu/menu_main.xml b/examples/0601/MyAndroidTutorial/app/src/main/res/menu/menu_main.xml
new file mode 100644
index 0000000..3ea061c
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/app/src/main/res/menu/menu_main.xml
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
diff --git a/examples/0601/MyAndroidTutorial/app/src/main/res/transition/explode_transition.xml b/examples/0601/MyAndroidTutorial/app/src/main/res/transition/explode_transition.xml
new file mode 100644
index 0000000..d2320b1
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/app/src/main/res/transition/explode_transition.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0601/MyAndroidTutorial/app/src/main/res/transition/fade_transition.xml b/examples/0601/MyAndroidTutorial/app/src/main/res/transition/fade_transition.xml
new file mode 100644
index 0000000..ea54111
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/app/src/main/res/transition/fade_transition.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0601/MyAndroidTutorial/app/src/main/res/transition/slide_transition.xml b/examples/0601/MyAndroidTutorial/app/src/main/res/transition/slide_transition.xml
new file mode 100644
index 0000000..afd9869
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/app/src/main/res/transition/slide_transition.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0601/MyAndroidTutorial/app/src/main/res/values-en/strings.xml b/examples/0601/MyAndroidTutorial/app/src/main/res/values-en/strings.xml
new file mode 100644
index 0000000..c532533
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/app/src/main/res/values-en/strings.xml
@@ -0,0 +1,12 @@
+
+
+
+ MyAndroidTutorial
+ Hello world!
+ Settings
+
+ Title
+ Enter title
+ Content
+ Enter content
+
diff --git a/examples/0601/MyAndroidTutorial/app/src/main/res/values-v14/dimens.xml b/examples/0601/MyAndroidTutorial/app/src/main/res/values-v14/dimens.xml
new file mode 100644
index 0000000..4db8c59
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/app/src/main/res/values-v14/dimens.xml
@@ -0,0 +1,10 @@
+
+
+
+
+ 0dp
+
+
\ No newline at end of file
diff --git a/examples/0601/MyAndroidTutorial/app/src/main/res/values-v21/styles.xml b/examples/0601/MyAndroidTutorial/app/src/main/res/values-v21/styles.xml
new file mode 100644
index 0000000..606e45f
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/app/src/main/res/values-v21/styles.xml
@@ -0,0 +1,12 @@
+
+
+
+
\ No newline at end of file
diff --git a/examples/0601/MyAndroidTutorial/app/src/main/res/values-w820dp/dimens.xml b/examples/0601/MyAndroidTutorial/app/src/main/res/values-w820dp/dimens.xml
new file mode 100644
index 0000000..63fc816
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/app/src/main/res/values-w820dp/dimens.xml
@@ -0,0 +1,6 @@
+
+
+ 64dp
+
diff --git a/examples/0601/MyAndroidTutorial/app/src/main/res/values/colors.xml b/examples/0601/MyAndroidTutorial/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..6b13c1d
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/app/src/main/res/values/colors.xml
@@ -0,0 +1,7 @@
+
+
+ #CCCCCC
+ #AAAAAA
+ #DD999999
+ #111111
+
\ No newline at end of file
diff --git a/examples/0601/MyAndroidTutorial/app/src/main/res/values/dimens.xml b/examples/0601/MyAndroidTutorial/app/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..9923269
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/app/src/main/res/values/dimens.xml
@@ -0,0 +1,15 @@
+
+
+ 16dp
+ 16dp
+
+ 6dp
+ 24sp
+ 2dp
+
+
+ 8dp
+
diff --git a/examples/0601/MyAndroidTutorial/app/src/main/res/values/strings.xml b/examples/0601/MyAndroidTutorial/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..a59f440
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/app/src/main/res/values/strings.xml
@@ -0,0 +1,59 @@
+
+
+
+ MyAndroidTutorial
+ Hello world!
+ Settings
+ 標題
+ 輸入標題
+ 內容
+ 輸入內容
+ 這是Android Tutorial應用程式
+ AboutActivity
+ 版本:AndroidTutorial_0.2.4
+ ItemActivity
+ ColorActivity
+ 刪除
+ 確定要刪除 %1$d 個項目?
+ 預設的顏色
+ 新增記事的預設顏色
+
+ 預設提醒時間
+ 在指定的時間之前通知
+
+
+ - 五分鐘
+ - 十分鐘
+ - 二十分鐘
+ - 三十分鐘
+ - 六十分鐘
+
+
+
+ - 5
+ - 10
+ - 20
+ - 30
+ - 60
+
+
+ 語音備忘
+ 播放語音備忘
+ 播放
+ 重新錄製
+ Map
+
+ 記事儲存的位置
+ 更新或清除儲存的位置資訊?
+ 更新
+ 清除
+
+ 目前位置
+ 是否儲存目前位置?
+
+ 裝置沒有安裝Google Play服務
+ EXAMPLE
+ Configure
+ Add widget
+
+
diff --git a/examples/0601/MyAndroidTutorial/app/src/main/res/values/styles.xml b/examples/0601/MyAndroidTutorial/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..766ab99
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/app/src/main/res/values/styles.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
diff --git a/examples/0601/MyAndroidTutorial/app/src/main/res/xml/item_app_widget_info.xml b/examples/0601/MyAndroidTutorial/app/src/main/res/xml/item_app_widget_info.xml
new file mode 100644
index 0000000..043d27b
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/app/src/main/res/xml/item_app_widget_info.xml
@@ -0,0 +1,15 @@
+
+
+
\ No newline at end of file
diff --git a/examples/0601/MyAndroidTutorial/app/src/main/res/xml/mypreference.xml b/examples/0601/MyAndroidTutorial/app/src/main/res/xml/mypreference.xml
new file mode 100644
index 0000000..33e714c
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/app/src/main/res/xml/mypreference.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0601/MyAndroidTutorial/app/src/release/res/values/google_maps_api.xml b/examples/0601/MyAndroidTutorial/app/src/release/res/values/google_maps_api.xml
new file mode 100644
index 0000000..c4e2431
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/app/src/release/res/values/google_maps_api.xml
@@ -0,0 +1,18 @@
+
+
+
+ YOUR_KEY_HERE
+
+
diff --git a/examples/0601/MyAndroidTutorial/build.gradle b/examples/0601/MyAndroidTutorial/build.gradle
new file mode 100644
index 0000000..6356aab
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/build.gradle
@@ -0,0 +1,19 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+ repositories {
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:1.0.0'
+
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+}
+
+allprojects {
+ repositories {
+ jcenter()
+ }
+}
diff --git a/examples/0601/MyAndroidTutorial/gradle.properties b/examples/0601/MyAndroidTutorial/gradle.properties
new file mode 100644
index 0000000..1d3591c
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/gradle.properties
@@ -0,0 +1,18 @@
+# Project-wide Gradle settings.
+
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+# Default value: -Xmx10248m -XX:MaxPermSize=256m
+# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
+
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
\ No newline at end of file
diff --git a/examples/0601/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.jar b/examples/0601/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
Binary files /dev/null and b/examples/0601/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/examples/0601/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.properties b/examples/0601/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..0c71e76
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
diff --git a/examples/0601/MyAndroidTutorial/gradlew b/examples/0601/MyAndroidTutorial/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/examples/0601/MyAndroidTutorial/gradlew.bat b/examples/0601/MyAndroidTutorial/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/examples/0601/MyAndroidTutorial/settings.gradle b/examples/0601/MyAndroidTutorial/settings.gradle
new file mode 100644
index 0000000..e7b4def
--- /dev/null
+++ b/examples/0601/MyAndroidTutorial/settings.gradle
@@ -0,0 +1 @@
+include ':app'
diff --git a/examples/0602/MyAndroidTutorial/.gitignore b/examples/0602/MyAndroidTutorial/.gitignore
new file mode 100644
index 0000000..afbdab3
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/.gitignore
@@ -0,0 +1,6 @@
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
diff --git a/examples/0602/MyAndroidTutorial/.idea/.name b/examples/0602/MyAndroidTutorial/.idea/.name
new file mode 100644
index 0000000..5bb7a85
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/.idea/.name
@@ -0,0 +1 @@
+MyAndroidTutorial
\ No newline at end of file
diff --git a/examples/0602/MyAndroidTutorial/.idea/compiler.xml b/examples/0602/MyAndroidTutorial/.idea/compiler.xml
new file mode 100644
index 0000000..9a8b7e5
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/.idea/compiler.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0602/MyAndroidTutorial/.idea/copyright/profiles_settings.xml b/examples/0602/MyAndroidTutorial/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..e7bedf3
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/examples/0602/MyAndroidTutorial/.idea/gradle.xml b/examples/0602/MyAndroidTutorial/.idea/gradle.xml
new file mode 100644
index 0000000..c595ad9
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/.idea/gradle.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0602/MyAndroidTutorial/.idea/misc.xml b/examples/0602/MyAndroidTutorial/.idea/misc.xml
new file mode 100644
index 0000000..b0c0cbc
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/.idea/misc.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0602/MyAndroidTutorial/.idea/modules.xml b/examples/0602/MyAndroidTutorial/.idea/modules.xml
new file mode 100644
index 0000000..5edca7e
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/.idea/modules.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0602/MyAndroidTutorial/.idea/vcs.xml b/examples/0602/MyAndroidTutorial/.idea/vcs.xml
new file mode 100644
index 0000000..6564d52
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0602/MyAndroidTutorial/MyAndroidTutorial.iml b/examples/0602/MyAndroidTutorial/MyAndroidTutorial.iml
new file mode 100644
index 0000000..62d899f
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/MyAndroidTutorial.iml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0602/MyAndroidTutorial/app/.gitignore b/examples/0602/MyAndroidTutorial/app/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/app/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/examples/0602/MyAndroidTutorial/app/app.iml b/examples/0602/MyAndroidTutorial/app/app.iml
new file mode 100644
index 0000000..2041401
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/app/app.iml
@@ -0,0 +1,114 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0602/MyAndroidTutorial/app/build.gradle b/examples/0602/MyAndroidTutorial/app/build.gradle
new file mode 100644
index 0000000..c5d367d
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/app/build.gradle
@@ -0,0 +1,27 @@
+apply plugin: 'com.android.application'
+
+android {
+ compileSdkVersion 21
+ buildToolsVersion "21.1.2"
+
+ defaultConfig {
+ applicationId "net.macdidi.myandroidtutorial"
+ minSdkVersion 16
+ targetSdkVersion 21
+ versionCode 1
+ versionName "1.0"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ compile fileTree(dir: 'libs', include: ['*.jar'])
+ compile 'com.android.support:appcompat-v7:22.0.0'
+ compile 'com.google.android.gms:play-services:7.0.0'
+ compile 'com.android.support:recyclerview-v7:21.0.+'
+}
diff --git a/examples/0602/MyAndroidTutorial/app/proguard-rules.pro b/examples/0602/MyAndroidTutorial/app/proguard-rules.pro
new file mode 100644
index 0000000..b5fa7ec
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/app/proguard-rules.pro
@@ -0,0 +1,17 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /Users/macdidi5/Library/Android/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
diff --git a/examples/0602/MyAndroidTutorial/app/src/androidTest/java/net/macdidi/myandroidtutorial/ApplicationTest.java b/examples/0602/MyAndroidTutorial/app/src/androidTest/java/net/macdidi/myandroidtutorial/ApplicationTest.java
new file mode 100644
index 0000000..2cb214e
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/app/src/androidTest/java/net/macdidi/myandroidtutorial/ApplicationTest.java
@@ -0,0 +1,13 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Application;
+import android.test.ApplicationTestCase;
+
+/**
+ * Testing Fundamentals
+ */
+public class ApplicationTest extends ApplicationTestCase {
+ public ApplicationTest() {
+ super(Application.class);
+ }
+}
\ No newline at end of file
diff --git a/examples/0602/MyAndroidTutorial/app/src/debug/res/values/google_maps_api.xml b/examples/0602/MyAndroidTutorial/app/src/debug/res/values/google_maps_api.xml
new file mode 100644
index 0000000..7341c8d
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/app/src/debug/res/values/google_maps_api.xml
@@ -0,0 +1,18 @@
+
+
+
+ AIzaSyCZg9YWlfokPA96VxWGYr6u4C12jL16VhM
+
+
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/AndroidManifest.xml b/examples/0602/MyAndroidTutorial/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..50449c2
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/app/src/main/AndroidManifest.xml
@@ -0,0 +1,128 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/AboutActivity.java b/examples/0602/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/AboutActivity.java
new file mode 100644
index 0000000..42dddeb
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/AboutActivity.java
@@ -0,0 +1,24 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.view.Window;
+
+public class AboutActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ // 取消元件的應用程式標題
+ requestWindowFeature(Window.FEATURE_NO_TITLE);
+ setContentView(R.layout.activity_about);
+ }
+
+ // 結束按鈕
+ public void clickOk(View view) {
+ // 呼叫這個方法結束Activity元件
+ finish();
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/AlarmReceiver.java b/examples/0602/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/AlarmReceiver.java
new file mode 100644
index 0000000..368165c
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/AlarmReceiver.java
@@ -0,0 +1,86 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.support.v4.app.NotificationCompat;
+
+import java.io.File;
+
+public class AlarmReceiver extends BroadcastReceiver {
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ // 讀取記事標題
+ //String title = intent.getStringExtra("title");
+ // 顯示訊息框
+ //Toast.makeText(context, title, Toast.LENGTH_LONG).show();
+
+ // 讀取記事編號
+ long id = intent.getLongExtra("id", 0);
+
+ if (id != 0) {
+ sendNotify(context, id);
+ }
+ }
+
+ private void sendNotify(Context context, long id) {
+ // 建立資料庫物件
+ ItemDAO itemDAO = new ItemDAO(context.getApplicationContext());
+ // 讀取指定編號的記事物件
+ Item item = itemDAO.get(id);
+
+ // 建立照片檔案物件
+ File file = new File(FileUtil.getExternalStorageDir(FileUtil.APP_DIR),
+ "P" + item.getFileName() + ".jpg");
+
+ // 是否儲存照片檔案
+ boolean isPicture = (item.getFileName() != null &&
+ item.getFileName().length() > 0 &&
+ file.exists());
+
+ // 取得NotificationManager物件
+ NotificationManager nm = (NotificationManager)
+ context.getSystemService(Context.NOTIFICATION_SERVICE);
+
+ // 如果有儲存照片檔案
+ if (isPicture) {
+ // 建立Notification.Builder物件,因為要設定大型圖片樣式
+ // 所以不能使用NotificationCompat.Builder
+ Notification.Builder builder = new Notification.Builder(context);
+ builder.setSmallIcon(android.R.drawable.star_on)
+ .setWhen(System.currentTimeMillis())
+ .setContentTitle(context.getString(R.string.app_name));
+
+ // 建立大型圖片樣式物件
+ Notification.BigPictureStyle bigPictureStyle =
+ new Notification.BigPictureStyle();
+ // 設定圖片與簡介
+ Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
+ bigPictureStyle.bigPicture(bitmap)
+ .setSummaryText(item.getTitle());
+ // 設定樣式為大型圖片
+ builder.setStyle(bigPictureStyle);
+ // 發出通知
+ nm.notify((int)item.getId(), builder.build());
+ }
+ // 如果沒有儲存照片檔案
+ else {
+ // 建立NotificationCompat.Builder物件
+ NotificationCompat.Builder builder =
+ new NotificationCompat.Builder(context);
+ // 設定圖示、時間、內容標題和內容訊息
+ builder.setSmallIcon(android.R.drawable.star_big_on)
+ .setWhen(System.currentTimeMillis())
+ .setContentTitle(context.getString(R.string.app_name))
+ .setContentText(item.getTitle());
+ // 發出通知
+ nm.notify((int)item.getId(), builder.build());
+ }
+ }
+
+}
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ColorActivity.java b/examples/0602/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ColorActivity.java
new file mode 100644
index 0000000..182cd55
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ColorActivity.java
@@ -0,0 +1,75 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.LinearLayout;
+
+public class ColorActivity extends Activity {
+
+ private LinearLayout color_gallery;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_color);
+
+ processViews();
+
+ ColorListener listener = new ColorListener();
+
+ for (Colors c : Colors.values()) {
+ Button button = new Button(this);
+ button.setId(c.parseColor());
+ LinearLayout.LayoutParams layout =
+ new LinearLayout.LayoutParams(128, 128);
+ layout.setMargins(6, 6, 6, 6);
+ button.setLayoutParams(layout);
+ button.setBackgroundColor(c.parseColor());
+
+ button.setOnClickListener(listener);
+
+ color_gallery.addView(button);
+ }
+ }
+
+ private void processViews() {
+ color_gallery = (LinearLayout) findViewById(R.id.color_gallery);
+ }
+
+ private class ColorListener implements OnClickListener {
+
+ @Override
+ public void onClick(View view) {
+ String action = ColorActivity.this.getIntent().getAction();
+
+ // 經由設定元件啟動
+ if (action != null &&
+ action.equals("net.macdidi.myandroidtutorial.CHOOSE_COLOR")) {
+ // 建立SharedPreferences物件
+ SharedPreferences.Editor editor =
+ PreferenceManager.getDefaultSharedPreferences(
+ ColorActivity.this).edit();
+ // 儲存預設顏色
+ editor.putInt("DEFAULT_COLOR", view.getId());
+ // 寫入設定值
+ editor.commit();
+ finish();
+ }
+ // 經由新增或修改記事的元件啟動
+ else {
+ Intent result = getIntent();
+ result.putExtra("colorId", view.getId());
+ setResult(Activity.RESULT_OK, result);
+ finish();
+ }
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Colors.java b/examples/0602/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Colors.java
new file mode 100644
index 0000000..1462149
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Colors.java
@@ -0,0 +1,24 @@
+package net.macdidi.myandroidtutorial;
+
+import android.graphics.Color;
+
+public enum Colors {
+
+ LIGHTGREY("#D3D3D3"), BLUE("#33B5E5"), PURPLE("#AA66CC"),
+ GREEN("#99CC00"), ORANGE("#FFBB33"), RED("#FF4444");
+
+ private String code;
+
+ private Colors(String code) {
+ this.code = code;
+ }
+
+ public String getCode() {
+ return code;
+ }
+
+ public int parseColor() {
+ return Color.parseColor(code);
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/FileUtil.java b/examples/0602/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/FileUtil.java
new file mode 100644
index 0000000..1fb41be
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/FileUtil.java
@@ -0,0 +1,112 @@
+package net.macdidi.myandroidtutorial;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.os.Environment;
+import android.util.Log;
+import android.widget.ImageView;
+
+import java.io.File;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+public class FileUtil {
+
+ // 應用程式儲存檔案的目錄
+ public static final String APP_DIR = "androidtutorial";
+
+ // 外部儲存設備是否可寫入
+ public static boolean isExternalStorageWritable() {
+ // 取得目前外部儲存設備的狀態
+ String state = Environment.getExternalStorageState();
+
+ // 判斷是否可寫入
+ if (Environment.MEDIA_MOUNTED.equals(state)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ // 外部儲存設備是否可讀取
+ public static boolean isExternalStorageReadable() {
+ // 取得目前外部儲存設備的狀態
+ String state = Environment.getExternalStorageState();
+
+ // 判斷是否可讀取
+ if (Environment.MEDIA_MOUNTED.equals(state) ||
+ Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ // 建立並傳回在公用相簿下參數指定的路徑
+ public static File getPublicAlbumStorageDir(String albumName) {
+ // 取得公用的照片路徑
+ File pictures = Environment.getExternalStoragePublicDirectory(
+ Environment.DIRECTORY_PICTURES);
+ // 準備在照片路徑下建立一個指定的路徑
+ File file = new File(pictures, albumName);
+
+ // 如果建立路徑不成功
+ if (!file.mkdirs()) {
+ Log.e("getAlbumStorageDir", "Directory not created");
+ }
+
+ return file;
+ }
+
+ // 建立並傳回在應用程式專用相簿下參數指定的路徑
+ public static File getAlbumStorageDir(Context context, String albumName) {
+ // 取得應用程式專用的照片路徑
+ File pictures = context.getExternalFilesDir(
+ Environment.DIRECTORY_PICTURES);
+ // 準備在照片路徑下建立一個指定的路徑
+ File file = new File(pictures, albumName);
+
+ // 如果建立路徑不成功
+ if (!file.mkdirs()) {
+ Log.e("getAlbumStorageDir", "Directory not created");
+ }
+
+ return file;
+ }
+
+ // 建立並傳回外部儲存媒體參數指定的路徑
+ public static File getExternalStorageDir(String dir) {
+ File result = new File(
+ Environment.getExternalStorageDirectory(), dir);
+
+ if (!isExternalStorageWritable()) {
+ return null;
+ }
+
+ if (!result.exists() && !result.mkdirs()) {
+ return null;
+ }
+
+ return result;
+ }
+
+ // 讀取指定的照片檔案名稱設定給ImageView元件
+ public static void fileToImageView(String fileName, ImageView imageView) {
+ if (new File(fileName).exists()) {
+ Bitmap bitmap = BitmapFactory.decodeFile(fileName);
+ imageView.setImageBitmap(bitmap);
+ }
+ else {
+ Log.e("fileToImageView", fileName + " not found.");
+ }
+ }
+
+ // 產生唯一的檔案名稱
+ public static String getUniqueFileName() {
+ // 使用年月日_時分秒格式為檔案名稱
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
+ return sdf.format(new Date());
+ }
+
+}
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/InitAlarmReceiver.java b/examples/0602/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/InitAlarmReceiver.java
new file mode 100644
index 0000000..959785f
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/InitAlarmReceiver.java
@@ -0,0 +1,49 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+import java.util.Calendar;
+import java.util.List;
+
+public class InitAlarmReceiver extends BroadcastReceiver {
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ // 建立資料庫物件
+ ItemDAO itemDAO = new ItemDAO(context.getApplicationContext());
+ // 讀取資料庫所有記事資料
+ List- items = itemDAO.getAll();
+
+ // 讀取目前時間
+ long current = Calendar.getInstance().getTimeInMillis();
+
+ AlarmManager am = (AlarmManager)
+ context.getSystemService(Context.ALARM_SERVICE);
+
+ for (Item item : items) {
+ long alarm = item.getAlarmDatetime();
+
+ // 如果沒有設定提醒或是提醒已經過期
+ if (alarm == 0 || alarm <= current) {
+ continue;
+ }
+
+ // 設定提醒
+ Intent alarmIntent = new Intent(context, AlarmReceiver.class);
+ //alarmIntent.putExtra("title", item.getTitle());
+
+ // 加入記事編號
+ intent.putExtra("id", item.getId());
+
+ PendingIntent pi = PendingIntent.getBroadcast(
+ context, (int)item.getId(),
+ alarmIntent, PendingIntent.FLAG_ONE_SHOT);
+ am.set(AlarmManager.RTC_WAKEUP, item.getAlarmDatetime(), pi);
+ }
+ }
+
+}
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Item.java b/examples/0602/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Item.java
new file mode 100644
index 0000000..e2bc93d
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Item.java
@@ -0,0 +1,156 @@
+package net.macdidi.myandroidtutorial;
+
+import java.util.Date;
+import java.util.Locale;
+
+public class Item implements java.io.Serializable {
+
+ // 編號、日期時間、顏色、標題、內容、照片檔案名稱、錄音檔案名稱、經緯度、修改、已選擇
+ private long id;
+ private long datetime;
+ private Colors color;
+ private String title;
+ private String content;
+ private String fileName;
+ private String recFileName;
+ private double latitude;
+ private double longitude;
+ private long lastModify;
+ private boolean selected;
+
+ // 提醒日期時間
+ private long alarmDatetime;
+
+ public Item() {
+ title = "";
+ content = "";
+ color = Colors.LIGHTGREY;
+ }
+
+ public Item(long id, long datetime, Colors color, String title,
+ String content, String fileName, String recFileName,
+ double latitude, double longitude, long lastModify) {
+ this.id = id;
+ this.datetime = datetime;
+ this.color = color;
+ this.title = title;
+ this.content = content;
+ this.fileName = fileName;
+ this.recFileName = recFileName;
+ this.latitude = latitude;
+ this.longitude = longitude;
+ this.lastModify = lastModify;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public long getDatetime() {
+ return datetime;
+ }
+
+ // 裝置區域的日期時間
+ public String getLocaleDatetime() {
+ return String.format(Locale.getDefault(), "%tF %
0) {
+ // 照片檔案物件
+ File file = configFileName("P", ".jpg");
+
+ // 如果照片檔案存在
+ if (file.exists()) {
+ // 顯示照片元件
+ picture.setVisibility(View.VISIBLE);
+ // 設定照片
+ FileUtil.fileToImageView(file.getAbsolutePath(), picture);
+ }
+ }
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (resultCode == Activity.RESULT_OK) {
+ switch (requestCode) {
+ // 照像
+ case START_CAMERA:
+ // 設定照片檔案名稱
+ item.setFileName(fileName);
+ break;
+ case START_RECORD:
+ // 設定錄音檔案名稱
+ item.setRecFileName(fileName);
+ break;
+ case START_LOCATION:
+ // 讀取與設定座標
+ double lat = data.getDoubleExtra("lat", 0.0);
+ double lng = data.getDoubleExtra("lng", 0.0);
+ item.setLatitude(lat);
+ item.setLongitude(lng);
+ break;
+ case START_ALARM:
+ break;
+ // 設定顏色
+ case START_COLOR:
+ int colorId = data.getIntExtra(
+ "colorId", Colors.LIGHTGREY.parseColor());
+ item.setColor(getColors(colorId));
+ break;
+ }
+ }
+ }
+
+ public static Colors getColors(int color) {
+ Colors result = Colors.LIGHTGREY;
+
+ if (color == Colors.BLUE.parseColor()) {
+ result = Colors.BLUE;
+ }
+ else if (color == Colors.PURPLE.parseColor()) {
+ result = Colors.PURPLE;
+ }
+ else if (color == Colors.GREEN.parseColor()) {
+ result = Colors.GREEN;
+ }
+ else if (color == Colors.ORANGE.parseColor()) {
+ result = Colors.ORANGE;
+ }
+ else if (color == Colors.RED.parseColor()) {
+ result = Colors.RED;
+ }
+
+ return result;
+ }
+
+ private void processViews() {
+ title_text = (EditText) findViewById(R.id.title_text);
+ content_text = (EditText) findViewById(R.id.content_text);
+ // 取得顯示照片的ImageView元件
+ picture = (ImageView) findViewById(R.id.picture);
+ }
+
+ // 點擊確定與取消按鈕都會呼叫這個方法
+ public void onSubmit(View view) {
+
+ if (view.getId() == R.id.ok_teim) {
+ String titleText = title_text.getText().toString();
+ String contentText = content_text.getText().toString();
+
+ item.setTitle(titleText);
+ item.setContent(contentText);
+
+ if (getIntent().getAction().equals(
+ "net.macdidi.myandroidtutorial.EDIT_ITEM")) {
+ item.setLastModify(new Date().getTime());
+ }
+ // 新增記事
+ else {
+ item.setDatetime(new Date().getTime());
+ }
+
+ Intent result = getIntent();
+ result.putExtra("net.macdidi.myandroidtutorial.Item", item);
+ setResult(Activity.RESULT_OK, result);
+ }
+
+ // 結束
+ finish();
+ }
+
+ public void clickFunction(View view) {
+ int id = view.getId();
+
+ switch (id) {
+ case R.id.take_picture:
+ // 啟動相機元件用的Intent物件
+ Intent intentCamera =
+ new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
+
+ // 照片檔案名稱
+ File pictureFile = configFileName("P", ".jpg");
+ Uri uri = Uri.fromFile(pictureFile);
+ // 設定檔案名稱
+ intentCamera.putExtra(MediaStore.EXTRA_OUTPUT, uri);
+ // 啟動相機元件
+ startActivityForResult(intentCamera, START_CAMERA);
+ break;
+ case R.id.record_sound:
+ // 錄音檔案名稱
+ final File recordFile = configRecFileName("R", ".mp3");
+
+ // 如果已經有錄音檔,詢問播放或重新錄製
+ if (recordFile.exists()) {
+ // 詢問播放還是重新錄製的對話框
+ AlertDialog.Builder d = new AlertDialog.Builder(this);
+
+ d.setTitle(R.string.title_record)
+ .setCancelable(false);
+ d.setPositiveButton(R.string.record_play,
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ // 播放
+ Intent playIntent = new Intent(
+ ItemActivity.this, PlayActivity.class);
+ playIntent.putExtra("fileName",
+ recordFile.getAbsolutePath());
+ startActivity(playIntent);
+ }
+ });
+ d.setNeutralButton(R.string.record_new,
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ goToRecord(recordFile);
+ }
+ });
+ d.setNegativeButton(android.R.string.cancel, null);
+
+ // 顯示對話框
+ d.show();
+ }
+ // 如果沒有錄音檔,啟動錄音元件
+ else {
+ goToRecord(recordFile);
+ }
+
+ break;
+ case R.id.set_location:
+ // 啟動地圖元件用的Intent物件
+ Intent intentMap = new Intent(this, MapsActivity.class);
+
+ // 設定儲存的座標
+ intentMap.putExtra("lat", item.getLatitude());
+ intentMap.putExtra("lng", item.getLongitude());
+ intentMap.putExtra("title", item.getTitle());
+ intentMap.putExtra("datetime", item.getLocaleDatetime());
+
+ // 啟動地圖元件
+ startActivityForResult(intentMap, START_LOCATION);
+ break;
+ case R.id.set_alarm:
+ // 設定提醒日期時間
+ processSetAlarm();
+ break;
+ case R.id.select_color:
+ // 啟動設定顏色的Activity元件
+ startActivityForResult(
+ new Intent(this, ColorActivity.class), START_COLOR);
+ break;
+ }
+
+ }
+
+ // 設定提醒日期時間
+ private void processSetAlarm() {
+ Calendar calendar = Calendar.getInstance();
+
+ if (item.getAlarmDatetime() != 0) {
+ // 設定為已經儲存的提醒日期時間
+ calendar.setTimeInMillis(item.getAlarmDatetime());
+ }
+
+ // 讀取年、月、日、時、分
+ int year = calendar.get(Calendar.YEAR);
+ int month = calendar.get(Calendar.MONTH);
+ int day = calendar.get(Calendar.DAY_OF_MONTH);
+ int hour = calendar.get(Calendar.HOUR_OF_DAY);
+ int minute = calendar.get(Calendar.MINUTE);
+
+ // 儲存設定的提醒日期時間
+ final Calendar alarm = Calendar.getInstance();
+
+ // 設定提醒時間
+ TimePickerDialog.OnTimeSetListener timeSetListener =
+ new TimePickerDialog.OnTimeSetListener() {
+ @Override
+ public void onTimeSet(TimePicker view,
+ int hourOfDay, int minute) {
+ alarm.set(Calendar.HOUR_OF_DAY, hourOfDay);
+ alarm.set(Calendar.MINUTE, minute);
+
+ item.setAlarmDatetime(alarm.getTimeInMillis());
+ }
+ };
+
+ // 選擇時間對話框
+ final TimePickerDialog tpd = new TimePickerDialog(
+ this, timeSetListener, hour, minute, true);
+
+ // 設定提醒日期
+ DatePickerDialog.OnDateSetListener dateSetListener =
+ new DatePickerDialog.OnDateSetListener() {
+ @Override
+ public void onDateSet(DatePicker view,
+ int year,
+ int monthOfYear,
+ int dayOfMonth) {
+ alarm.set(Calendar.YEAR, year);
+ alarm.set(Calendar.MONTH, monthOfYear);
+ alarm.set(Calendar.DAY_OF_MONTH, dayOfMonth);
+
+ // 繼續選擇提醒時間
+ tpd.show();
+ }
+ };
+
+ // 建立與顯示選擇日期對話框
+ final DatePickerDialog dpd = new DatePickerDialog(
+ this, dateSetListener, year, month, day);
+ dpd.show();
+ }
+
+ private void goToRecord(File recordFile) {
+ // 錄音
+ Intent recordIntent = new Intent(this, RecordActivity.class);
+ recordIntent.putExtra("fileName", recordFile.getAbsolutePath());
+ startActivityForResult(recordIntent, START_RECORD);
+ }
+
+ private File configFileName(String prefix, String extension) {
+ // 如果記事資料已經有檔案名稱
+ if (item.getFileName() != null && item.getFileName().length() > 0) {
+ fileName = item.getFileName();
+ }
+ // 產生檔案名稱
+ else {
+ fileName = FileUtil.getUniqueFileName();
+ }
+
+ return new File(FileUtil.getExternalStorageDir(FileUtil.APP_DIR),
+ prefix + fileName + extension);
+ }
+
+ private File configRecFileName(String prefix, String extension) {
+ // 如果記事資料已經有檔案名稱
+ if (item.getRecFileName() != null && item.getRecFileName().length() > 0) {
+ recFileName = item.getRecFileName();
+ }
+ // 產生檔案名稱
+ else {
+ recFileName = FileUtil.getUniqueFileName();
+ }
+
+ return new File(FileUtil.getExternalStorageDir(FileUtil.APP_DIR),
+ prefix + recFileName + extension);
+ }
+
+}
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemAdapter.java b/examples/0602/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemAdapter.java
new file mode 100644
index 0000000..85b40ba
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemAdapter.java
@@ -0,0 +1,80 @@
+package net.macdidi.myandroidtutorial;
+
+import android.content.Context;
+import android.graphics.drawable.GradientDrawable;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+import java.util.List;
+
+public class ItemAdapter extends ArrayAdapter- {
+
+ // 畫面資源編號
+ private int resource;
+ // 包裝的記事資料
+ private List
- items;
+
+ public ItemAdapter(Context context, int resource, List
- items) {
+ super(context, resource, items);
+ this.resource = resource;
+ this.items = items;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ LinearLayout itemView;
+ // 讀取目前位置的記事物件
+ final Item item = getItem(position);
+
+ if (convertView == null) {
+ // 建立項目畫面元件
+ itemView = new LinearLayout(getContext());
+ String inflater = Context.LAYOUT_INFLATER_SERVICE;
+ LayoutInflater li = (LayoutInflater)
+ getContext().getSystemService(inflater);
+ li.inflate(resource, itemView, true);
+ }
+ else {
+ itemView = (LinearLayout) convertView;
+ }
+
+ // 讀取記事顏色、已選擇、標題與日期時間元件
+ RelativeLayout typeColor = (RelativeLayout) itemView.findViewById(R.id.type_color);
+ ImageView selectedItem = (ImageView) itemView.findViewById(R.id.selected_item);
+ TextView titleView = (TextView) itemView.findViewById(R.id.title_text);
+ TextView dateView = (TextView) itemView.findViewById(R.id.date_text);
+
+ // 設定記事顏色
+ GradientDrawable background = (GradientDrawable)typeColor.getBackground();
+ background.setColor(item.getColor().parseColor());
+
+ // 設定標題與日期時間
+ titleView.setText(item.getTitle());
+ dateView.setText(item.getLocaleDatetime());
+
+ // 設定是否已選擇
+ selectedItem.setVisibility(item.isSelected() ? View.VISIBLE : View.INVISIBLE);
+
+ return itemView;
+ }
+
+ // 設定指定編號的記事資料
+ public void set(int index, Item item) {
+ if (index >= 0 && index < items.size()) {
+ items.set(index, item);
+ notifyDataSetChanged();
+ }
+ }
+
+ // 讀取指定編號的記事資料
+ public Item get(int index) {
+ return items.get(index);
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemAdapterRV.java b/examples/0602/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemAdapterRV.java
new file mode 100644
index 0000000..454df42
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemAdapterRV.java
@@ -0,0 +1,79 @@
+package net.macdidi.myandroidtutorial;
+
+import android.graphics.drawable.GradientDrawable;
+import android.support.v7.widget.RecyclerView;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+import java.util.List;
+
+public class ItemAdapterRV extends RecyclerView.Adapter
{
+
+ // 包裝的記事資料
+ private List- items;
+
+ public ItemAdapterRV(List
- items) {
+ this.items = items;
+ }
+
+ @Override
+ public ItemAdapterRV.ViewHolder onCreateViewHolder(
+ ViewGroup parent, int viewType) {
+ View v = LayoutInflater.from(parent.getContext()).inflate(
+ R.layout.single_item, parent, false);
+ ViewHolder viewHolder = new ViewHolder(v);
+
+ return viewHolder;
+ }
+
+ @Override
+ public void onBindViewHolder(final ViewHolder holder, int position) {
+ final Item item = items.get(position);
+
+ // 設定記事顏色
+ GradientDrawable background = (GradientDrawable)
+ holder.typeColor.getBackground();
+ background.setColor(item.getColor().parseColor());
+
+ // 設定標題與日期時間
+ holder.titleView.setText(item.getTitle());
+ holder.dateView.setText(item.getLocaleDatetime());
+
+ // 設定是否已選擇
+ holder.selectedItem.setVisibility(
+ item.isSelected() ? View.VISIBLE : View.INVISIBLE);
+ }
+
+ @Override
+ public int getItemCount() {
+ return items.size();
+ }
+
+ // 一定要使用ViewHolder包裝畫面元件
+ public class ViewHolder extends RecyclerView.ViewHolder {
+
+ protected RelativeLayout typeColor;
+ protected ImageView selectedItem;
+ protected TextView titleView;
+ protected TextView dateView;
+
+ protected View rootView;
+
+ public ViewHolder(View view) {
+ super(view);
+
+ typeColor = (RelativeLayout) itemView.findViewById(R.id.type_color);
+ selectedItem = (ImageView) itemView.findViewById(R.id.selected_item);
+ titleView = (TextView) itemView.findViewById(R.id.title_text);
+ dateView = (TextView) itemView.findViewById(R.id.date_text);
+
+ rootView = view;
+ }
+
+ }
+
+}
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemAppWidget.java b/examples/0602/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemAppWidget.java
new file mode 100644
index 0000000..9301f57
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemAppWidget.java
@@ -0,0 +1,72 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.PendingIntent;
+import android.appwidget.AppWidgetManager;
+import android.appwidget.AppWidgetProvider;
+import android.content.Context;
+import android.content.Intent;
+import android.widget.RemoteViews;
+
+
+public class ItemAppWidget extends AppWidgetProvider {
+
+ @Override
+ public void onUpdate(Context context,
+ AppWidgetManager appWidgetManager,
+ int[] appWidgetIds) {
+ final int N = appWidgetIds.length;
+
+ for (int i = 0; i < N; i++) {
+ updateAppWidget(context, appWidgetManager, appWidgetIds[i]);
+ }
+ }
+
+ @Override
+ public void onDeleted(Context context, int[] appWidgetIds) {
+ final int N = appWidgetIds.length;
+ for (int i = 0; i < N; i++) {
+ // 刪除小工具已經儲存的記事編號
+ ItemAppWidgetConfigureActivity.deleteItemPref(
+ context, appWidgetIds[i]);
+ }
+ }
+
+ @Override
+ public void onEnabled(Context context) {
+
+ }
+
+ @Override
+ public void onDisabled(Context context) {
+
+ }
+
+ static void updateAppWidget(Context context,
+ AppWidgetManager appWidgetManager,
+ int appWidgetId) {
+ // 讀取小工具儲存的記事編號
+ long id = ItemAppWidgetConfigureActivity.loadItemPref(
+ context, appWidgetId);
+ // 建立小工具畫面元件
+ RemoteViews views = new RemoteViews(
+ context.getPackageName(), R.layout.item_app_widget);
+ // 讀取指定編號的記事物件
+ ItemDAO itemDAO = new ItemDAO(context.getApplicationContext());
+ Item item = itemDAO.get(id);
+
+ // 設定小工具畫面顯示記事標題
+ views.setTextViewText(R.id.appwidget_text,
+ item != null ? item.getTitle() : "NA");
+
+ // 點選小工具畫面的記事標題後,啟動記事應用程式
+ Intent intent = new Intent(context, MainActivity.class);
+ PendingIntent pending = PendingIntent.getActivity(
+ context, 0, intent, 0);
+ views.setOnClickPendingIntent(R.id.appwidget_text, pending);
+
+ // 更新小工具
+ appWidgetManager.updateAppWidget(appWidgetId, views);
+ }
+}
+
+
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemAppWidgetConfigureActivity.java b/examples/0602/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemAppWidgetConfigureActivity.java
new file mode 100644
index 0000000..f83be71
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemAppWidgetConfigureActivity.java
@@ -0,0 +1,120 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.appwidget.AppWidgetManager;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.ListView;
+
+import java.util.List;
+
+
+public class ItemAppWidgetConfigureActivity extends Activity {
+
+ int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
+
+ private static final String PREFS_NAME =
+ "net.macdidi.myandroidtutorial.ItemAppWidget";
+ private static final String PREF_PREFIX_KEY = "appwidget_";
+
+ // 選擇小工具使用的記事項目
+ private ListView item_list;
+ private ItemAdapter itemAdapter;
+ private List
- items;
+ private ItemDAO itemDAO;
+
+ public ItemAppWidgetConfigureActivity() {
+ super();
+ }
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ setResult(RESULT_CANCELED);
+
+ // 改為使用應用程式主畫面
+ setContentView(R.layout.activity_main);
+
+ // 建立與設定選擇小工具使用的記事項目需要的物件
+ item_list = (ListView)findViewById(R.id.item_list);
+ itemDAO = new ItemDAO(getApplicationContext());
+ items = itemDAO.getAll();
+ itemAdapter = new ItemAdapter(this, R.layout.single_item, items);
+ item_list.setAdapter(itemAdapter);
+ item_list.setOnItemClickListener(itemListener);
+
+ Intent intent = getIntent();
+ Bundle extras = intent.getExtras();
+
+ if (extras != null) {
+ mAppWidgetId = extras.getInt(
+ AppWidgetManager.EXTRA_APPWIDGET_ID,
+ AppWidgetManager.INVALID_APPWIDGET_ID);
+ }
+
+ if (mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
+ finish();
+ return;
+ }
+
+ }
+
+ // 選擇記事項目
+ AdapterView.OnItemClickListener itemListener =
+ new AdapterView.OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView> parent, View view,
+ int position, long id) {
+ final Context context = ItemAppWidgetConfigureActivity.this;
+
+ // 讀取與儲存選擇的記事物件
+ Item item = itemAdapter.getItem(position);
+ saveItemPref(context, mAppWidgetId, item.getId());
+
+ AppWidgetManager appWidgetManager =
+ AppWidgetManager.getInstance(context);
+ ItemAppWidget.updateAppWidget(
+ context, appWidgetManager, mAppWidgetId);
+ Intent resultValue = new Intent();
+ resultValue.putExtra(
+ AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
+ setResult(RESULT_OK, resultValue);
+
+ finish();
+ }
+ };
+
+ // 儲存選擇的記事編號
+ static void saveItemPref(Context context, int appWidgetId, long id) {
+ SharedPreferences.Editor prefs =
+ context.getSharedPreferences(PREFS_NAME, 0).edit();
+ prefs.putLong(PREF_PREFIX_KEY + appWidgetId, id);
+ prefs.commit();
+ }
+
+ // 讀取記事編號
+ static long loadItemPref(Context context, int appWidgetId) {
+ SharedPreferences prefs =
+ context.getSharedPreferences(PREFS_NAME, 0);
+ long idValue = prefs.getLong(PREF_PREFIX_KEY + appWidgetId, 0);
+
+ return idValue;
+ }
+
+ // 刪除記事編號
+ static void deleteItemPref(Context context, int appWidgetId) {
+ SharedPreferences.Editor prefs =
+ context.getSharedPreferences(PREFS_NAME, 0).edit();
+ prefs.remove(PREF_PREFIX_KEY + appWidgetId);
+ prefs.commit();
+ }
+
+}
+
+
+
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemDAO.java b/examples/0602/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemDAO.java
new file mode 100644
index 0000000..b3c7b49
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemDAO.java
@@ -0,0 +1,214 @@
+package net.macdidi.myandroidtutorial;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+// 資料功能類別
+public class ItemDAO {
+ // 表格名稱
+ public static final String TABLE_NAME = "item";
+
+ // 編號表格欄位名稱,固定不變
+ public static final String KEY_ID = "_id";
+
+ // 其它表格欄位名稱
+ public static final String DATETIME_COLUMN = "datetime";
+ public static final String COLOR_COLUMN = "color";
+ public static final String TITLE_COLUMN = "title";
+ public static final String CONTENT_COLUMN = "content";
+ public static final String FILENAME_COLUMN = "filename";
+ public static final String RECFILENAME_COLUMN = "recfilename";
+ public static final String LATITUDE_COLUMN = "latitude";
+ public static final String LONGITUDE_COLUMN = "longitude";
+ public static final String LASTMODIFY_COLUMN = "lastmodify";
+
+ // 提醒日期時間
+ public static final String ALARMDATETIME_COLUMN = "alarmdatetime";
+
+ // 使用上面宣告的變數建立表格的SQL指令
+ public static final String CREATE_TABLE =
+ "CREATE TABLE " + TABLE_NAME + " (" +
+ KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
+ DATETIME_COLUMN + " INTEGER NOT NULL, " +
+ COLOR_COLUMN + " INTEGER NOT NULL, " +
+ TITLE_COLUMN + " TEXT NOT NULL, " +
+ CONTENT_COLUMN + " TEXT NOT NULL, " +
+ FILENAME_COLUMN + " TEXT, " +
+ RECFILENAME_COLUMN + " TEXT, " +
+ LATITUDE_COLUMN + " REAL, " +
+ LONGITUDE_COLUMN + " REAL, " +
+ LASTMODIFY_COLUMN + " INTEGER, " +
+ ALARMDATETIME_COLUMN + " INTEGER)";
+
+ // 資料庫物件
+ private SQLiteDatabase db;
+
+ // 建構子,一般的應用都不需要修改
+ public ItemDAO(Context context) {
+ db = MyDBHelper.getDatabase(context);
+ }
+
+ // 關閉資料庫,一般的應用都不需要修改
+ public void close() {
+ db.close();
+ }
+
+ // 新增參數指定的物件
+ public Item insert(Item item) {
+ // 建立準備新增資料的ContentValues物件
+ ContentValues cv = new ContentValues();
+
+ // 加入ContentValues物件包裝的新增資料
+ // 第一個參數是欄位名稱, 第二個參數是欄位的資料
+ cv.put(DATETIME_COLUMN, item.getDatetime());
+ cv.put(COLOR_COLUMN, item.getColor().parseColor());
+ cv.put(TITLE_COLUMN, item.getTitle());
+ cv.put(CONTENT_COLUMN, item.getContent());
+ cv.put(FILENAME_COLUMN, item.getFileName());
+ cv.put(RECFILENAME_COLUMN, item.getRecFileName());
+ cv.put(LATITUDE_COLUMN, item.getLatitude());
+ cv.put(LONGITUDE_COLUMN, item.getLongitude());
+ cv.put(LASTMODIFY_COLUMN, item.getLastModify());
+
+ // 提醒日期時間
+ cv.put(ALARMDATETIME_COLUMN, item.getAlarmDatetime());
+
+ // 新增一筆資料並取得編號
+ // 第一個參數是表格名稱
+ // 第二個參數是沒有指定欄位值的預設值
+ // 第三個參數是包裝新增資料的ContentValues物件
+ long id = db.insert(TABLE_NAME, null, cv);
+
+ // 設定編號
+ item.setId(id);
+ // 回傳結果
+ return item;
+ }
+
+ // 修改參數指定的物件
+ public boolean update(Item item) {
+ // 建立準備修改資料的ContentValues物件
+ ContentValues cv = new ContentValues();
+
+ // 加入ContentValues物件包裝的修改資料
+ // 第一個參數是欄位名稱, 第二個參數是欄位的資料
+ cv.put(DATETIME_COLUMN, item.getDatetime());
+ cv.put(COLOR_COLUMN, item.getColor().parseColor());
+ cv.put(TITLE_COLUMN, item.getTitle());
+ cv.put(CONTENT_COLUMN, item.getContent());
+ cv.put(FILENAME_COLUMN, item.getFileName());
+ cv.put(RECFILENAME_COLUMN, item.getRecFileName());
+ cv.put(LATITUDE_COLUMN, item.getLatitude());
+ cv.put(LONGITUDE_COLUMN, item.getLongitude());
+ cv.put(LASTMODIFY_COLUMN, item.getLastModify());
+
+ // 提醒日期時間
+ cv.put(ALARMDATETIME_COLUMN, item.getAlarmDatetime());
+
+ // 設定修改資料的條件為編號
+ // 格式為「欄位名稱=資料」
+ String where = KEY_ID + "=" + item.getId();
+
+ // 執行修改資料並回傳修改的資料數量是否成功
+ return db.update(TABLE_NAME, cv, where, null) > 0;
+ }
+
+ // 刪除參數指定編號的資料
+ public boolean delete(long id){
+ // 設定條件為編號,格式為「欄位名稱=資料」
+ String where = KEY_ID + "=" + id;
+ // 刪除指定編號資料並回傳刪除是否成功
+ return db.delete(TABLE_NAME, where , null) > 0;
+ }
+
+ // 讀取所有記事資料
+ public List
- getAll() {
+ List
- result = new ArrayList<>();
+ Cursor cursor = db.query(
+ TABLE_NAME, null, null, null, null, null, null, null);
+
+ while (cursor.moveToNext()) {
+ result.add(getRecord(cursor));
+ }
+
+ cursor.close();
+ return result;
+ }
+
+ // 取得指定編號的資料物件
+ public Item get(long id) {
+ // 準備回傳結果用的物件
+ Item item = null;
+ // 使用編號為查詢條件
+ String where = KEY_ID + "=" + id;
+ // 執行查詢
+ Cursor result = db.query(
+ TABLE_NAME, null, where, null, null, null, null, null);
+
+ // 如果有查詢結果
+ if (result.moveToFirst()) {
+ // 讀取包裝一筆資料的物件
+ item = getRecord(result);
+ }
+
+ // 關閉Cursor物件
+ result.close();
+ // 回傳結果
+ return item;
+ }
+
+ // 把Cursor目前的資料包裝為物件
+ public Item getRecord(Cursor cursor) {
+ // 準備回傳結果用的物件
+ Item result = new Item();
+
+ result.setId(cursor.getLong(0));
+ result.setDatetime(cursor.getLong(1));
+ result.setColor(ItemActivity.getColors(cursor.getInt(2)));
+ result.setTitle(cursor.getString(3));
+ result.setContent(cursor.getString(4));
+ result.setFileName(cursor.getString(5));
+ result.setRecFileName(cursor.getString(6));
+ result.setLatitude(cursor.getDouble(7));
+ result.setLongitude(cursor.getDouble(8));
+ result.setLastModify(cursor.getLong(9));
+
+ // 提醒日期時間
+ result.setAlarmDatetime(cursor.getLong(9));
+
+ // 回傳結果
+ return result;
+ }
+
+ // 取得資料數量
+ public int getCount() {
+ int result = 0;
+ Cursor cursor = db.rawQuery("SELECT COUNT(*) FROM " + TABLE_NAME, null);
+
+ if (cursor.moveToNext()) {
+ result = cursor.getInt(0);
+ }
+
+ return result;
+ }
+
+ // 建立範例資料
+ public void sample() {
+ Item item = new Item(0, new Date().getTime(), Colors.RED, "關於Android Tutorial的事情.", "Hello content", "", "", 0, 0, 0);
+ Item item2 = new Item(0, new Date().getTime(), Colors.BLUE, "一隻非常可愛的小狗狗!", "她的名字叫「大熱狗」,又叫\n作「奶嘴」,是一隻非常可愛\n的小狗。", "", "", 25.04719, 121.516981, 0);
+ Item item3 = new Item(0, new Date().getTime(), Colors.GREEN, "一首非常好聽的音樂!", "Hello content", "", "", 0, 0, 0);
+ Item item4 = new Item(0, new Date().getTime(), Colors.ORANGE, "儲存在資料庫的資料", "Hello content", "", "", 0, 0, 0);
+
+ insert(item);
+ insert(item2);
+ insert(item3);
+ insert(item4);
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MainActivity.java b/examples/0602/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MainActivity.java
new file mode 100644
index 0000000..391eb24
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MainActivity.java
@@ -0,0 +1,333 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.app.ActivityOptions;
+import android.app.AlarmManager;
+import android.app.AlertDialog;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.os.Build;
+import android.os.Bundle;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.TextView;
+
+import java.util.List;
+
+public class MainActivity extends Activity {
+
+ // 移除原來的ListView元件
+ //private ListView item_list;
+
+ // 加入下列需要的元件
+ private RecyclerView item_list;
+ private RecyclerView.Adapter itemAdapter;
+ private RecyclerView.LayoutManager rvLayoutManager;
+
+ private TextView show_app_name;
+
+ // 移除原來的ItemAdapter
+ //private ItemAdapter itemAdapter;
+
+ // 儲存所有記事本的List物件
+ private List
- items;
+
+ // 選單項目物件
+ private MenuItem add_item, search_item, revert_item, share_item, delete_item;
+
+ // 已選擇項目數量
+ private int selectedCount = 0;
+
+ // 宣告資料庫功能類別欄位變數
+ private ItemDAO itemDAO;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ processViews();
+ // 移除註冊監聽事件的工作,要移到下面執行
+ // processControllers();
+
+ itemDAO = new ItemDAO(getApplicationContext());
+
+ if (itemDAO.getCount() == 0) {
+ itemDAO.sample();
+ }
+
+ items = itemDAO.getAll();
+
+ // 移除原來ListView元件執行的工作
+ //itemAdapter = new ItemAdapter(this, R.layout.single_item, items);
+ //item_list.setAdapter(itemAdapter);
+
+ // 執行RecyclerView元件的設定
+ item_list.setHasFixedSize(true);
+ rvLayoutManager = new LinearLayoutManager(this);
+ item_list.setLayoutManager(rvLayoutManager);
+
+ // 在這裡執行註冊監聽事件的工作
+ processControllers();
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (resultCode == Activity.RESULT_OK) {
+ Item item = (Item) data.getExtras().getSerializable(
+ "net.macdidi.myandroidtutorial.Item");
+
+ boolean updateAlarm = false;
+
+ if (requestCode == 0) {
+ item = itemDAO.insert(item);
+
+ items.add(item);
+ itemAdapter.notifyDataSetChanged();
+ }
+ else if (requestCode == 1) {
+ int position = data.getIntExtra("position", -1);
+
+ if (position != -1) {
+ Item ori = itemDAO.get(item.getId());
+ updateAlarm = (item.getAlarmDatetime() != ori.getAlarmDatetime());
+
+ itemDAO.update(item);
+
+ items.set(position, item);
+ itemAdapter.notifyDataSetChanged();
+ }
+ }
+
+ if (item.getAlarmDatetime() != 0 && updateAlarm) {
+ Intent intent = new Intent(this, AlarmReceiver.class);
+ intent.putExtra("id", item.getId());
+ PendingIntent pi = PendingIntent.getBroadcast(
+ this, (int)item.getId(),
+ intent, PendingIntent.FLAG_ONE_SHOT);
+ AlarmManager am = (AlarmManager)
+ getSystemService(Context.ALARM_SERVICE);
+ am.set(AlarmManager.RTC_WAKEUP, item.getAlarmDatetime(), pi);
+ }
+ }
+ }
+
+ private void processViews() {
+ item_list = (RecyclerView) findViewById(R.id.item_list);
+ show_app_name = (TextView) findViewById(R.id.show_app_name);
+ }
+
+ private void processControllers() {
+
+ itemAdapter = new ItemAdapterRV(items) {
+ @Override
+ public void onBindViewHolder(final ViewHolder holder, final int position) {
+ super.onBindViewHolder(holder, position);
+
+ // 建立與註冊項目點擊監聽物件
+ holder.rootView.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ // 讀取選擇的記事物件
+ Item item = items.get(position);
+
+ // 如果已經有勾選的項目
+ if (selectedCount > 0) {
+ // 處理是否顯示已選擇項目
+ processMenu(item);
+ // 重新設定記事項目
+ items.set(position, item);
+ } else {
+ Intent intent = new Intent(
+ "net.macdidi.myandroidtutorial.EDIT_ITEM");
+
+ // 設定記事編號與記事物件
+ intent.putExtra("position", position);
+ intent.putExtra("net.macdidi.myandroidtutorial.Item", item);
+
+ // 依照版本啟動Acvitity元件
+ startActivityForVersion(intent, 1);
+ }
+ }
+ });
+
+ // 建立與註冊項目長按監聽物件
+ holder.rootView.setOnLongClickListener(new View.OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View v) {
+ // 讀取選擇的記事物件
+ Item item = items.get(position);
+ // 處理是否顯示已選擇項目
+ processMenu(item);
+ // 重新設定記事項目
+ items.set(position, item);
+ return true;
+ }
+ });
+ }
+ };
+
+ item_list.setAdapter(itemAdapter);
+ }
+
+ // 處理是否顯示已選擇項目
+ private void processMenu(Item item) {
+ if (item != null) {
+ item.setSelected(!item.isSelected());
+
+ if (item.isSelected()) {
+ selectedCount++;
+ }
+ else {
+ selectedCount--;
+ }
+ }
+
+ add_item.setVisible(selectedCount == 0);
+ search_item.setVisible(selectedCount == 0);
+ revert_item.setVisible(selectedCount > 0);
+ share_item.setVisible(selectedCount > 0);
+ delete_item.setVisible(selectedCount > 0);
+
+ // 通知項目勾選狀態改變
+ itemAdapter.notifyDataSetChanged();
+ }
+
+ // 載入選單資源
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ MenuInflater menuInflater = getMenuInflater();
+ menuInflater.inflate(R.menu.menu_main, menu);
+
+ // 取得選單項目物件
+ add_item = menu.findItem(R.id.add_item);
+ search_item = menu.findItem(R.id.search_item);
+ revert_item = menu.findItem(R.id.revert_item);
+ share_item = menu.findItem(R.id.share_item);
+ delete_item = menu.findItem(R.id.delete_item);
+
+ // 設定選單項目
+ processMenu(null);
+
+ return true;
+ }
+
+ // 使用者選擇所有的選單項目都會呼叫這個方法
+ public void clickMenuItem(MenuItem item) {
+ int itemId = item.getItemId();
+
+ switch (itemId) {
+ case R.id.search_item:
+ break;
+ case R.id.add_item:
+ Intent intent = new Intent("net.macdidi.myandroidtutorial.ADD_ITEM");
+ startActivityForVersion(intent, 0);
+ break;
+ // 取消所有已勾選的項目
+ case R.id.revert_item:
+ for (int i = 0; i < items.size(); i++) {
+ Item ri = items.get(i);
+
+ if (ri.isSelected()) {
+ ri.setSelected(false);
+ // 移除
+ //itemAdapter.set(i, ri);
+ }
+ }
+
+ selectedCount = 0;
+ processMenu(null);
+
+ break;
+ // 刪除
+ case R.id.delete_item:
+ if (selectedCount == 0) {
+ break;
+ }
+
+ AlertDialog.Builder d = new AlertDialog.Builder(this);
+ String message = getString(R.string.delete_item);
+ d.setTitle(R.string.delete)
+ .setMessage(String.format(message, selectedCount));
+ d.setPositiveButton(android.R.string.yes,
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ int index = items.size() - 1;
+
+ while (index > -1) {
+ // 改為使用items物件
+ Item item = items.get(index);
+
+ if (item.isSelected()) {
+ // 改為使用items物件
+ items.remove(item);
+ itemDAO.delete(item.getId());
+ }
+
+ index--;
+ }
+
+ // 移除
+ //itemAdapter.notifyDataSetChanged();
+ selectedCount = 0;
+ processMenu(null);
+ }
+ });
+ d.setNegativeButton(android.R.string.no, null);
+ d.show();
+
+ break;
+ case R.id.googleplus_item:
+ break;
+ case R.id.facebook_item:
+ break;
+ }
+
+ }
+
+ public void aboutApp(View view) {
+ Intent intent = new Intent(this, AboutActivity.class);
+ startActivity(intent);
+ }
+
+ public void clickPreferences(MenuItem item) {
+ // 依照版本啟動Acvitity元件
+ startActivityForVersion(new Intent(this, PrefActivity.class));
+ }
+
+ private void startActivityForVersion(Intent intent, int requestCode) {
+ // 如果裝置的版本是LOLLIPOP
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ // 加入畫面轉換設定
+ startActivityForResult(intent, requestCode,
+ ActivityOptions.makeSceneTransitionAnimation(
+ MainActivity.this).toBundle());
+ }
+ else {
+ startActivityForResult(intent, requestCode);
+ }
+ }
+
+ private void startActivityForVersion(Intent intent) {
+ // 如果裝置的版本是LOLLIPOP
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ // 加入畫面轉換設定
+ startActivity(intent,
+ ActivityOptions.makeSceneTransitionAnimation(
+ MainActivity.this).toBundle());
+ }
+ else {
+ startActivity(intent);
+ }
+ }
+
+}
+
+
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MapsActivity.java b/examples/0602/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MapsActivity.java
new file mode 100644
index 0000000..abab911
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MapsActivity.java
@@ -0,0 +1,338 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.location.Location;
+import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
+import android.widget.Toast;
+
+import com.google.android.gms.common.ConnectionResult;
+import com.google.android.gms.common.api.GoogleApiClient;
+import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
+import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
+
+import com.google.android.gms.location.LocationListener;
+import com.google.android.gms.location.LocationRequest;
+import com.google.android.gms.location.LocationServices;
+
+import com.google.android.gms.maps.CameraUpdateFactory;
+import com.google.android.gms.maps.GoogleMap;
+import com.google.android.gms.maps.SupportMapFragment;
+import com.google.android.gms.maps.model.BitmapDescriptor;
+import com.google.android.gms.maps.model.BitmapDescriptorFactory;
+import com.google.android.gms.maps.model.CameraPosition;
+import com.google.android.gms.maps.model.LatLng;
+import com.google.android.gms.maps.model.Marker;
+import com.google.android.gms.maps.model.MarkerOptions;
+
+public class MapsActivity extends FragmentActivity
+ implements ConnectionCallbacks,
+ OnConnectionFailedListener,
+ LocationListener {
+
+ private GoogleMap mMap;
+
+ // Google API用戶端物件
+ private GoogleApiClient googleApiClient;
+
+ // Location請求物件
+ private LocationRequest locationRequest;
+
+ // 記錄目前最新的位置
+ private Location currentLocation;
+
+ // 顯示目前與儲存位置的標記物件
+ private Marker currentMarker, itemMarker;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_maps);
+ setUpMapIfNeeded();
+
+ // 建立Google API用戶端物件
+ configGoogleApiClient();
+
+ // 建立Location請求物件
+ configLocationRequest();
+
+ // 讀取記事儲存的座標
+ Intent intent = getIntent();
+ double lat = intent.getDoubleExtra("lat", 0.0);
+ double lng = intent.getDoubleExtra("lng", 0.0);
+
+ // 如果記事已經儲存座標
+ if (lat != 0.0 && lng != 0.0) {
+ // 建立座標物件
+ LatLng itemPlace = new LatLng(lat, lng);
+ // 加入地圖標記
+ addMarker(itemPlace, intent.getStringExtra("title"),
+ intent.getStringExtra("datetime"));
+ // 移動地圖
+ moveMap(itemPlace);
+ }
+ else {
+ // 連線到Google API用戶端
+ if (!googleApiClient.isConnected()) {
+ googleApiClient.connect();
+ }
+ }
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ setUpMapIfNeeded();
+
+ // 連線到Google API用戶端
+ if (!googleApiClient.isConnected() && currentMarker != null) {
+ googleApiClient.connect();
+ }
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+
+ // 移除位置請求服務
+ if (googleApiClient.isConnected()) {
+ LocationServices.FusedLocationApi.removeLocationUpdates(
+ googleApiClient, this);
+ }
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+
+ // 移除Google API用戶端連線
+ if (googleApiClient.isConnected()) {
+ googleApiClient.disconnect();
+ }
+ }
+
+ // 建立Google API用戶端物件
+ private synchronized void configGoogleApiClient() {
+ googleApiClient = new GoogleApiClient.Builder(this)
+ .addConnectionCallbacks(this)
+ .addOnConnectionFailedListener(this)
+ .addApi(LocationServices.API)
+ .build();
+ }
+
+ // 建立Location請求物件
+ private void configLocationRequest() {
+ locationRequest = new LocationRequest();
+ // 設定讀取位置資訊的間隔時間為一秒(1000ms)
+ locationRequest.setInterval(1000);
+ // 設定讀取位置資訊最快的間隔時間為一秒(1000ms)
+ locationRequest.setFastestInterval(1000);
+ // 設定優先讀取高精確度的位置資訊(GPS)
+ locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
+ }
+
+ private void setUpMapIfNeeded() {
+ if (mMap == null) {
+ mMap = ((SupportMapFragment) getSupportFragmentManager().
+ findFragmentById(R.id.map)).getMap();
+
+ if (mMap != null) {
+ // 移除地圖設定
+ //setUpMap();
+ processController();
+ }
+ }
+ }
+
+ // 移除地圖設定方法
+ private void setUpMap() {
+ // 建立位置的座標物件
+ LatLng place = new LatLng(25.033408, 121.564099);
+ // 移動地圖
+ moveMap(place);
+
+ // 加入地圖標記
+ addMarker(place, "Hello!", " Google Maps v2!");
+ }
+
+ private void processController() {
+ // 對話框按鈕事件
+ final DialogInterface.OnClickListener listener =
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ switch (which) {
+ // 更新位置資訊
+ case DialogInterface.BUTTON_POSITIVE:
+ // 連線到Google API用戶端
+ if (!googleApiClient.isConnected()) {
+ googleApiClient.connect();
+ }
+ break;
+ // 清除位置資訊
+ case DialogInterface.BUTTON_NEUTRAL:
+ Intent result = new Intent();
+ result.putExtra("lat", 0);
+ result.putExtra("lng", 0);
+ setResult(Activity.RESULT_OK, result);
+ finish();
+ break;
+ // 取消
+ case DialogInterface.BUTTON_NEGATIVE:
+ break;
+ }
+ }
+ };
+
+ // 標記訊息框點擊事件
+ mMap.setOnInfoWindowClickListener(new GoogleMap.OnInfoWindowClickListener() {
+ @Override
+ public void onInfoWindowClick(Marker marker) {
+ // 如果是記事儲存的標記
+ if (marker.equals(itemMarker)) {
+ AlertDialog.Builder ab = new AlertDialog.Builder(MapsActivity.this);
+
+ ab.setTitle(R.string.title_update_location)
+ .setMessage(R.string.message_update_location)
+ .setCancelable(true);
+
+ ab.setPositiveButton(R.string.update, listener);
+ ab.setNeutralButton(R.string.clear, listener);
+ ab.setNegativeButton(android.R.string.cancel, listener);
+
+ ab.show();
+ }
+ }
+ });
+
+ // 標記點擊事件
+ mMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
+ @Override
+ public boolean onMarkerClick(Marker marker) {
+ // 如果是目前位置標記
+ if (marker.equals(currentMarker)) {
+ AlertDialog.Builder ab = new AlertDialog.Builder(MapsActivity.this);
+
+ ab.setTitle(R.string.title_current_location)
+ .setMessage(R.string.message_current_location)
+ .setCancelable(true);
+
+ ab.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ Intent result = new Intent();
+ result.putExtra("lat", currentLocation.getLatitude());
+ result.putExtra("lng", currentLocation.getLongitude());
+ setResult(Activity.RESULT_OK, result);
+ finish();
+ }
+ });
+ ab.setNegativeButton(android.R.string.cancel, null);
+
+ ab.show();
+
+ return true;
+ }
+
+ return false;
+ }
+ });
+ }
+
+ // 移動地圖到參數指定的位置
+ private void moveMap(LatLng place) {
+ // 建立地圖攝影機的位置物件
+ CameraPosition cameraPosition =
+ new CameraPosition.Builder()
+ .target(place)
+ .zoom(17)
+ .build();
+
+ // 使用動畫的效果移動地圖
+ mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition),
+ new GoogleMap.CancelableCallback() {
+ @Override
+ public void onFinish() {
+ if (itemMarker != null) {
+ itemMarker.showInfoWindow();
+ }
+ }
+
+ @Override
+ public void onCancel() {
+
+ }
+ });
+ }
+
+ // 在地圖加入指定位置與標題的標記
+ private void addMarker(LatLng place, String title, String snippet) {
+ BitmapDescriptor icon =
+ BitmapDescriptorFactory.fromResource(R.drawable.ic_launcher);
+
+ MarkerOptions markerOptions = new MarkerOptions();
+ markerOptions.position(place)
+ .title(title)
+ .snippet(snippet)
+ .icon(icon);
+
+ // 加入並設定記事儲存的位置標記
+ itemMarker = mMap.addMarker(markerOptions);
+ }
+
+ // ConnectionCallbacks
+ @Override
+ public void onConnected(Bundle bundle) {
+ // 已經連線到Google Services
+ // 啟動位置更新服務
+ // 位置資訊更新的時候,應用程式會自動呼叫LocationListener.onLocationChanged
+ LocationServices.FusedLocationApi.requestLocationUpdates(
+ googleApiClient, locationRequest, MapsActivity.this);
+ }
+
+ // ConnectionCallbacks
+ @Override
+ public void onConnectionSuspended(int i) {
+ // Google Services連線中斷
+ // int參數是連線中斷的代號
+ }
+
+ // OnConnectionFailedListener
+ @Override
+ public void onConnectionFailed(ConnectionResult connectionResult) {
+ // Google Services連線失敗
+ // ConnectionResult參數是連線失敗的資訊
+ int errorCode = connectionResult.getErrorCode();
+
+ // 裝置沒有安裝Google Play服務
+ if (errorCode == ConnectionResult.SERVICE_MISSING) {
+ Toast.makeText(this, R.string.google_play_service_missing,
+ Toast.LENGTH_LONG).show();
+ }
+ }
+
+ // LocationListener
+ @Override
+ public void onLocationChanged(Location location) {
+ // 位置改變
+ // Location參數是目前的位置
+ currentLocation = location;
+ LatLng latLng = new LatLng(
+ location.getLatitude(), location.getLongitude());
+
+ // 設定目前位置的標記
+ if (currentMarker == null) {
+ currentMarker = mMap.addMarker(new MarkerOptions().position(latLng));
+ }
+ else {
+ currentMarker.setPosition(latLng);
+ }
+
+ // 移動地圖到目前的位置
+ moveMap(latLng);
+ }
+
+}
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MyDBHelper.java b/examples/0602/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MyDBHelper.java
new file mode 100644
index 0000000..9350577
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MyDBHelper.java
@@ -0,0 +1,47 @@
+package net.macdidi.myandroidtutorial;
+
+import android.content.Context;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteDatabase.CursorFactory;
+import android.database.sqlite.SQLiteOpenHelper;
+
+public class MyDBHelper extends SQLiteOpenHelper {
+
+ // 資料庫名稱
+ public static final String DATABASE_NAME = "mydata.db";
+ // 資料庫版本,資料結構改變的時候要更改這個數字,通常是加一
+ public static final int VERSION = 3;
+ // 資料庫物件,固定的欄位變數
+ private static SQLiteDatabase database;
+
+ // 建構子,在一般的應用都不需要修改
+ public MyDBHelper(Context context, String name, CursorFactory factory,
+ int version) {
+ super(context, name, factory, version);
+ }
+
+ // 需要資料庫的元件呼叫這個方法,這個方法在一般的應用都不需要修改
+ public static SQLiteDatabase getDatabase(Context context) {
+ if (database == null || !database.isOpen()) {
+ database = new MyDBHelper(context, DATABASE_NAME,
+ null, VERSION).getWritableDatabase();
+ }
+
+ return database;
+ }
+
+ @Override
+ public void onCreate(SQLiteDatabase db) {
+ // 建立應用程式需要的表格
+ db.execSQL(ItemDAO.CREATE_TABLE);
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ // 刪除原有的表格
+ db.execSQL("DROP TABLE IF EXISTS " + ItemDAO.TABLE_NAME);
+ // 呼叫onCreate建立新版的表格
+ onCreate(db);
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PlayActivity.java b/examples/0602/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PlayActivity.java
new file mode 100644
index 0000000..5cfb523
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PlayActivity.java
@@ -0,0 +1,64 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.media.MediaPlayer;
+import android.net.Uri;
+import android.os.Bundle;
+import android.view.View;
+
+public class PlayActivity extends Activity {
+
+ private MediaPlayer mediaPlayer;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_play);
+
+ Intent intent = getIntent();
+ String fileName = intent.getStringExtra("fileName");
+
+ // 建立指定資源的MediaPlayer物件
+ Uri uri = Uri.parse(fileName);
+ mediaPlayer = MediaPlayer.create(this, uri);
+ }
+
+ @Override
+ protected void onStop() {
+ if (mediaPlayer.isPlaying()) {
+ // 停止播放
+ mediaPlayer.stop();
+ }
+
+ // 清除MediaPlayer物件
+ mediaPlayer.release();
+ super.onStop();
+ }
+
+ public void onSubmit(View view) {
+ // 結束Activity元件
+ finish();
+ }
+
+ public void clickPlay(View view) {
+ // 開始播放
+ mediaPlayer.start();
+ }
+
+ public void clickPause(View view) {
+ // 暫停播放
+ mediaPlayer.pause();
+ }
+
+ public void clickStop(View view) {
+ // 停止播放
+ if (mediaPlayer.isPlaying()) {
+ mediaPlayer.stop();
+ }
+
+ // 回到開始的位置
+ mediaPlayer.seekTo(0);
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PrefActivity.java b/examples/0602/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PrefActivity.java
new file mode 100644
index 0000000..b2dcc4a
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PrefActivity.java
@@ -0,0 +1,38 @@
+package net.macdidi.myandroidtutorial;
+
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceManager;
+
+public class PrefActivity extends PreferenceActivity {
+
+ private SharedPreferences sharedPreferences;
+ private Preference defaultColor;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ // 指定使用的設定畫面配置資源
+ addPreferencesFromResource(R.xml.mypreference);
+ defaultColor = (Preference)findPreference("DEFAULT_COLOR");
+ // 建立SharedPreferences物件
+ sharedPreferences =
+ PreferenceManager.getDefaultSharedPreferences(this);
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ // 讀取設定的預設顏色
+ int color = sharedPreferences.getInt("DEFAULT_COLOR", -1);
+
+ if (color != -1) {
+ // 設定顏色說明
+ defaultColor.setSummary(getString(R.string.default_color_summary) +
+ ": " + ItemActivity.getColors(color));
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/RecordActivity.java b/examples/0602/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/RecordActivity.java
new file mode 100644
index 0000000..62b5e93
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/RecordActivity.java
@@ -0,0 +1,180 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.media.MediaRecorder;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.widget.ImageButton;
+import android.widget.ProgressBar;
+
+import java.io.IOException;
+
+public class RecordActivity extends Activity {
+
+ private ImageButton record_button;
+ private boolean isRecording = false;
+ private ProgressBar record_volumn;
+
+ private MyRecoder myRecoder;
+
+ private String fileName;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_record);
+
+ processViews();
+
+ // 讀取檔案名稱
+ Intent intent = getIntent();
+ fileName = intent.getStringExtra("fileName");
+ }
+
+ public void onSubmit(View view) {
+ if (isRecording) {
+ // 停止錄音
+ myRecoder.stop();
+ }
+
+ // 確定
+ if (view.getId() == R.id.record_ok) {
+ Intent result = getIntent();
+ setResult(Activity.RESULT_OK, result);
+ }
+
+ finish();
+ }
+
+ private void processViews() {
+ record_button = (ImageButton) findViewById(R.id.record_button);
+ record_volumn = (ProgressBar) findViewById(R.id.record_volumn);
+ // 隱藏狀態列ProgressBar
+ setProgressBarIndeterminateVisibility(false);
+ }
+
+ public void clickRecord(View view) {
+ // 切換
+ isRecording = !isRecording;
+
+ // 開始錄音
+ if (isRecording) {
+ // 設定按鈕圖示為錄音中
+ record_button.setImageResource(R.drawable.record_red_icon);
+ // 建立錄音物件
+ myRecoder = new MyRecoder(fileName);
+ // 開始錄音
+ myRecoder.start();
+ // 建立並執行顯示麥克風音量的AsyncTask物件
+ new MicLevelTask().execute();
+ }
+ // 停止錄音
+ else {
+ // 設定按鈕圖示為停止錄音
+ record_button.setImageResource(R.drawable.record_dark_icon);
+ // 麥克風音量歸零
+ record_volumn.setProgress(0);
+ // 停止錄音
+ myRecoder.stop();
+ }
+ }
+
+ // 在錄音過程中顯示麥克風音量
+ private class MicLevelTask extends AsyncTask
{
+ @Override
+ protected Void doInBackground(Void... args) {
+ while (isRecording) {
+ publishProgress();
+
+ try {
+ Thread.sleep(200);
+ }
+ catch (InterruptedException e) {
+ Log.d("RecordActivity", e.toString());
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ protected void onProgressUpdate(Void... values) {
+ record_volumn.setProgress((int) myRecoder.getAmplitudeEMA());
+ }
+
+ }
+
+ // 執行錄音並且可以取得麥克風音量的錄音物件
+ private class MyRecoder {
+
+ private static final double EMA_FILTER = 0.6;
+ private MediaRecorder recorder = null;
+ private double mEMA = 0.0;
+ private String output;
+
+ // 建立錄音物件,參數為錄音儲存的位置與檔名
+ MyRecoder(String output) {
+ this.output = output;
+ }
+
+ // 開始錄音
+ public void start() {
+ if (recorder == null) {
+ // 建立錄音用的MediaRecorder物件
+ recorder = new MediaRecorder();
+ // 設定錄音來源為麥克風,必須在setOutputFormat方法之前呼叫
+ recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
+ // 設定輸出格式為3GP壓縮格式,必須在setAudioSource方法之後,
+ // 在prepare方法之前呼叫
+ recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
+ // 設定錄音的編碼方式,必須在setOutputFormat方法之後,
+ // 在prepare方法之前呼叫
+ recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
+ // 設定輸出的檔案名稱,必須在setOutputFormat方法之後,
+ // 在prepare方法之前呼叫
+ recorder.setOutputFile(output);
+
+ try {
+ // 準備執行錄音工作,必須在所有設定之後呼叫
+ recorder.prepare();
+ }
+ catch (IOException e) {
+ Log.d("RecordActivity", e.toString());
+ }
+
+ // 開始錄音
+ recorder.start();
+ mEMA = 0.0;
+ }
+ }
+
+ // 停止錄音
+ public void stop() {
+ if (recorder != null) {
+ // 停止錄音
+ recorder.stop();
+ // 清除錄音資源
+ recorder.release();
+ recorder = null;
+ }
+ }
+
+ public double getAmplitude() {
+ if (recorder != null)
+ return (recorder.getMaxAmplitude() / 2700.0);
+ else
+ return 0;
+ }
+
+ // 取得麥克風音量
+ public double getAmplitudeEMA() {
+ double amp = getAmplitude();
+ mEMA = EMA_FILTER * amp + (1.0 - EMA_FILTER) * mEMA;
+ return mEMA;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/res/drawable-hdpi/ic_launcher.png b/examples/0602/MyAndroidTutorial/app/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..96a442e
Binary files /dev/null and b/examples/0602/MyAndroidTutorial/app/src/main/res/drawable-hdpi/ic_launcher.png differ
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/res/drawable-mdpi/ic_launcher.png b/examples/0602/MyAndroidTutorial/app/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..359047d
Binary files /dev/null and b/examples/0602/MyAndroidTutorial/app/src/main/res/drawable-mdpi/ic_launcher.png differ
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/res/drawable-nodpi/example_appwidget_preview.png b/examples/0602/MyAndroidTutorial/app/src/main/res/drawable-nodpi/example_appwidget_preview.png
new file mode 100644
index 0000000..894b069
Binary files /dev/null and b/examples/0602/MyAndroidTutorial/app/src/main/res/drawable-nodpi/example_appwidget_preview.png differ
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/res/drawable-xhdpi/ic_launcher.png b/examples/0602/MyAndroidTutorial/app/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..71c6d76
Binary files /dev/null and b/examples/0602/MyAndroidTutorial/app/src/main/res/drawable-xhdpi/ic_launcher.png differ
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/res/drawable-xxhdpi/ic_launcher.png b/examples/0602/MyAndroidTutorial/app/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..4df1894
Binary files /dev/null and b/examples/0602/MyAndroidTutorial/app/src/main/res/drawable-xxhdpi/ic_launcher.png differ
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/res/drawable/alarm_icon.png b/examples/0602/MyAndroidTutorial/app/src/main/res/drawable/alarm_icon.png
new file mode 100644
index 0000000..c6cac88
Binary files /dev/null and b/examples/0602/MyAndroidTutorial/app/src/main/res/drawable/alarm_icon.png differ
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/res/drawable/item_drawable.xml b/examples/0602/MyAndroidTutorial/app/src/main/res/drawable/item_drawable.xml
new file mode 100644
index 0000000..37607e2
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/app/src/main/res/drawable/item_drawable.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/res/drawable/location_icon.png b/examples/0602/MyAndroidTutorial/app/src/main/res/drawable/location_icon.png
new file mode 100644
index 0000000..4c3c514
Binary files /dev/null and b/examples/0602/MyAndroidTutorial/app/src/main/res/drawable/location_icon.png differ
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/res/drawable/pause_icon.png b/examples/0602/MyAndroidTutorial/app/src/main/res/drawable/pause_icon.png
new file mode 100755
index 0000000..a5aee6f
Binary files /dev/null and b/examples/0602/MyAndroidTutorial/app/src/main/res/drawable/pause_icon.png differ
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/res/drawable/play_icon.png b/examples/0602/MyAndroidTutorial/app/src/main/res/drawable/play_icon.png
new file mode 100755
index 0000000..6a40cd5
Binary files /dev/null and b/examples/0602/MyAndroidTutorial/app/src/main/res/drawable/play_icon.png differ
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/res/drawable/record_dark_icon.png b/examples/0602/MyAndroidTutorial/app/src/main/res/drawable/record_dark_icon.png
new file mode 100755
index 0000000..bcf83ca
Binary files /dev/null and b/examples/0602/MyAndroidTutorial/app/src/main/res/drawable/record_dark_icon.png differ
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/res/drawable/record_red_icon.png b/examples/0602/MyAndroidTutorial/app/src/main/res/drawable/record_red_icon.png
new file mode 100755
index 0000000..2b44af0
Binary files /dev/null and b/examples/0602/MyAndroidTutorial/app/src/main/res/drawable/record_red_icon.png differ
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/res/drawable/record_sound_icon.png b/examples/0602/MyAndroidTutorial/app/src/main/res/drawable/record_sound_icon.png
new file mode 100755
index 0000000..a1382ac
Binary files /dev/null and b/examples/0602/MyAndroidTutorial/app/src/main/res/drawable/record_sound_icon.png differ
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/res/drawable/retangle_drawable.xml b/examples/0602/MyAndroidTutorial/app/src/main/res/drawable/retangle_drawable.xml
new file mode 100644
index 0000000..51d1e84
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/app/src/main/res/drawable/retangle_drawable.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/res/drawable/select_color_icon.png b/examples/0602/MyAndroidTutorial/app/src/main/res/drawable/select_color_icon.png
new file mode 100644
index 0000000..8567d5e
Binary files /dev/null and b/examples/0602/MyAndroidTutorial/app/src/main/res/drawable/select_color_icon.png differ
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/res/drawable/selected_icon.png b/examples/0602/MyAndroidTutorial/app/src/main/res/drawable/selected_icon.png
new file mode 100755
index 0000000..b891571
Binary files /dev/null and b/examples/0602/MyAndroidTutorial/app/src/main/res/drawable/selected_icon.png differ
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/res/drawable/stop_icon.png b/examples/0602/MyAndroidTutorial/app/src/main/res/drawable/stop_icon.png
new file mode 100755
index 0000000..20df415
Binary files /dev/null and b/examples/0602/MyAndroidTutorial/app/src/main/res/drawable/stop_icon.png differ
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/res/drawable/take_picture_icon.png b/examples/0602/MyAndroidTutorial/app/src/main/res/drawable/take_picture_icon.png
new file mode 100644
index 0000000..08fb514
Binary files /dev/null and b/examples/0602/MyAndroidTutorial/app/src/main/res/drawable/take_picture_icon.png differ
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/res/layout/activity_about.xml b/examples/0602/MyAndroidTutorial/app/src/main/res/layout/activity_about.xml
new file mode 100644
index 0000000..211a9b6
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/app/src/main/res/layout/activity_about.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/res/layout/activity_color.xml b/examples/0602/MyAndroidTutorial/app/src/main/res/layout/activity_color.xml
new file mode 100644
index 0000000..d25bbc5
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/app/src/main/res/layout/activity_color.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/res/layout/activity_item.xml b/examples/0602/MyAndroidTutorial/app/src/main/res/layout/activity_item.xml
new file mode 100644
index 0000000..4ec4362
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/app/src/main/res/layout/activity_item.xml
@@ -0,0 +1,125 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/res/layout/activity_main.xml b/examples/0602/MyAndroidTutorial/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..30cdf98
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/res/layout/activity_maps.xml b/examples/0602/MyAndroidTutorial/app/src/main/res/layout/activity_maps.xml
new file mode 100644
index 0000000..5de477b
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/app/src/main/res/layout/activity_maps.xml
@@ -0,0 +1,7 @@
+
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/res/layout/activity_play.xml b/examples/0602/MyAndroidTutorial/app/src/main/res/layout/activity_play.xml
new file mode 100644
index 0000000..52db308
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/app/src/main/res/layout/activity_play.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/res/layout/activity_record.xml b/examples/0602/MyAndroidTutorial/app/src/main/res/layout/activity_record.xml
new file mode 100644
index 0000000..63d9e36
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/app/src/main/res/layout/activity_record.xml
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/res/layout/item_app_widget.xml b/examples/0602/MyAndroidTutorial/app/src/main/res/layout/item_app_widget.xml
new file mode 100644
index 0000000..92bb45a
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/app/src/main/res/layout/item_app_widget.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/res/layout/single_item.xml b/examples/0602/MyAndroidTutorial/app/src/main/res/layout/single_item.xml
new file mode 100644
index 0000000..8acc60a
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/app/src/main/res/layout/single_item.xml
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/res/menu/menu_main.xml b/examples/0602/MyAndroidTutorial/app/src/main/res/menu/menu_main.xml
new file mode 100644
index 0000000..3ea061c
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/app/src/main/res/menu/menu_main.xml
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/res/transition/explode_transition.xml b/examples/0602/MyAndroidTutorial/app/src/main/res/transition/explode_transition.xml
new file mode 100644
index 0000000..d2320b1
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/app/src/main/res/transition/explode_transition.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/res/transition/fade_transition.xml b/examples/0602/MyAndroidTutorial/app/src/main/res/transition/fade_transition.xml
new file mode 100644
index 0000000..ea54111
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/app/src/main/res/transition/fade_transition.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/res/transition/slide_transition.xml b/examples/0602/MyAndroidTutorial/app/src/main/res/transition/slide_transition.xml
new file mode 100644
index 0000000..afd9869
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/app/src/main/res/transition/slide_transition.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/res/values-en/strings.xml b/examples/0602/MyAndroidTutorial/app/src/main/res/values-en/strings.xml
new file mode 100644
index 0000000..c532533
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/app/src/main/res/values-en/strings.xml
@@ -0,0 +1,12 @@
+
+
+
+ MyAndroidTutorial
+ Hello world!
+ Settings
+
+ Title
+ Enter title
+ Content
+ Enter content
+
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/res/values-v14/dimens.xml b/examples/0602/MyAndroidTutorial/app/src/main/res/values-v14/dimens.xml
new file mode 100644
index 0000000..4db8c59
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/app/src/main/res/values-v14/dimens.xml
@@ -0,0 +1,10 @@
+
+
+
+
+ 0dp
+
+
\ No newline at end of file
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/res/values-v21/styles.xml b/examples/0602/MyAndroidTutorial/app/src/main/res/values-v21/styles.xml
new file mode 100644
index 0000000..606e45f
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/app/src/main/res/values-v21/styles.xml
@@ -0,0 +1,12 @@
+
+
+
+
\ No newline at end of file
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/res/values-w820dp/dimens.xml b/examples/0602/MyAndroidTutorial/app/src/main/res/values-w820dp/dimens.xml
new file mode 100644
index 0000000..63fc816
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/app/src/main/res/values-w820dp/dimens.xml
@@ -0,0 +1,6 @@
+
+
+ 64dp
+
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/res/values/colors.xml b/examples/0602/MyAndroidTutorial/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..6b13c1d
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/app/src/main/res/values/colors.xml
@@ -0,0 +1,7 @@
+
+
+ #CCCCCC
+ #AAAAAA
+ #DD999999
+ #111111
+
\ No newline at end of file
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/res/values/dimens.xml b/examples/0602/MyAndroidTutorial/app/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..7fa5a6f
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/app/src/main/res/values/dimens.xml
@@ -0,0 +1,13 @@
+
+
+ 16dp
+ 16dp
+
+ 6dp
+ 24sp
+ 2dp
+
+ 8dp
+
+ 2sp
+
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/res/values/strings.xml b/examples/0602/MyAndroidTutorial/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..a59f440
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/app/src/main/res/values/strings.xml
@@ -0,0 +1,59 @@
+
+
+
+ MyAndroidTutorial
+ Hello world!
+ Settings
+ 標題
+ 輸入標題
+ 內容
+ 輸入內容
+ 這是Android Tutorial應用程式
+ AboutActivity
+ 版本:AndroidTutorial_0.2.4
+ ItemActivity
+ ColorActivity
+ 刪除
+ 確定要刪除 %1$d 個項目?
+ 預設的顏色
+ 新增記事的預設顏色
+
+ 預設提醒時間
+ 在指定的時間之前通知
+
+
+ - 五分鐘
+ - 十分鐘
+ - 二十分鐘
+ - 三十分鐘
+ - 六十分鐘
+
+
+
+ - 5
+ - 10
+ - 20
+ - 30
+ - 60
+
+
+ 語音備忘
+ 播放語音備忘
+ 播放
+ 重新錄製
+ Map
+
+ 記事儲存的位置
+ 更新或清除儲存的位置資訊?
+ 更新
+ 清除
+
+ 目前位置
+ 是否儲存目前位置?
+
+ 裝置沒有安裝Google Play服務
+ EXAMPLE
+ Configure
+ Add widget
+
+
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/res/values/styles.xml b/examples/0602/MyAndroidTutorial/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..766ab99
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/app/src/main/res/values/styles.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/res/xml/item_app_widget_info.xml b/examples/0602/MyAndroidTutorial/app/src/main/res/xml/item_app_widget_info.xml
new file mode 100644
index 0000000..043d27b
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/app/src/main/res/xml/item_app_widget_info.xml
@@ -0,0 +1,15 @@
+
+
+
\ No newline at end of file
diff --git a/examples/0602/MyAndroidTutorial/app/src/main/res/xml/mypreference.xml b/examples/0602/MyAndroidTutorial/app/src/main/res/xml/mypreference.xml
new file mode 100644
index 0000000..33e714c
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/app/src/main/res/xml/mypreference.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0602/MyAndroidTutorial/app/src/release/res/values/google_maps_api.xml b/examples/0602/MyAndroidTutorial/app/src/release/res/values/google_maps_api.xml
new file mode 100644
index 0000000..c4e2431
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/app/src/release/res/values/google_maps_api.xml
@@ -0,0 +1,18 @@
+
+
+
+ YOUR_KEY_HERE
+
+
diff --git a/examples/0602/MyAndroidTutorial/build.gradle b/examples/0602/MyAndroidTutorial/build.gradle
new file mode 100644
index 0000000..6356aab
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/build.gradle
@@ -0,0 +1,19 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+ repositories {
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:1.0.0'
+
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+}
+
+allprojects {
+ repositories {
+ jcenter()
+ }
+}
diff --git a/examples/0602/MyAndroidTutorial/gradle.properties b/examples/0602/MyAndroidTutorial/gradle.properties
new file mode 100644
index 0000000..1d3591c
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/gradle.properties
@@ -0,0 +1,18 @@
+# Project-wide Gradle settings.
+
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+# Default value: -Xmx10248m -XX:MaxPermSize=256m
+# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
+
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
\ No newline at end of file
diff --git a/examples/0602/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.jar b/examples/0602/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
Binary files /dev/null and b/examples/0602/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/examples/0602/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.properties b/examples/0602/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..0c71e76
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
diff --git a/examples/0602/MyAndroidTutorial/gradlew b/examples/0602/MyAndroidTutorial/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/examples/0602/MyAndroidTutorial/gradlew.bat b/examples/0602/MyAndroidTutorial/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/examples/0602/MyAndroidTutorial/settings.gradle b/examples/0602/MyAndroidTutorial/settings.gradle
new file mode 100644
index 0000000..e7b4def
--- /dev/null
+++ b/examples/0602/MyAndroidTutorial/settings.gradle
@@ -0,0 +1 @@
+include ':app'
diff --git a/examples/0603/MyAndroidTutorial/.gitignore b/examples/0603/MyAndroidTutorial/.gitignore
new file mode 100644
index 0000000..afbdab3
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/.gitignore
@@ -0,0 +1,6 @@
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
diff --git a/examples/0603/MyAndroidTutorial/.idea/.name b/examples/0603/MyAndroidTutorial/.idea/.name
new file mode 100644
index 0000000..5bb7a85
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/.idea/.name
@@ -0,0 +1 @@
+MyAndroidTutorial
\ No newline at end of file
diff --git a/examples/0603/MyAndroidTutorial/.idea/compiler.xml b/examples/0603/MyAndroidTutorial/.idea/compiler.xml
new file mode 100644
index 0000000..9a8b7e5
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/.idea/compiler.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0603/MyAndroidTutorial/.idea/copyright/profiles_settings.xml b/examples/0603/MyAndroidTutorial/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..e7bedf3
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/examples/0603/MyAndroidTutorial/.idea/gradle.xml b/examples/0603/MyAndroidTutorial/.idea/gradle.xml
new file mode 100644
index 0000000..c595ad9
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/.idea/gradle.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0603/MyAndroidTutorial/.idea/misc.xml b/examples/0603/MyAndroidTutorial/.idea/misc.xml
new file mode 100644
index 0000000..b0c0cbc
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/.idea/misc.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0603/MyAndroidTutorial/.idea/modules.xml b/examples/0603/MyAndroidTutorial/.idea/modules.xml
new file mode 100644
index 0000000..5edca7e
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/.idea/modules.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0603/MyAndroidTutorial/.idea/vcs.xml b/examples/0603/MyAndroidTutorial/.idea/vcs.xml
new file mode 100644
index 0000000..6564d52
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0603/MyAndroidTutorial/MyAndroidTutorial.iml b/examples/0603/MyAndroidTutorial/MyAndroidTutorial.iml
new file mode 100644
index 0000000..62d899f
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/MyAndroidTutorial.iml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0603/MyAndroidTutorial/app/.gitignore b/examples/0603/MyAndroidTutorial/app/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/app/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/examples/0603/MyAndroidTutorial/app/app.iml b/examples/0603/MyAndroidTutorial/app/app.iml
new file mode 100644
index 0000000..2041401
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/app/app.iml
@@ -0,0 +1,114 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0603/MyAndroidTutorial/app/build.gradle b/examples/0603/MyAndroidTutorial/app/build.gradle
new file mode 100644
index 0000000..c5d367d
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/app/build.gradle
@@ -0,0 +1,27 @@
+apply plugin: 'com.android.application'
+
+android {
+ compileSdkVersion 21
+ buildToolsVersion "21.1.2"
+
+ defaultConfig {
+ applicationId "net.macdidi.myandroidtutorial"
+ minSdkVersion 16
+ targetSdkVersion 21
+ versionCode 1
+ versionName "1.0"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ compile fileTree(dir: 'libs', include: ['*.jar'])
+ compile 'com.android.support:appcompat-v7:22.0.0'
+ compile 'com.google.android.gms:play-services:7.0.0'
+ compile 'com.android.support:recyclerview-v7:21.0.+'
+}
diff --git a/examples/0603/MyAndroidTutorial/app/proguard-rules.pro b/examples/0603/MyAndroidTutorial/app/proguard-rules.pro
new file mode 100644
index 0000000..b5fa7ec
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/app/proguard-rules.pro
@@ -0,0 +1,17 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /Users/macdidi5/Library/Android/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
diff --git a/examples/0603/MyAndroidTutorial/app/src/androidTest/java/net/macdidi/myandroidtutorial/ApplicationTest.java b/examples/0603/MyAndroidTutorial/app/src/androidTest/java/net/macdidi/myandroidtutorial/ApplicationTest.java
new file mode 100644
index 0000000..2cb214e
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/app/src/androidTest/java/net/macdidi/myandroidtutorial/ApplicationTest.java
@@ -0,0 +1,13 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Application;
+import android.test.ApplicationTestCase;
+
+/**
+ * Testing Fundamentals
+ */
+public class ApplicationTest extends ApplicationTestCase {
+ public ApplicationTest() {
+ super(Application.class);
+ }
+}
\ No newline at end of file
diff --git a/examples/0603/MyAndroidTutorial/app/src/debug/res/values/google_maps_api.xml b/examples/0603/MyAndroidTutorial/app/src/debug/res/values/google_maps_api.xml
new file mode 100644
index 0000000..7341c8d
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/app/src/debug/res/values/google_maps_api.xml
@@ -0,0 +1,18 @@
+
+
+
+ AIzaSyCZg9YWlfokPA96VxWGYr6u4C12jL16VhM
+
+
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/AndroidManifest.xml b/examples/0603/MyAndroidTutorial/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..06271c2
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/app/src/main/AndroidManifest.xml
@@ -0,0 +1,131 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/AboutActivity.java b/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/AboutActivity.java
new file mode 100644
index 0000000..42dddeb
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/AboutActivity.java
@@ -0,0 +1,24 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.view.Window;
+
+public class AboutActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ // 取消元件的應用程式標題
+ requestWindowFeature(Window.FEATURE_NO_TITLE);
+ setContentView(R.layout.activity_about);
+ }
+
+ // 結束按鈕
+ public void clickOk(View view) {
+ // 呼叫這個方法結束Activity元件
+ finish();
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/AlarmReceiver.java b/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/AlarmReceiver.java
new file mode 100644
index 0000000..368165c
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/AlarmReceiver.java
@@ -0,0 +1,86 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.support.v4.app.NotificationCompat;
+
+import java.io.File;
+
+public class AlarmReceiver extends BroadcastReceiver {
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ // 讀取記事標題
+ //String title = intent.getStringExtra("title");
+ // 顯示訊息框
+ //Toast.makeText(context, title, Toast.LENGTH_LONG).show();
+
+ // 讀取記事編號
+ long id = intent.getLongExtra("id", 0);
+
+ if (id != 0) {
+ sendNotify(context, id);
+ }
+ }
+
+ private void sendNotify(Context context, long id) {
+ // 建立資料庫物件
+ ItemDAO itemDAO = new ItemDAO(context.getApplicationContext());
+ // 讀取指定編號的記事物件
+ Item item = itemDAO.get(id);
+
+ // 建立照片檔案物件
+ File file = new File(FileUtil.getExternalStorageDir(FileUtil.APP_DIR),
+ "P" + item.getFileName() + ".jpg");
+
+ // 是否儲存照片檔案
+ boolean isPicture = (item.getFileName() != null &&
+ item.getFileName().length() > 0 &&
+ file.exists());
+
+ // 取得NotificationManager物件
+ NotificationManager nm = (NotificationManager)
+ context.getSystemService(Context.NOTIFICATION_SERVICE);
+
+ // 如果有儲存照片檔案
+ if (isPicture) {
+ // 建立Notification.Builder物件,因為要設定大型圖片樣式
+ // 所以不能使用NotificationCompat.Builder
+ Notification.Builder builder = new Notification.Builder(context);
+ builder.setSmallIcon(android.R.drawable.star_on)
+ .setWhen(System.currentTimeMillis())
+ .setContentTitle(context.getString(R.string.app_name));
+
+ // 建立大型圖片樣式物件
+ Notification.BigPictureStyle bigPictureStyle =
+ new Notification.BigPictureStyle();
+ // 設定圖片與簡介
+ Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
+ bigPictureStyle.bigPicture(bitmap)
+ .setSummaryText(item.getTitle());
+ // 設定樣式為大型圖片
+ builder.setStyle(bigPictureStyle);
+ // 發出通知
+ nm.notify((int)item.getId(), builder.build());
+ }
+ // 如果沒有儲存照片檔案
+ else {
+ // 建立NotificationCompat.Builder物件
+ NotificationCompat.Builder builder =
+ new NotificationCompat.Builder(context);
+ // 設定圖示、時間、內容標題和內容訊息
+ builder.setSmallIcon(android.R.drawable.star_big_on)
+ .setWhen(System.currentTimeMillis())
+ .setContentTitle(context.getString(R.string.app_name))
+ .setContentText(item.getTitle());
+ // 發出通知
+ nm.notify((int)item.getId(), builder.build());
+ }
+ }
+
+}
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ColorActivity.java b/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ColorActivity.java
new file mode 100644
index 0000000..182cd55
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ColorActivity.java
@@ -0,0 +1,75 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.LinearLayout;
+
+public class ColorActivity extends Activity {
+
+ private LinearLayout color_gallery;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_color);
+
+ processViews();
+
+ ColorListener listener = new ColorListener();
+
+ for (Colors c : Colors.values()) {
+ Button button = new Button(this);
+ button.setId(c.parseColor());
+ LinearLayout.LayoutParams layout =
+ new LinearLayout.LayoutParams(128, 128);
+ layout.setMargins(6, 6, 6, 6);
+ button.setLayoutParams(layout);
+ button.setBackgroundColor(c.parseColor());
+
+ button.setOnClickListener(listener);
+
+ color_gallery.addView(button);
+ }
+ }
+
+ private void processViews() {
+ color_gallery = (LinearLayout) findViewById(R.id.color_gallery);
+ }
+
+ private class ColorListener implements OnClickListener {
+
+ @Override
+ public void onClick(View view) {
+ String action = ColorActivity.this.getIntent().getAction();
+
+ // 經由設定元件啟動
+ if (action != null &&
+ action.equals("net.macdidi.myandroidtutorial.CHOOSE_COLOR")) {
+ // 建立SharedPreferences物件
+ SharedPreferences.Editor editor =
+ PreferenceManager.getDefaultSharedPreferences(
+ ColorActivity.this).edit();
+ // 儲存預設顏色
+ editor.putInt("DEFAULT_COLOR", view.getId());
+ // 寫入設定值
+ editor.commit();
+ finish();
+ }
+ // 經由新增或修改記事的元件啟動
+ else {
+ Intent result = getIntent();
+ result.putExtra("colorId", view.getId());
+ setResult(Activity.RESULT_OK, result);
+ finish();
+ }
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Colors.java b/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Colors.java
new file mode 100644
index 0000000..1462149
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Colors.java
@@ -0,0 +1,24 @@
+package net.macdidi.myandroidtutorial;
+
+import android.graphics.Color;
+
+public enum Colors {
+
+ LIGHTGREY("#D3D3D3"), BLUE("#33B5E5"), PURPLE("#AA66CC"),
+ GREEN("#99CC00"), ORANGE("#FFBB33"), RED("#FF4444");
+
+ private String code;
+
+ private Colors(String code) {
+ this.code = code;
+ }
+
+ public String getCode() {
+ return code;
+ }
+
+ public int parseColor() {
+ return Color.parseColor(code);
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/FileUtil.java b/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/FileUtil.java
new file mode 100644
index 0000000..1fb41be
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/FileUtil.java
@@ -0,0 +1,112 @@
+package net.macdidi.myandroidtutorial;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.os.Environment;
+import android.util.Log;
+import android.widget.ImageView;
+
+import java.io.File;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+public class FileUtil {
+
+ // 應用程式儲存檔案的目錄
+ public static final String APP_DIR = "androidtutorial";
+
+ // 外部儲存設備是否可寫入
+ public static boolean isExternalStorageWritable() {
+ // 取得目前外部儲存設備的狀態
+ String state = Environment.getExternalStorageState();
+
+ // 判斷是否可寫入
+ if (Environment.MEDIA_MOUNTED.equals(state)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ // 外部儲存設備是否可讀取
+ public static boolean isExternalStorageReadable() {
+ // 取得目前外部儲存設備的狀態
+ String state = Environment.getExternalStorageState();
+
+ // 判斷是否可讀取
+ if (Environment.MEDIA_MOUNTED.equals(state) ||
+ Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ // 建立並傳回在公用相簿下參數指定的路徑
+ public static File getPublicAlbumStorageDir(String albumName) {
+ // 取得公用的照片路徑
+ File pictures = Environment.getExternalStoragePublicDirectory(
+ Environment.DIRECTORY_PICTURES);
+ // 準備在照片路徑下建立一個指定的路徑
+ File file = new File(pictures, albumName);
+
+ // 如果建立路徑不成功
+ if (!file.mkdirs()) {
+ Log.e("getAlbumStorageDir", "Directory not created");
+ }
+
+ return file;
+ }
+
+ // 建立並傳回在應用程式專用相簿下參數指定的路徑
+ public static File getAlbumStorageDir(Context context, String albumName) {
+ // 取得應用程式專用的照片路徑
+ File pictures = context.getExternalFilesDir(
+ Environment.DIRECTORY_PICTURES);
+ // 準備在照片路徑下建立一個指定的路徑
+ File file = new File(pictures, albumName);
+
+ // 如果建立路徑不成功
+ if (!file.mkdirs()) {
+ Log.e("getAlbumStorageDir", "Directory not created");
+ }
+
+ return file;
+ }
+
+ // 建立並傳回外部儲存媒體參數指定的路徑
+ public static File getExternalStorageDir(String dir) {
+ File result = new File(
+ Environment.getExternalStorageDirectory(), dir);
+
+ if (!isExternalStorageWritable()) {
+ return null;
+ }
+
+ if (!result.exists() && !result.mkdirs()) {
+ return null;
+ }
+
+ return result;
+ }
+
+ // 讀取指定的照片檔案名稱設定給ImageView元件
+ public static void fileToImageView(String fileName, ImageView imageView) {
+ if (new File(fileName).exists()) {
+ Bitmap bitmap = BitmapFactory.decodeFile(fileName);
+ imageView.setImageBitmap(bitmap);
+ }
+ else {
+ Log.e("fileToImageView", fileName + " not found.");
+ }
+ }
+
+ // 產生唯一的檔案名稱
+ public static String getUniqueFileName() {
+ // 使用年月日_時分秒格式為檔案名稱
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
+ return sdf.format(new Date());
+ }
+
+}
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/InitAlarmReceiver.java b/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/InitAlarmReceiver.java
new file mode 100644
index 0000000..959785f
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/InitAlarmReceiver.java
@@ -0,0 +1,49 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+import java.util.Calendar;
+import java.util.List;
+
+public class InitAlarmReceiver extends BroadcastReceiver {
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ // 建立資料庫物件
+ ItemDAO itemDAO = new ItemDAO(context.getApplicationContext());
+ // 讀取資料庫所有記事資料
+ List- items = itemDAO.getAll();
+
+ // 讀取目前時間
+ long current = Calendar.getInstance().getTimeInMillis();
+
+ AlarmManager am = (AlarmManager)
+ context.getSystemService(Context.ALARM_SERVICE);
+
+ for (Item item : items) {
+ long alarm = item.getAlarmDatetime();
+
+ // 如果沒有設定提醒或是提醒已經過期
+ if (alarm == 0 || alarm <= current) {
+ continue;
+ }
+
+ // 設定提醒
+ Intent alarmIntent = new Intent(context, AlarmReceiver.class);
+ //alarmIntent.putExtra("title", item.getTitle());
+
+ // 加入記事編號
+ intent.putExtra("id", item.getId());
+
+ PendingIntent pi = PendingIntent.getBroadcast(
+ context, (int)item.getId(),
+ alarmIntent, PendingIntent.FLAG_ONE_SHOT);
+ am.set(AlarmManager.RTC_WAKEUP, item.getAlarmDatetime(), pi);
+ }
+ }
+
+}
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Item.java b/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Item.java
new file mode 100644
index 0000000..e2bc93d
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/Item.java
@@ -0,0 +1,156 @@
+package net.macdidi.myandroidtutorial;
+
+import java.util.Date;
+import java.util.Locale;
+
+public class Item implements java.io.Serializable {
+
+ // 編號、日期時間、顏色、標題、內容、照片檔案名稱、錄音檔案名稱、經緯度、修改、已選擇
+ private long id;
+ private long datetime;
+ private Colors color;
+ private String title;
+ private String content;
+ private String fileName;
+ private String recFileName;
+ private double latitude;
+ private double longitude;
+ private long lastModify;
+ private boolean selected;
+
+ // 提醒日期時間
+ private long alarmDatetime;
+
+ public Item() {
+ title = "";
+ content = "";
+ color = Colors.LIGHTGREY;
+ }
+
+ public Item(long id, long datetime, Colors color, String title,
+ String content, String fileName, String recFileName,
+ double latitude, double longitude, long lastModify) {
+ this.id = id;
+ this.datetime = datetime;
+ this.color = color;
+ this.title = title;
+ this.content = content;
+ this.fileName = fileName;
+ this.recFileName = recFileName;
+ this.latitude = latitude;
+ this.longitude = longitude;
+ this.lastModify = lastModify;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public long getDatetime() {
+ return datetime;
+ }
+
+ // 裝置區域的日期時間
+ public String getLocaleDatetime() {
+ return String.format(Locale.getDefault(), "%tF %
0) {
+ // 照片檔案物件
+ File file = configFileName("P", ".jpg");
+
+ // 如果照片檔案存在
+ if (file.exists()) {
+ // 顯示照片元件
+ picture.setVisibility(View.VISIBLE);
+ // 設定照片
+ FileUtil.fileToImageView(file.getAbsolutePath(), picture);
+ }
+ }
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (resultCode == Activity.RESULT_OK) {
+ switch (requestCode) {
+ // 照像
+ case START_CAMERA:
+ // 設定照片檔案名稱
+ item.setFileName(fileName);
+ break;
+ case START_RECORD:
+ // 設定錄音檔案名稱
+ item.setRecFileName(fileName);
+ break;
+ case START_LOCATION:
+ // 讀取與設定座標
+ double lat = data.getDoubleExtra("lat", 0.0);
+ double lng = data.getDoubleExtra("lng", 0.0);
+ item.setLatitude(lat);
+ item.setLongitude(lng);
+ break;
+ case START_ALARM:
+ break;
+ // 設定顏色
+ case START_COLOR:
+ int colorId = data.getIntExtra(
+ "colorId", Colors.LIGHTGREY.parseColor());
+ item.setColor(getColors(colorId));
+ break;
+ }
+ }
+ }
+
+ public static Colors getColors(int color) {
+ Colors result = Colors.LIGHTGREY;
+
+ if (color == Colors.BLUE.parseColor()) {
+ result = Colors.BLUE;
+ }
+ else if (color == Colors.PURPLE.parseColor()) {
+ result = Colors.PURPLE;
+ }
+ else if (color == Colors.GREEN.parseColor()) {
+ result = Colors.GREEN;
+ }
+ else if (color == Colors.ORANGE.parseColor()) {
+ result = Colors.ORANGE;
+ }
+ else if (color == Colors.RED.parseColor()) {
+ result = Colors.RED;
+ }
+
+ return result;
+ }
+
+ private void processViews() {
+ title_text = (EditText) findViewById(R.id.title_text);
+ content_text = (EditText) findViewById(R.id.content_text);
+ // 取得顯示照片的ImageView元件
+ picture = (ImageView) findViewById(R.id.picture);
+ }
+
+ // 點擊確定與取消按鈕都會呼叫這個方法
+ public void onSubmit(View view) {
+
+ if (view.getId() == R.id.ok_teim) {
+ String titleText = title_text.getText().toString();
+ String contentText = content_text.getText().toString();
+
+ item.setTitle(titleText);
+ item.setContent(contentText);
+
+ if (getIntent().getAction().equals(
+ "net.macdidi.myandroidtutorial.EDIT_ITEM")) {
+ item.setLastModify(new Date().getTime());
+ }
+ // 新增記事
+ else {
+ item.setDatetime(new Date().getTime());
+ }
+
+ Intent result = getIntent();
+ result.putExtra("net.macdidi.myandroidtutorial.Item", item);
+ setResult(Activity.RESULT_OK, result);
+ }
+
+ // 結束
+ finish();
+ }
+
+ public void clickFunction(View view) {
+ int id = view.getId();
+
+ switch (id) {
+ case R.id.take_picture:
+ // 啟動相機元件用的Intent物件
+ Intent intentCamera =
+ new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
+
+ // 照片檔案名稱
+ File pictureFile = configFileName("P", ".jpg");
+ Uri uri = Uri.fromFile(pictureFile);
+ // 設定檔案名稱
+ intentCamera.putExtra(MediaStore.EXTRA_OUTPUT, uri);
+ // 啟動相機元件
+ startActivityForResult(intentCamera, START_CAMERA);
+ break;
+ case R.id.record_sound:
+ // 錄音檔案名稱
+ final File recordFile = configRecFileName("R", ".mp3");
+
+ // 如果已經有錄音檔,詢問播放或重新錄製
+ if (recordFile.exists()) {
+ // 詢問播放還是重新錄製的對話框
+ AlertDialog.Builder d = new AlertDialog.Builder(this);
+
+ d.setTitle(R.string.title_record)
+ .setCancelable(false);
+ d.setPositiveButton(R.string.record_play,
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ // 播放
+ Intent playIntent = new Intent(
+ ItemActivity.this, PlayActivity.class);
+ playIntent.putExtra("fileName",
+ recordFile.getAbsolutePath());
+ startActivity(playIntent);
+ }
+ });
+ d.setNeutralButton(R.string.record_new,
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ goToRecord(recordFile);
+ }
+ });
+ d.setNegativeButton(android.R.string.cancel, null);
+
+ // 顯示對話框
+ d.show();
+ }
+ // 如果沒有錄音檔,啟動錄音元件
+ else {
+ goToRecord(recordFile);
+ }
+
+ break;
+ case R.id.set_location:
+ // 啟動地圖元件用的Intent物件
+ Intent intentMap = new Intent(this, MapsActivity.class);
+
+ // 設定儲存的座標
+ intentMap.putExtra("lat", item.getLatitude());
+ intentMap.putExtra("lng", item.getLongitude());
+ intentMap.putExtra("title", item.getTitle());
+ intentMap.putExtra("datetime", item.getLocaleDatetime());
+
+ // 啟動地圖元件
+ startActivityForResult(intentMap, START_LOCATION);
+ break;
+ case R.id.set_alarm:
+ // 設定提醒日期時間
+ processSetAlarm();
+ break;
+ case R.id.select_color:
+ // 啟動設定顏色的Activity元件
+ startActivityForResult(
+ new Intent(this, ColorActivity.class), START_COLOR);
+ break;
+ }
+
+ }
+
+ // 設定提醒日期時間
+ private void processSetAlarm() {
+ Calendar calendar = Calendar.getInstance();
+
+ if (item.getAlarmDatetime() != 0) {
+ // 設定為已經儲存的提醒日期時間
+ calendar.setTimeInMillis(item.getAlarmDatetime());
+ }
+
+ // 讀取年、月、日、時、分
+ int year = calendar.get(Calendar.YEAR);
+ int month = calendar.get(Calendar.MONTH);
+ int day = calendar.get(Calendar.DAY_OF_MONTH);
+ int hour = calendar.get(Calendar.HOUR_OF_DAY);
+ int minute = calendar.get(Calendar.MINUTE);
+
+ // 儲存設定的提醒日期時間
+ final Calendar alarm = Calendar.getInstance();
+
+ // 設定提醒時間
+ TimePickerDialog.OnTimeSetListener timeSetListener =
+ new TimePickerDialog.OnTimeSetListener() {
+ @Override
+ public void onTimeSet(TimePicker view,
+ int hourOfDay, int minute) {
+ alarm.set(Calendar.HOUR_OF_DAY, hourOfDay);
+ alarm.set(Calendar.MINUTE, minute);
+
+ item.setAlarmDatetime(alarm.getTimeInMillis());
+ }
+ };
+
+ // 選擇時間對話框
+ final TimePickerDialog tpd = new TimePickerDialog(
+ this, timeSetListener, hour, minute, true);
+
+ // 設定提醒日期
+ DatePickerDialog.OnDateSetListener dateSetListener =
+ new DatePickerDialog.OnDateSetListener() {
+ @Override
+ public void onDateSet(DatePicker view,
+ int year,
+ int monthOfYear,
+ int dayOfMonth) {
+ alarm.set(Calendar.YEAR, year);
+ alarm.set(Calendar.MONTH, monthOfYear);
+ alarm.set(Calendar.DAY_OF_MONTH, dayOfMonth);
+
+ // 繼續選擇提醒時間
+ tpd.show();
+ }
+ };
+
+ // 建立與顯示選擇日期對話框
+ final DatePickerDialog dpd = new DatePickerDialog(
+ this, dateSetListener, year, month, day);
+ dpd.show();
+ }
+
+ private void goToRecord(File recordFile) {
+ // 錄音
+ Intent recordIntent = new Intent(this, RecordActivity.class);
+ recordIntent.putExtra("fileName", recordFile.getAbsolutePath());
+ startActivityForResult(recordIntent, START_RECORD);
+ }
+
+ private File configFileName(String prefix, String extension) {
+ // 如果記事資料已經有檔案名稱
+ if (item.getFileName() != null && item.getFileName().length() > 0) {
+ fileName = item.getFileName();
+ }
+ // 產生檔案名稱
+ else {
+ fileName = FileUtil.getUniqueFileName();
+ }
+
+ return new File(FileUtil.getExternalStorageDir(FileUtil.APP_DIR),
+ prefix + fileName + extension);
+ }
+
+ private File configRecFileName(String prefix, String extension) {
+ // 如果記事資料已經有檔案名稱
+ if (item.getRecFileName() != null && item.getRecFileName().length() > 0) {
+ recFileName = item.getRecFileName();
+ }
+ // 產生檔案名稱
+ else {
+ recFileName = FileUtil.getUniqueFileName();
+ }
+
+ return new File(FileUtil.getExternalStorageDir(FileUtil.APP_DIR),
+ prefix + recFileName + extension);
+ }
+
+ // 點擊畫面右下角的照片縮圖元件
+ public void clickPicture(View view) {
+ Intent intent = new Intent(this, PictureActivity.class);
+
+ // 設定圖片檔案名稱
+ intent.putExtra("pictureName", configFileName("P", ".jpg").getAbsolutePath());
+
+ // 如果裝置的版本是LOLLIPOP
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ ActivityOptions options = ActivityOptions
+ .makeSceneTransitionAnimation(this, picture, "picture");
+ startActivity(intent, options.toBundle());
+ }
+ else {
+ startActivity(intent);
+ }
+ }
+
+}
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemAdapter.java b/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemAdapter.java
new file mode 100644
index 0000000..85b40ba
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemAdapter.java
@@ -0,0 +1,80 @@
+package net.macdidi.myandroidtutorial;
+
+import android.content.Context;
+import android.graphics.drawable.GradientDrawable;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+import java.util.List;
+
+public class ItemAdapter extends ArrayAdapter- {
+
+ // 畫面資源編號
+ private int resource;
+ // 包裝的記事資料
+ private List
- items;
+
+ public ItemAdapter(Context context, int resource, List
- items) {
+ super(context, resource, items);
+ this.resource = resource;
+ this.items = items;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ LinearLayout itemView;
+ // 讀取目前位置的記事物件
+ final Item item = getItem(position);
+
+ if (convertView == null) {
+ // 建立項目畫面元件
+ itemView = new LinearLayout(getContext());
+ String inflater = Context.LAYOUT_INFLATER_SERVICE;
+ LayoutInflater li = (LayoutInflater)
+ getContext().getSystemService(inflater);
+ li.inflate(resource, itemView, true);
+ }
+ else {
+ itemView = (LinearLayout) convertView;
+ }
+
+ // 讀取記事顏色、已選擇、標題與日期時間元件
+ RelativeLayout typeColor = (RelativeLayout) itemView.findViewById(R.id.type_color);
+ ImageView selectedItem = (ImageView) itemView.findViewById(R.id.selected_item);
+ TextView titleView = (TextView) itemView.findViewById(R.id.title_text);
+ TextView dateView = (TextView) itemView.findViewById(R.id.date_text);
+
+ // 設定記事顏色
+ GradientDrawable background = (GradientDrawable)typeColor.getBackground();
+ background.setColor(item.getColor().parseColor());
+
+ // 設定標題與日期時間
+ titleView.setText(item.getTitle());
+ dateView.setText(item.getLocaleDatetime());
+
+ // 設定是否已選擇
+ selectedItem.setVisibility(item.isSelected() ? View.VISIBLE : View.INVISIBLE);
+
+ return itemView;
+ }
+
+ // 設定指定編號的記事資料
+ public void set(int index, Item item) {
+ if (index >= 0 && index < items.size()) {
+ items.set(index, item);
+ notifyDataSetChanged();
+ }
+ }
+
+ // 讀取指定編號的記事資料
+ public Item get(int index) {
+ return items.get(index);
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemAdapterRV.java b/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemAdapterRV.java
new file mode 100644
index 0000000..9e104d4
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemAdapterRV.java
@@ -0,0 +1,84 @@
+package net.macdidi.myandroidtutorial;
+
+import android.graphics.drawable.GradientDrawable;
+import android.support.v7.widget.RecyclerView;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+import java.util.List;
+
+public class ItemAdapterRV extends RecyclerView.Adapter
{
+
+ // 包裝的記事資料
+ private List- items;
+
+ public ItemAdapterRV(List
- items) {
+ this.items = items;
+ }
+
+ @Override
+ public ItemAdapterRV.ViewHolder onCreateViewHolder(
+ ViewGroup parent, int viewType) {
+ View v = LayoutInflater.from(parent.getContext()).inflate(
+ R.layout.single_item, parent, false);
+ ViewHolder viewHolder = new ViewHolder(v);
+
+ return viewHolder;
+ }
+
+ @Override
+ public void onBindViewHolder(final ViewHolder holder, int position) {
+ final Item item = items.get(position);
+
+ // 設定記事顏色
+ GradientDrawable background = (GradientDrawable)
+ holder.typeColor.getBackground();
+ background.setColor(item.getColor().parseColor());
+
+ // 設定標題與日期時間
+ holder.titleView.setText(item.getTitle());
+ holder.dateView.setText(item.getLocaleDatetime());
+
+ // 設定是否已選擇
+ holder.selectedItem.setVisibility(
+ item.isSelected() ? View.VISIBLE : View.INVISIBLE);
+ }
+
+ @Override
+ public int getItemCount() {
+ return items.size();
+ }
+
+ public void add(Item item) {
+ items.add(item);
+ notifyItemInserted(items.size());
+ }
+
+ // 一定要使用ViewHolder包裝畫面元件
+ public class ViewHolder extends RecyclerView.ViewHolder {
+
+ protected RelativeLayout typeColor;
+ protected ImageView selectedItem;
+ protected TextView titleView;
+ protected TextView dateView;
+
+ protected View rootView;
+
+ public ViewHolder(View view) {
+ super(view);
+
+ typeColor = (RelativeLayout) itemView.findViewById(R.id.type_color);
+ selectedItem = (ImageView) itemView.findViewById(R.id.selected_item);
+ titleView = (TextView) itemView.findViewById(R.id.title_text);
+ dateView = (TextView) itemView.findViewById(R.id.date_text);
+
+ rootView = view;
+ }
+
+ }
+
+}
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemAppWidget.java b/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemAppWidget.java
new file mode 100644
index 0000000..9301f57
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemAppWidget.java
@@ -0,0 +1,72 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.PendingIntent;
+import android.appwidget.AppWidgetManager;
+import android.appwidget.AppWidgetProvider;
+import android.content.Context;
+import android.content.Intent;
+import android.widget.RemoteViews;
+
+
+public class ItemAppWidget extends AppWidgetProvider {
+
+ @Override
+ public void onUpdate(Context context,
+ AppWidgetManager appWidgetManager,
+ int[] appWidgetIds) {
+ final int N = appWidgetIds.length;
+
+ for (int i = 0; i < N; i++) {
+ updateAppWidget(context, appWidgetManager, appWidgetIds[i]);
+ }
+ }
+
+ @Override
+ public void onDeleted(Context context, int[] appWidgetIds) {
+ final int N = appWidgetIds.length;
+ for (int i = 0; i < N; i++) {
+ // 刪除小工具已經儲存的記事編號
+ ItemAppWidgetConfigureActivity.deleteItemPref(
+ context, appWidgetIds[i]);
+ }
+ }
+
+ @Override
+ public void onEnabled(Context context) {
+
+ }
+
+ @Override
+ public void onDisabled(Context context) {
+
+ }
+
+ static void updateAppWidget(Context context,
+ AppWidgetManager appWidgetManager,
+ int appWidgetId) {
+ // 讀取小工具儲存的記事編號
+ long id = ItemAppWidgetConfigureActivity.loadItemPref(
+ context, appWidgetId);
+ // 建立小工具畫面元件
+ RemoteViews views = new RemoteViews(
+ context.getPackageName(), R.layout.item_app_widget);
+ // 讀取指定編號的記事物件
+ ItemDAO itemDAO = new ItemDAO(context.getApplicationContext());
+ Item item = itemDAO.get(id);
+
+ // 設定小工具畫面顯示記事標題
+ views.setTextViewText(R.id.appwidget_text,
+ item != null ? item.getTitle() : "NA");
+
+ // 點選小工具畫面的記事標題後,啟動記事應用程式
+ Intent intent = new Intent(context, MainActivity.class);
+ PendingIntent pending = PendingIntent.getActivity(
+ context, 0, intent, 0);
+ views.setOnClickPendingIntent(R.id.appwidget_text, pending);
+
+ // 更新小工具
+ appWidgetManager.updateAppWidget(appWidgetId, views);
+ }
+}
+
+
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemAppWidgetConfigureActivity.java b/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemAppWidgetConfigureActivity.java
new file mode 100644
index 0000000..f83be71
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemAppWidgetConfigureActivity.java
@@ -0,0 +1,120 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.appwidget.AppWidgetManager;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.ListView;
+
+import java.util.List;
+
+
+public class ItemAppWidgetConfigureActivity extends Activity {
+
+ int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
+
+ private static final String PREFS_NAME =
+ "net.macdidi.myandroidtutorial.ItemAppWidget";
+ private static final String PREF_PREFIX_KEY = "appwidget_";
+
+ // 選擇小工具使用的記事項目
+ private ListView item_list;
+ private ItemAdapter itemAdapter;
+ private List
- items;
+ private ItemDAO itemDAO;
+
+ public ItemAppWidgetConfigureActivity() {
+ super();
+ }
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ setResult(RESULT_CANCELED);
+
+ // 改為使用應用程式主畫面
+ setContentView(R.layout.activity_main);
+
+ // 建立與設定選擇小工具使用的記事項目需要的物件
+ item_list = (ListView)findViewById(R.id.item_list);
+ itemDAO = new ItemDAO(getApplicationContext());
+ items = itemDAO.getAll();
+ itemAdapter = new ItemAdapter(this, R.layout.single_item, items);
+ item_list.setAdapter(itemAdapter);
+ item_list.setOnItemClickListener(itemListener);
+
+ Intent intent = getIntent();
+ Bundle extras = intent.getExtras();
+
+ if (extras != null) {
+ mAppWidgetId = extras.getInt(
+ AppWidgetManager.EXTRA_APPWIDGET_ID,
+ AppWidgetManager.INVALID_APPWIDGET_ID);
+ }
+
+ if (mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
+ finish();
+ return;
+ }
+
+ }
+
+ // 選擇記事項目
+ AdapterView.OnItemClickListener itemListener =
+ new AdapterView.OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView> parent, View view,
+ int position, long id) {
+ final Context context = ItemAppWidgetConfigureActivity.this;
+
+ // 讀取與儲存選擇的記事物件
+ Item item = itemAdapter.getItem(position);
+ saveItemPref(context, mAppWidgetId, item.getId());
+
+ AppWidgetManager appWidgetManager =
+ AppWidgetManager.getInstance(context);
+ ItemAppWidget.updateAppWidget(
+ context, appWidgetManager, mAppWidgetId);
+ Intent resultValue = new Intent();
+ resultValue.putExtra(
+ AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
+ setResult(RESULT_OK, resultValue);
+
+ finish();
+ }
+ };
+
+ // 儲存選擇的記事編號
+ static void saveItemPref(Context context, int appWidgetId, long id) {
+ SharedPreferences.Editor prefs =
+ context.getSharedPreferences(PREFS_NAME, 0).edit();
+ prefs.putLong(PREF_PREFIX_KEY + appWidgetId, id);
+ prefs.commit();
+ }
+
+ // 讀取記事編號
+ static long loadItemPref(Context context, int appWidgetId) {
+ SharedPreferences prefs =
+ context.getSharedPreferences(PREFS_NAME, 0);
+ long idValue = prefs.getLong(PREF_PREFIX_KEY + appWidgetId, 0);
+
+ return idValue;
+ }
+
+ // 刪除記事編號
+ static void deleteItemPref(Context context, int appWidgetId) {
+ SharedPreferences.Editor prefs =
+ context.getSharedPreferences(PREFS_NAME, 0).edit();
+ prefs.remove(PREF_PREFIX_KEY + appWidgetId);
+ prefs.commit();
+ }
+
+}
+
+
+
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemDAO.java b/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemDAO.java
new file mode 100644
index 0000000..b3c7b49
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/ItemDAO.java
@@ -0,0 +1,214 @@
+package net.macdidi.myandroidtutorial;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+// 資料功能類別
+public class ItemDAO {
+ // 表格名稱
+ public static final String TABLE_NAME = "item";
+
+ // 編號表格欄位名稱,固定不變
+ public static final String KEY_ID = "_id";
+
+ // 其它表格欄位名稱
+ public static final String DATETIME_COLUMN = "datetime";
+ public static final String COLOR_COLUMN = "color";
+ public static final String TITLE_COLUMN = "title";
+ public static final String CONTENT_COLUMN = "content";
+ public static final String FILENAME_COLUMN = "filename";
+ public static final String RECFILENAME_COLUMN = "recfilename";
+ public static final String LATITUDE_COLUMN = "latitude";
+ public static final String LONGITUDE_COLUMN = "longitude";
+ public static final String LASTMODIFY_COLUMN = "lastmodify";
+
+ // 提醒日期時間
+ public static final String ALARMDATETIME_COLUMN = "alarmdatetime";
+
+ // 使用上面宣告的變數建立表格的SQL指令
+ public static final String CREATE_TABLE =
+ "CREATE TABLE " + TABLE_NAME + " (" +
+ KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
+ DATETIME_COLUMN + " INTEGER NOT NULL, " +
+ COLOR_COLUMN + " INTEGER NOT NULL, " +
+ TITLE_COLUMN + " TEXT NOT NULL, " +
+ CONTENT_COLUMN + " TEXT NOT NULL, " +
+ FILENAME_COLUMN + " TEXT, " +
+ RECFILENAME_COLUMN + " TEXT, " +
+ LATITUDE_COLUMN + " REAL, " +
+ LONGITUDE_COLUMN + " REAL, " +
+ LASTMODIFY_COLUMN + " INTEGER, " +
+ ALARMDATETIME_COLUMN + " INTEGER)";
+
+ // 資料庫物件
+ private SQLiteDatabase db;
+
+ // 建構子,一般的應用都不需要修改
+ public ItemDAO(Context context) {
+ db = MyDBHelper.getDatabase(context);
+ }
+
+ // 關閉資料庫,一般的應用都不需要修改
+ public void close() {
+ db.close();
+ }
+
+ // 新增參數指定的物件
+ public Item insert(Item item) {
+ // 建立準備新增資料的ContentValues物件
+ ContentValues cv = new ContentValues();
+
+ // 加入ContentValues物件包裝的新增資料
+ // 第一個參數是欄位名稱, 第二個參數是欄位的資料
+ cv.put(DATETIME_COLUMN, item.getDatetime());
+ cv.put(COLOR_COLUMN, item.getColor().parseColor());
+ cv.put(TITLE_COLUMN, item.getTitle());
+ cv.put(CONTENT_COLUMN, item.getContent());
+ cv.put(FILENAME_COLUMN, item.getFileName());
+ cv.put(RECFILENAME_COLUMN, item.getRecFileName());
+ cv.put(LATITUDE_COLUMN, item.getLatitude());
+ cv.put(LONGITUDE_COLUMN, item.getLongitude());
+ cv.put(LASTMODIFY_COLUMN, item.getLastModify());
+
+ // 提醒日期時間
+ cv.put(ALARMDATETIME_COLUMN, item.getAlarmDatetime());
+
+ // 新增一筆資料並取得編號
+ // 第一個參數是表格名稱
+ // 第二個參數是沒有指定欄位值的預設值
+ // 第三個參數是包裝新增資料的ContentValues物件
+ long id = db.insert(TABLE_NAME, null, cv);
+
+ // 設定編號
+ item.setId(id);
+ // 回傳結果
+ return item;
+ }
+
+ // 修改參數指定的物件
+ public boolean update(Item item) {
+ // 建立準備修改資料的ContentValues物件
+ ContentValues cv = new ContentValues();
+
+ // 加入ContentValues物件包裝的修改資料
+ // 第一個參數是欄位名稱, 第二個參數是欄位的資料
+ cv.put(DATETIME_COLUMN, item.getDatetime());
+ cv.put(COLOR_COLUMN, item.getColor().parseColor());
+ cv.put(TITLE_COLUMN, item.getTitle());
+ cv.put(CONTENT_COLUMN, item.getContent());
+ cv.put(FILENAME_COLUMN, item.getFileName());
+ cv.put(RECFILENAME_COLUMN, item.getRecFileName());
+ cv.put(LATITUDE_COLUMN, item.getLatitude());
+ cv.put(LONGITUDE_COLUMN, item.getLongitude());
+ cv.put(LASTMODIFY_COLUMN, item.getLastModify());
+
+ // 提醒日期時間
+ cv.put(ALARMDATETIME_COLUMN, item.getAlarmDatetime());
+
+ // 設定修改資料的條件為編號
+ // 格式為「欄位名稱=資料」
+ String where = KEY_ID + "=" + item.getId();
+
+ // 執行修改資料並回傳修改的資料數量是否成功
+ return db.update(TABLE_NAME, cv, where, null) > 0;
+ }
+
+ // 刪除參數指定編號的資料
+ public boolean delete(long id){
+ // 設定條件為編號,格式為「欄位名稱=資料」
+ String where = KEY_ID + "=" + id;
+ // 刪除指定編號資料並回傳刪除是否成功
+ return db.delete(TABLE_NAME, where , null) > 0;
+ }
+
+ // 讀取所有記事資料
+ public List
- getAll() {
+ List
- result = new ArrayList<>();
+ Cursor cursor = db.query(
+ TABLE_NAME, null, null, null, null, null, null, null);
+
+ while (cursor.moveToNext()) {
+ result.add(getRecord(cursor));
+ }
+
+ cursor.close();
+ return result;
+ }
+
+ // 取得指定編號的資料物件
+ public Item get(long id) {
+ // 準備回傳結果用的物件
+ Item item = null;
+ // 使用編號為查詢條件
+ String where = KEY_ID + "=" + id;
+ // 執行查詢
+ Cursor result = db.query(
+ TABLE_NAME, null, where, null, null, null, null, null);
+
+ // 如果有查詢結果
+ if (result.moveToFirst()) {
+ // 讀取包裝一筆資料的物件
+ item = getRecord(result);
+ }
+
+ // 關閉Cursor物件
+ result.close();
+ // 回傳結果
+ return item;
+ }
+
+ // 把Cursor目前的資料包裝為物件
+ public Item getRecord(Cursor cursor) {
+ // 準備回傳結果用的物件
+ Item result = new Item();
+
+ result.setId(cursor.getLong(0));
+ result.setDatetime(cursor.getLong(1));
+ result.setColor(ItemActivity.getColors(cursor.getInt(2)));
+ result.setTitle(cursor.getString(3));
+ result.setContent(cursor.getString(4));
+ result.setFileName(cursor.getString(5));
+ result.setRecFileName(cursor.getString(6));
+ result.setLatitude(cursor.getDouble(7));
+ result.setLongitude(cursor.getDouble(8));
+ result.setLastModify(cursor.getLong(9));
+
+ // 提醒日期時間
+ result.setAlarmDatetime(cursor.getLong(9));
+
+ // 回傳結果
+ return result;
+ }
+
+ // 取得資料數量
+ public int getCount() {
+ int result = 0;
+ Cursor cursor = db.rawQuery("SELECT COUNT(*) FROM " + TABLE_NAME, null);
+
+ if (cursor.moveToNext()) {
+ result = cursor.getInt(0);
+ }
+
+ return result;
+ }
+
+ // 建立範例資料
+ public void sample() {
+ Item item = new Item(0, new Date().getTime(), Colors.RED, "關於Android Tutorial的事情.", "Hello content", "", "", 0, 0, 0);
+ Item item2 = new Item(0, new Date().getTime(), Colors.BLUE, "一隻非常可愛的小狗狗!", "她的名字叫「大熱狗」,又叫\n作「奶嘴」,是一隻非常可愛\n的小狗。", "", "", 25.04719, 121.516981, 0);
+ Item item3 = new Item(0, new Date().getTime(), Colors.GREEN, "一首非常好聽的音樂!", "Hello content", "", "", 0, 0, 0);
+ Item item4 = new Item(0, new Date().getTime(), Colors.ORANGE, "儲存在資料庫的資料", "Hello content", "", "", 0, 0, 0);
+
+ insert(item);
+ insert(item2);
+ insert(item3);
+ insert(item4);
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MainActivity.java b/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MainActivity.java
new file mode 100644
index 0000000..496391c
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MainActivity.java
@@ -0,0 +1,336 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.app.ActivityOptions;
+import android.app.AlarmManager;
+import android.app.AlertDialog;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.os.Build;
+import android.os.Bundle;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.TextView;
+
+import java.util.List;
+
+public class MainActivity extends Activity {
+
+ // 移除原來的ListView元件
+ //private ListView item_list;
+
+ // 加入下列需要的元件
+ private RecyclerView item_list;
+ private RecyclerView.Adapter itemAdapter;
+ private RecyclerView.LayoutManager rvLayoutManager;
+
+ private TextView show_app_name;
+
+ // 移除原來的ItemAdapter
+ //private ItemAdapter itemAdapter;
+
+ // 儲存所有記事本的List物件
+ private List
- items;
+
+ // 選單項目物件
+ private MenuItem add_item, search_item, revert_item, share_item, delete_item;
+
+ // 已選擇項目數量
+ private int selectedCount = 0;
+
+ // 宣告資料庫功能類別欄位變數
+ private ItemDAO itemDAO;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ processViews();
+ // 移除註冊監聽事件的工作,要移到下面執行
+ // processControllers();
+
+ itemDAO = new ItemDAO(getApplicationContext());
+
+ if (itemDAO.getCount() == 0) {
+ itemDAO.sample();
+ }
+
+ items = itemDAO.getAll();
+
+ // 移除原來ListView元件執行的工作
+ //itemAdapter = new ItemAdapter(this, R.layout.single_item, items);
+ //item_list.setAdapter(itemAdapter);
+
+ // 執行RecyclerView元件的設定
+ item_list.setHasFixedSize(true);
+ rvLayoutManager = new LinearLayoutManager(this);
+ item_list.setLayoutManager(rvLayoutManager);
+
+ // 在這裡執行註冊監聽事件的工作
+ processControllers();
+
+ // 設定自定動畫效果物件
+ item_list.setItemAnimator(new MyItemAnimator());
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (resultCode == Activity.RESULT_OK) {
+ Item item = (Item) data.getExtras().getSerializable(
+ "net.macdidi.myandroidtutorial.Item");
+
+ boolean updateAlarm = false;
+
+ if (requestCode == 0) {
+ item = itemDAO.insert(item);
+
+ //items.add(item);
+ //itemAdapter.notifyDataSetChanged();
+ ((ItemAdapterRV)itemAdapter).add(item);
+ }
+ else if (requestCode == 1) {
+ int position = data.getIntExtra("position", -1);
+
+ if (position != -1) {
+ Item ori = itemDAO.get(item.getId());
+ updateAlarm = (item.getAlarmDatetime() != ori.getAlarmDatetime());
+
+ itemDAO.update(item);
+
+ items.set(position, item);
+ itemAdapter.notifyDataSetChanged();
+ }
+ }
+
+ if (item.getAlarmDatetime() != 0 && updateAlarm) {
+ Intent intent = new Intent(this, AlarmReceiver.class);
+ intent.putExtra("id", item.getId());
+ PendingIntent pi = PendingIntent.getBroadcast(
+ this, (int)item.getId(),
+ intent, PendingIntent.FLAG_ONE_SHOT);
+ AlarmManager am = (AlarmManager)
+ getSystemService(Context.ALARM_SERVICE);
+ am.set(AlarmManager.RTC_WAKEUP, item.getAlarmDatetime(), pi);
+ }
+ }
+ }
+
+ private void processViews() {
+ item_list = (RecyclerView) findViewById(R.id.item_list);
+ show_app_name = (TextView) findViewById(R.id.show_app_name);
+ }
+
+ private void processControllers() {
+ itemAdapter = new ItemAdapterRV(items) {
+ @Override
+ public void onBindViewHolder(final ViewHolder holder, final int position) {
+ super.onBindViewHolder(holder, position);
+
+ // 建立與註冊項目點擊監聽物件
+ holder.rootView.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ // 讀取選擇的記事物件
+ Item item = items.get(position);
+
+ // 如果已經有勾選的項目
+ if (selectedCount > 0) {
+ // 處理是否顯示已選擇項目
+ processMenu(item);
+ // 重新設定記事項目
+ items.set(position, item);
+ } else {
+ Intent intent = new Intent(
+ "net.macdidi.myandroidtutorial.EDIT_ITEM");
+
+ // 設定記事編號與記事物件
+ intent.putExtra("position", position);
+ intent.putExtra("net.macdidi.myandroidtutorial.Item", item);
+
+ // 依照版本啟動Acvitity元件
+ startActivityForVersion(intent, 1);
+ }
+ }
+ });
+
+ // 建立與註冊項目長按監聽物件
+ holder.rootView.setOnLongClickListener(new View.OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View v) {
+ // 讀取選擇的記事物件
+ Item item = items.get(position);
+ // 處理是否顯示已選擇項目
+ processMenu(item);
+ // 重新設定記事項目
+ items.set(position, item);
+ return true;
+ }
+ });
+ }
+ };
+
+ item_list.setAdapter(itemAdapter);
+ }
+
+ // 處理是否顯示已選擇項目
+ private void processMenu(Item item) {
+ if (item != null) {
+ item.setSelected(!item.isSelected());
+
+ if (item.isSelected()) {
+ selectedCount++;
+ }
+ else {
+ selectedCount--;
+ }
+ }
+
+ add_item.setVisible(selectedCount == 0);
+ search_item.setVisible(selectedCount == 0);
+ revert_item.setVisible(selectedCount > 0);
+ share_item.setVisible(selectedCount > 0);
+ delete_item.setVisible(selectedCount > 0);
+
+ // 通知項目勾選狀態改變
+ itemAdapter.notifyDataSetChanged();
+ }
+
+ // 載入選單資源
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ MenuInflater menuInflater = getMenuInflater();
+ menuInflater.inflate(R.menu.menu_main, menu);
+
+ // 取得選單項目物件
+ add_item = menu.findItem(R.id.add_item);
+ search_item = menu.findItem(R.id.search_item);
+ revert_item = menu.findItem(R.id.revert_item);
+ share_item = menu.findItem(R.id.share_item);
+ delete_item = menu.findItem(R.id.delete_item);
+
+ // 設定選單項目
+ processMenu(null);
+
+ return true;
+ }
+
+ // 使用者選擇所有的選單項目都會呼叫這個方法
+ public void clickMenuItem(MenuItem item) {
+ int itemId = item.getItemId();
+
+ switch (itemId) {
+ case R.id.search_item:
+ break;
+ case R.id.add_item:
+ Intent intent = new Intent("net.macdidi.myandroidtutorial.ADD_ITEM");
+ startActivityForVersion(intent, 0);
+ break;
+ // 取消所有已勾選的項目
+ case R.id.revert_item:
+ for (int i = 0; i < items.size(); i++) {
+ Item ri = items.get(i);
+
+ if (ri.isSelected()) {
+ ri.setSelected(false);
+ // 移除
+ //itemAdapter.set(i, ri);
+ }
+ }
+
+ selectedCount = 0;
+ processMenu(null);
+
+ break;
+ // 刪除
+ case R.id.delete_item:
+ if (selectedCount == 0) {
+ break;
+ }
+
+ AlertDialog.Builder d = new AlertDialog.Builder(this);
+ String message = getString(R.string.delete_item);
+ d.setTitle(R.string.delete)
+ .setMessage(String.format(message, selectedCount));
+ d.setPositiveButton(android.R.string.yes,
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ int index = items.size() - 1;
+
+ while (index > -1) {
+ // 改為使用items物件
+ Item item = items.get(index);
+
+ if (item.isSelected()) {
+ // 改為使用items物件
+ items.remove(item);
+ itemDAO.delete(item.getId());
+ }
+
+ index--;
+ }
+
+ // 移除
+ //itemAdapter.notifyDataSetChanged();
+ selectedCount = 0;
+ processMenu(null);
+ }
+ });
+ d.setNegativeButton(android.R.string.no, null);
+ d.show();
+
+ break;
+ case R.id.googleplus_item:
+ break;
+ case R.id.facebook_item:
+ break;
+ }
+
+ }
+
+ public void aboutApp(View view) {
+ Intent intent = new Intent(this, AboutActivity.class);
+ startActivity(intent);
+ }
+
+ public void clickPreferences(MenuItem item) {
+ // 依照版本啟動Acvitity元件
+ startActivityForVersion(new Intent(this, PrefActivity.class));
+ }
+
+ private void startActivityForVersion(Intent intent, int requestCode) {
+ // 如果裝置的版本是LOLLIPOP
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ // 加入畫面轉換設定
+ startActivityForResult(intent, requestCode,
+ ActivityOptions.makeSceneTransitionAnimation(
+ MainActivity.this).toBundle());
+ }
+ else {
+ startActivityForResult(intent, requestCode);
+ }
+ }
+
+ private void startActivityForVersion(Intent intent) {
+ // 如果裝置的版本是LOLLIPOP
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ // 加入畫面轉換設定
+ startActivity(intent,
+ ActivityOptions.makeSceneTransitionAnimation(
+ MainActivity.this).toBundle());
+ }
+ else {
+ startActivity(intent);
+ }
+ }
+
+}
+
+
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MapsActivity.java b/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MapsActivity.java
new file mode 100644
index 0000000..abab911
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MapsActivity.java
@@ -0,0 +1,338 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.location.Location;
+import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
+import android.widget.Toast;
+
+import com.google.android.gms.common.ConnectionResult;
+import com.google.android.gms.common.api.GoogleApiClient;
+import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
+import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
+
+import com.google.android.gms.location.LocationListener;
+import com.google.android.gms.location.LocationRequest;
+import com.google.android.gms.location.LocationServices;
+
+import com.google.android.gms.maps.CameraUpdateFactory;
+import com.google.android.gms.maps.GoogleMap;
+import com.google.android.gms.maps.SupportMapFragment;
+import com.google.android.gms.maps.model.BitmapDescriptor;
+import com.google.android.gms.maps.model.BitmapDescriptorFactory;
+import com.google.android.gms.maps.model.CameraPosition;
+import com.google.android.gms.maps.model.LatLng;
+import com.google.android.gms.maps.model.Marker;
+import com.google.android.gms.maps.model.MarkerOptions;
+
+public class MapsActivity extends FragmentActivity
+ implements ConnectionCallbacks,
+ OnConnectionFailedListener,
+ LocationListener {
+
+ private GoogleMap mMap;
+
+ // Google API用戶端物件
+ private GoogleApiClient googleApiClient;
+
+ // Location請求物件
+ private LocationRequest locationRequest;
+
+ // 記錄目前最新的位置
+ private Location currentLocation;
+
+ // 顯示目前與儲存位置的標記物件
+ private Marker currentMarker, itemMarker;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_maps);
+ setUpMapIfNeeded();
+
+ // 建立Google API用戶端物件
+ configGoogleApiClient();
+
+ // 建立Location請求物件
+ configLocationRequest();
+
+ // 讀取記事儲存的座標
+ Intent intent = getIntent();
+ double lat = intent.getDoubleExtra("lat", 0.0);
+ double lng = intent.getDoubleExtra("lng", 0.0);
+
+ // 如果記事已經儲存座標
+ if (lat != 0.0 && lng != 0.0) {
+ // 建立座標物件
+ LatLng itemPlace = new LatLng(lat, lng);
+ // 加入地圖標記
+ addMarker(itemPlace, intent.getStringExtra("title"),
+ intent.getStringExtra("datetime"));
+ // 移動地圖
+ moveMap(itemPlace);
+ }
+ else {
+ // 連線到Google API用戶端
+ if (!googleApiClient.isConnected()) {
+ googleApiClient.connect();
+ }
+ }
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ setUpMapIfNeeded();
+
+ // 連線到Google API用戶端
+ if (!googleApiClient.isConnected() && currentMarker != null) {
+ googleApiClient.connect();
+ }
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+
+ // 移除位置請求服務
+ if (googleApiClient.isConnected()) {
+ LocationServices.FusedLocationApi.removeLocationUpdates(
+ googleApiClient, this);
+ }
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+
+ // 移除Google API用戶端連線
+ if (googleApiClient.isConnected()) {
+ googleApiClient.disconnect();
+ }
+ }
+
+ // 建立Google API用戶端物件
+ private synchronized void configGoogleApiClient() {
+ googleApiClient = new GoogleApiClient.Builder(this)
+ .addConnectionCallbacks(this)
+ .addOnConnectionFailedListener(this)
+ .addApi(LocationServices.API)
+ .build();
+ }
+
+ // 建立Location請求物件
+ private void configLocationRequest() {
+ locationRequest = new LocationRequest();
+ // 設定讀取位置資訊的間隔時間為一秒(1000ms)
+ locationRequest.setInterval(1000);
+ // 設定讀取位置資訊最快的間隔時間為一秒(1000ms)
+ locationRequest.setFastestInterval(1000);
+ // 設定優先讀取高精確度的位置資訊(GPS)
+ locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
+ }
+
+ private void setUpMapIfNeeded() {
+ if (mMap == null) {
+ mMap = ((SupportMapFragment) getSupportFragmentManager().
+ findFragmentById(R.id.map)).getMap();
+
+ if (mMap != null) {
+ // 移除地圖設定
+ //setUpMap();
+ processController();
+ }
+ }
+ }
+
+ // 移除地圖設定方法
+ private void setUpMap() {
+ // 建立位置的座標物件
+ LatLng place = new LatLng(25.033408, 121.564099);
+ // 移動地圖
+ moveMap(place);
+
+ // 加入地圖標記
+ addMarker(place, "Hello!", " Google Maps v2!");
+ }
+
+ private void processController() {
+ // 對話框按鈕事件
+ final DialogInterface.OnClickListener listener =
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ switch (which) {
+ // 更新位置資訊
+ case DialogInterface.BUTTON_POSITIVE:
+ // 連線到Google API用戶端
+ if (!googleApiClient.isConnected()) {
+ googleApiClient.connect();
+ }
+ break;
+ // 清除位置資訊
+ case DialogInterface.BUTTON_NEUTRAL:
+ Intent result = new Intent();
+ result.putExtra("lat", 0);
+ result.putExtra("lng", 0);
+ setResult(Activity.RESULT_OK, result);
+ finish();
+ break;
+ // 取消
+ case DialogInterface.BUTTON_NEGATIVE:
+ break;
+ }
+ }
+ };
+
+ // 標記訊息框點擊事件
+ mMap.setOnInfoWindowClickListener(new GoogleMap.OnInfoWindowClickListener() {
+ @Override
+ public void onInfoWindowClick(Marker marker) {
+ // 如果是記事儲存的標記
+ if (marker.equals(itemMarker)) {
+ AlertDialog.Builder ab = new AlertDialog.Builder(MapsActivity.this);
+
+ ab.setTitle(R.string.title_update_location)
+ .setMessage(R.string.message_update_location)
+ .setCancelable(true);
+
+ ab.setPositiveButton(R.string.update, listener);
+ ab.setNeutralButton(R.string.clear, listener);
+ ab.setNegativeButton(android.R.string.cancel, listener);
+
+ ab.show();
+ }
+ }
+ });
+
+ // 標記點擊事件
+ mMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
+ @Override
+ public boolean onMarkerClick(Marker marker) {
+ // 如果是目前位置標記
+ if (marker.equals(currentMarker)) {
+ AlertDialog.Builder ab = new AlertDialog.Builder(MapsActivity.this);
+
+ ab.setTitle(R.string.title_current_location)
+ .setMessage(R.string.message_current_location)
+ .setCancelable(true);
+
+ ab.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ Intent result = new Intent();
+ result.putExtra("lat", currentLocation.getLatitude());
+ result.putExtra("lng", currentLocation.getLongitude());
+ setResult(Activity.RESULT_OK, result);
+ finish();
+ }
+ });
+ ab.setNegativeButton(android.R.string.cancel, null);
+
+ ab.show();
+
+ return true;
+ }
+
+ return false;
+ }
+ });
+ }
+
+ // 移動地圖到參數指定的位置
+ private void moveMap(LatLng place) {
+ // 建立地圖攝影機的位置物件
+ CameraPosition cameraPosition =
+ new CameraPosition.Builder()
+ .target(place)
+ .zoom(17)
+ .build();
+
+ // 使用動畫的效果移動地圖
+ mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition),
+ new GoogleMap.CancelableCallback() {
+ @Override
+ public void onFinish() {
+ if (itemMarker != null) {
+ itemMarker.showInfoWindow();
+ }
+ }
+
+ @Override
+ public void onCancel() {
+
+ }
+ });
+ }
+
+ // 在地圖加入指定位置與標題的標記
+ private void addMarker(LatLng place, String title, String snippet) {
+ BitmapDescriptor icon =
+ BitmapDescriptorFactory.fromResource(R.drawable.ic_launcher);
+
+ MarkerOptions markerOptions = new MarkerOptions();
+ markerOptions.position(place)
+ .title(title)
+ .snippet(snippet)
+ .icon(icon);
+
+ // 加入並設定記事儲存的位置標記
+ itemMarker = mMap.addMarker(markerOptions);
+ }
+
+ // ConnectionCallbacks
+ @Override
+ public void onConnected(Bundle bundle) {
+ // 已經連線到Google Services
+ // 啟動位置更新服務
+ // 位置資訊更新的時候,應用程式會自動呼叫LocationListener.onLocationChanged
+ LocationServices.FusedLocationApi.requestLocationUpdates(
+ googleApiClient, locationRequest, MapsActivity.this);
+ }
+
+ // ConnectionCallbacks
+ @Override
+ public void onConnectionSuspended(int i) {
+ // Google Services連線中斷
+ // int參數是連線中斷的代號
+ }
+
+ // OnConnectionFailedListener
+ @Override
+ public void onConnectionFailed(ConnectionResult connectionResult) {
+ // Google Services連線失敗
+ // ConnectionResult參數是連線失敗的資訊
+ int errorCode = connectionResult.getErrorCode();
+
+ // 裝置沒有安裝Google Play服務
+ if (errorCode == ConnectionResult.SERVICE_MISSING) {
+ Toast.makeText(this, R.string.google_play_service_missing,
+ Toast.LENGTH_LONG).show();
+ }
+ }
+
+ // LocationListener
+ @Override
+ public void onLocationChanged(Location location) {
+ // 位置改變
+ // Location參數是目前的位置
+ currentLocation = location;
+ LatLng latLng = new LatLng(
+ location.getLatitude(), location.getLongitude());
+
+ // 設定目前位置的標記
+ if (currentMarker == null) {
+ currentMarker = mMap.addMarker(new MarkerOptions().position(latLng));
+ }
+ else {
+ currentMarker.setPosition(latLng);
+ }
+
+ // 移動地圖到目前的位置
+ moveMap(latLng);
+ }
+
+}
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MyDBHelper.java b/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MyDBHelper.java
new file mode 100644
index 0000000..9350577
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MyDBHelper.java
@@ -0,0 +1,47 @@
+package net.macdidi.myandroidtutorial;
+
+import android.content.Context;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteDatabase.CursorFactory;
+import android.database.sqlite.SQLiteOpenHelper;
+
+public class MyDBHelper extends SQLiteOpenHelper {
+
+ // 資料庫名稱
+ public static final String DATABASE_NAME = "mydata.db";
+ // 資料庫版本,資料結構改變的時候要更改這個數字,通常是加一
+ public static final int VERSION = 3;
+ // 資料庫物件,固定的欄位變數
+ private static SQLiteDatabase database;
+
+ // 建構子,在一般的應用都不需要修改
+ public MyDBHelper(Context context, String name, CursorFactory factory,
+ int version) {
+ super(context, name, factory, version);
+ }
+
+ // 需要資料庫的元件呼叫這個方法,這個方法在一般的應用都不需要修改
+ public static SQLiteDatabase getDatabase(Context context) {
+ if (database == null || !database.isOpen()) {
+ database = new MyDBHelper(context, DATABASE_NAME,
+ null, VERSION).getWritableDatabase();
+ }
+
+ return database;
+ }
+
+ @Override
+ public void onCreate(SQLiteDatabase db) {
+ // 建立應用程式需要的表格
+ db.execSQL(ItemDAO.CREATE_TABLE);
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ // 刪除原有的表格
+ db.execSQL("DROP TABLE IF EXISTS " + ItemDAO.TABLE_NAME);
+ // 呼叫onCreate建立新版的表格
+ onCreate(db);
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MyItemAnimator.java b/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MyItemAnimator.java
new file mode 100644
index 0000000..0a0892f
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/MyItemAnimator.java
@@ -0,0 +1,124 @@
+package net.macdidi.myandroidtutorial;
+
+import android.animation.Animator;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.support.v7.widget.RecyclerView;
+import android.view.View;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class MyItemAnimator extends RecyclerView.ItemAnimator {
+
+ // 儲存動畫的畫面包裝元件
+ private List
viewHolders = new ArrayList<>();
+
+ @Override
+ public void runPendingAnimations() {
+
+ if (!viewHolders.isEmpty()) {
+
+ // 動畫物件
+ AnimatorSet animator;
+ // 執行動畫的元件
+ View target;
+
+ for (final RecyclerView.ViewHolder viewHolder : viewHolders) {
+ // 取得執行動畫的元件
+ target = viewHolder.itemView;
+ // 建立動畫物件
+ animator = new AnimatorSet();
+
+ // 設定動畫效果
+ // 由左側出現與淡入效果
+ animator.playTogether(
+ ObjectAnimator.ofFloat(target, "translationX", -target.getMeasuredWidth(), 0.0f),
+ ObjectAnimator.ofFloat(target, "alpha", 0.5F, 1.0F)
+ );
+
+ // 設定動畫套用的元件與時間
+ animator.setTarget(target);
+ animator.setDuration(1000);
+
+ // 動畫結束監聽事件
+ animator.addListener(new AnimatorListenerWrapper() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ // 移除完成動畫的元件
+ viewHolders.remove(viewHolder);
+
+ if (!isRunning()) {
+ dispatchAnimationsFinished();
+ }
+ }
+ });
+
+ animator.start();
+ }
+ }
+ }
+
+ @Override
+ public boolean animateAdd(RecyclerView.ViewHolder viewHolder) {
+ return viewHolders.add(viewHolder);
+ }
+
+ @Override
+ public boolean animateRemove(RecyclerView.ViewHolder viewHolder) {
+ return false;
+ }
+
+ @Override
+ public boolean animateMove(RecyclerView.ViewHolder viewHolder,
+ int i, int i2, int i3, int i4) {
+ return false;
+ }
+
+ @Override
+ public boolean animateChange(RecyclerView.ViewHolder oldHolder,
+ RecyclerView.ViewHolder newHolder,
+ int fromLeft, int fromTop,
+ int toLeft, int toTop) {
+ return false;
+ }
+
+ @Override
+ public void endAnimation(RecyclerView.ViewHolder viewHolder) {
+
+ }
+
+ @Override
+ public void endAnimations() {
+
+ }
+
+ @Override
+ public boolean isRunning() {
+ return !viewHolders.isEmpty();
+ }
+
+ public class AnimatorListenerWrapper implements Animator.AnimatorListener {
+
+ @Override
+ public void onAnimationStart(Animator animation) {
+
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+
+ }
+
+ @Override
+ public void onAnimationCancel(Animator animation) {
+
+ }
+
+ @Override
+ public void onAnimationRepeat(Animator animation) {
+
+ }
+ }
+
+}
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PictureActivity.java b/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PictureActivity.java
new file mode 100644
index 0000000..59ac50e
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PictureActivity.java
@@ -0,0 +1,42 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Build;
+import android.os.Bundle;
+import android.view.View;
+import android.view.Window;
+import android.widget.ImageView;
+
+public class PictureActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ requestWindowFeature(Window.FEATURE_NO_TITLE);
+ setContentView(R.layout.activity_picture);
+
+ // 取得照片元件
+ ImageView picture_view = (ImageView) findViewById(R.id.picture_view);
+
+ // 讀取照片檔案名稱
+ Intent intent = getIntent();
+ String pictureName = intent.getStringExtra("pictureName");
+
+ if (pictureName != null) {
+ // 設定照片元件
+ FileUtil.fileToImageView(pictureName, picture_view);
+ }
+ }
+
+ public void clickPicture(View view) {
+ // 如果裝置的版本是LOLLIPOP
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ finishAfterTransition();
+ }
+ else {
+ finish();
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PlayActivity.java b/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PlayActivity.java
new file mode 100644
index 0000000..5cfb523
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PlayActivity.java
@@ -0,0 +1,64 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.media.MediaPlayer;
+import android.net.Uri;
+import android.os.Bundle;
+import android.view.View;
+
+public class PlayActivity extends Activity {
+
+ private MediaPlayer mediaPlayer;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_play);
+
+ Intent intent = getIntent();
+ String fileName = intent.getStringExtra("fileName");
+
+ // 建立指定資源的MediaPlayer物件
+ Uri uri = Uri.parse(fileName);
+ mediaPlayer = MediaPlayer.create(this, uri);
+ }
+
+ @Override
+ protected void onStop() {
+ if (mediaPlayer.isPlaying()) {
+ // 停止播放
+ mediaPlayer.stop();
+ }
+
+ // 清除MediaPlayer物件
+ mediaPlayer.release();
+ super.onStop();
+ }
+
+ public void onSubmit(View view) {
+ // 結束Activity元件
+ finish();
+ }
+
+ public void clickPlay(View view) {
+ // 開始播放
+ mediaPlayer.start();
+ }
+
+ public void clickPause(View view) {
+ // 暫停播放
+ mediaPlayer.pause();
+ }
+
+ public void clickStop(View view) {
+ // 停止播放
+ if (mediaPlayer.isPlaying()) {
+ mediaPlayer.stop();
+ }
+
+ // 回到開始的位置
+ mediaPlayer.seekTo(0);
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PrefActivity.java b/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PrefActivity.java
new file mode 100644
index 0000000..b2dcc4a
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/PrefActivity.java
@@ -0,0 +1,38 @@
+package net.macdidi.myandroidtutorial;
+
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceManager;
+
+public class PrefActivity extends PreferenceActivity {
+
+ private SharedPreferences sharedPreferences;
+ private Preference defaultColor;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ // 指定使用的設定畫面配置資源
+ addPreferencesFromResource(R.xml.mypreference);
+ defaultColor = (Preference)findPreference("DEFAULT_COLOR");
+ // 建立SharedPreferences物件
+ sharedPreferences =
+ PreferenceManager.getDefaultSharedPreferences(this);
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ // 讀取設定的預設顏色
+ int color = sharedPreferences.getInt("DEFAULT_COLOR", -1);
+
+ if (color != -1) {
+ // 設定顏色說明
+ defaultColor.setSummary(getString(R.string.default_color_summary) +
+ ": " + ItemActivity.getColors(color));
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/RecordActivity.java b/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/RecordActivity.java
new file mode 100644
index 0000000..62b5e93
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/app/src/main/java/net/macdidi/myandroidtutorial/RecordActivity.java
@@ -0,0 +1,180 @@
+package net.macdidi.myandroidtutorial;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.media.MediaRecorder;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.widget.ImageButton;
+import android.widget.ProgressBar;
+
+import java.io.IOException;
+
+public class RecordActivity extends Activity {
+
+ private ImageButton record_button;
+ private boolean isRecording = false;
+ private ProgressBar record_volumn;
+
+ private MyRecoder myRecoder;
+
+ private String fileName;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_record);
+
+ processViews();
+
+ // 讀取檔案名稱
+ Intent intent = getIntent();
+ fileName = intent.getStringExtra("fileName");
+ }
+
+ public void onSubmit(View view) {
+ if (isRecording) {
+ // 停止錄音
+ myRecoder.stop();
+ }
+
+ // 確定
+ if (view.getId() == R.id.record_ok) {
+ Intent result = getIntent();
+ setResult(Activity.RESULT_OK, result);
+ }
+
+ finish();
+ }
+
+ private void processViews() {
+ record_button = (ImageButton) findViewById(R.id.record_button);
+ record_volumn = (ProgressBar) findViewById(R.id.record_volumn);
+ // 隱藏狀態列ProgressBar
+ setProgressBarIndeterminateVisibility(false);
+ }
+
+ public void clickRecord(View view) {
+ // 切換
+ isRecording = !isRecording;
+
+ // 開始錄音
+ if (isRecording) {
+ // 設定按鈕圖示為錄音中
+ record_button.setImageResource(R.drawable.record_red_icon);
+ // 建立錄音物件
+ myRecoder = new MyRecoder(fileName);
+ // 開始錄音
+ myRecoder.start();
+ // 建立並執行顯示麥克風音量的AsyncTask物件
+ new MicLevelTask().execute();
+ }
+ // 停止錄音
+ else {
+ // 設定按鈕圖示為停止錄音
+ record_button.setImageResource(R.drawable.record_dark_icon);
+ // 麥克風音量歸零
+ record_volumn.setProgress(0);
+ // 停止錄音
+ myRecoder.stop();
+ }
+ }
+
+ // 在錄音過程中顯示麥克風音量
+ private class MicLevelTask extends AsyncTask {
+ @Override
+ protected Void doInBackground(Void... args) {
+ while (isRecording) {
+ publishProgress();
+
+ try {
+ Thread.sleep(200);
+ }
+ catch (InterruptedException e) {
+ Log.d("RecordActivity", e.toString());
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ protected void onProgressUpdate(Void... values) {
+ record_volumn.setProgress((int) myRecoder.getAmplitudeEMA());
+ }
+
+ }
+
+ // 執行錄音並且可以取得麥克風音量的錄音物件
+ private class MyRecoder {
+
+ private static final double EMA_FILTER = 0.6;
+ private MediaRecorder recorder = null;
+ private double mEMA = 0.0;
+ private String output;
+
+ // 建立錄音物件,參數為錄音儲存的位置與檔名
+ MyRecoder(String output) {
+ this.output = output;
+ }
+
+ // 開始錄音
+ public void start() {
+ if (recorder == null) {
+ // 建立錄音用的MediaRecorder物件
+ recorder = new MediaRecorder();
+ // 設定錄音來源為麥克風,必須在setOutputFormat方法之前呼叫
+ recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
+ // 設定輸出格式為3GP壓縮格式,必須在setAudioSource方法之後,
+ // 在prepare方法之前呼叫
+ recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
+ // 設定錄音的編碼方式,必須在setOutputFormat方法之後,
+ // 在prepare方法之前呼叫
+ recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
+ // 設定輸出的檔案名稱,必須在setOutputFormat方法之後,
+ // 在prepare方法之前呼叫
+ recorder.setOutputFile(output);
+
+ try {
+ // 準備執行錄音工作,必須在所有設定之後呼叫
+ recorder.prepare();
+ }
+ catch (IOException e) {
+ Log.d("RecordActivity", e.toString());
+ }
+
+ // 開始錄音
+ recorder.start();
+ mEMA = 0.0;
+ }
+ }
+
+ // 停止錄音
+ public void stop() {
+ if (recorder != null) {
+ // 停止錄音
+ recorder.stop();
+ // 清除錄音資源
+ recorder.release();
+ recorder = null;
+ }
+ }
+
+ public double getAmplitude() {
+ if (recorder != null)
+ return (recorder.getMaxAmplitude() / 2700.0);
+ else
+ return 0;
+ }
+
+ // 取得麥克風音量
+ public double getAmplitudeEMA() {
+ double amp = getAmplitude();
+ mEMA = EMA_FILTER * amp + (1.0 - EMA_FILTER) * mEMA;
+ return mEMA;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/res/drawable-hdpi/ic_launcher.png b/examples/0603/MyAndroidTutorial/app/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..96a442e
Binary files /dev/null and b/examples/0603/MyAndroidTutorial/app/src/main/res/drawable-hdpi/ic_launcher.png differ
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/res/drawable-mdpi/ic_launcher.png b/examples/0603/MyAndroidTutorial/app/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..359047d
Binary files /dev/null and b/examples/0603/MyAndroidTutorial/app/src/main/res/drawable-mdpi/ic_launcher.png differ
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/res/drawable-nodpi/example_appwidget_preview.png b/examples/0603/MyAndroidTutorial/app/src/main/res/drawable-nodpi/example_appwidget_preview.png
new file mode 100644
index 0000000..894b069
Binary files /dev/null and b/examples/0603/MyAndroidTutorial/app/src/main/res/drawable-nodpi/example_appwidget_preview.png differ
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/res/drawable-xhdpi/ic_launcher.png b/examples/0603/MyAndroidTutorial/app/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..71c6d76
Binary files /dev/null and b/examples/0603/MyAndroidTutorial/app/src/main/res/drawable-xhdpi/ic_launcher.png differ
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/res/drawable-xxhdpi/ic_launcher.png b/examples/0603/MyAndroidTutorial/app/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..4df1894
Binary files /dev/null and b/examples/0603/MyAndroidTutorial/app/src/main/res/drawable-xxhdpi/ic_launcher.png differ
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/res/drawable/alarm_icon.png b/examples/0603/MyAndroidTutorial/app/src/main/res/drawable/alarm_icon.png
new file mode 100644
index 0000000..c6cac88
Binary files /dev/null and b/examples/0603/MyAndroidTutorial/app/src/main/res/drawable/alarm_icon.png differ
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/res/drawable/item_drawable.xml b/examples/0603/MyAndroidTutorial/app/src/main/res/drawable/item_drawable.xml
new file mode 100644
index 0000000..37607e2
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/app/src/main/res/drawable/item_drawable.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/res/drawable/location_icon.png b/examples/0603/MyAndroidTutorial/app/src/main/res/drawable/location_icon.png
new file mode 100644
index 0000000..4c3c514
Binary files /dev/null and b/examples/0603/MyAndroidTutorial/app/src/main/res/drawable/location_icon.png differ
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/res/drawable/pause_icon.png b/examples/0603/MyAndroidTutorial/app/src/main/res/drawable/pause_icon.png
new file mode 100755
index 0000000..a5aee6f
Binary files /dev/null and b/examples/0603/MyAndroidTutorial/app/src/main/res/drawable/pause_icon.png differ
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/res/drawable/play_icon.png b/examples/0603/MyAndroidTutorial/app/src/main/res/drawable/play_icon.png
new file mode 100755
index 0000000..6a40cd5
Binary files /dev/null and b/examples/0603/MyAndroidTutorial/app/src/main/res/drawable/play_icon.png differ
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/res/drawable/record_dark_icon.png b/examples/0603/MyAndroidTutorial/app/src/main/res/drawable/record_dark_icon.png
new file mode 100755
index 0000000..bcf83ca
Binary files /dev/null and b/examples/0603/MyAndroidTutorial/app/src/main/res/drawable/record_dark_icon.png differ
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/res/drawable/record_red_icon.png b/examples/0603/MyAndroidTutorial/app/src/main/res/drawable/record_red_icon.png
new file mode 100755
index 0000000..2b44af0
Binary files /dev/null and b/examples/0603/MyAndroidTutorial/app/src/main/res/drawable/record_red_icon.png differ
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/res/drawable/record_sound_icon.png b/examples/0603/MyAndroidTutorial/app/src/main/res/drawable/record_sound_icon.png
new file mode 100755
index 0000000..a1382ac
Binary files /dev/null and b/examples/0603/MyAndroidTutorial/app/src/main/res/drawable/record_sound_icon.png differ
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/res/drawable/retangle_drawable.xml b/examples/0603/MyAndroidTutorial/app/src/main/res/drawable/retangle_drawable.xml
new file mode 100644
index 0000000..51d1e84
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/app/src/main/res/drawable/retangle_drawable.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/res/drawable/select_color_icon.png b/examples/0603/MyAndroidTutorial/app/src/main/res/drawable/select_color_icon.png
new file mode 100644
index 0000000..8567d5e
Binary files /dev/null and b/examples/0603/MyAndroidTutorial/app/src/main/res/drawable/select_color_icon.png differ
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/res/drawable/selected_icon.png b/examples/0603/MyAndroidTutorial/app/src/main/res/drawable/selected_icon.png
new file mode 100755
index 0000000..b891571
Binary files /dev/null and b/examples/0603/MyAndroidTutorial/app/src/main/res/drawable/selected_icon.png differ
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/res/drawable/stop_icon.png b/examples/0603/MyAndroidTutorial/app/src/main/res/drawable/stop_icon.png
new file mode 100755
index 0000000..20df415
Binary files /dev/null and b/examples/0603/MyAndroidTutorial/app/src/main/res/drawable/stop_icon.png differ
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/res/drawable/take_picture_icon.png b/examples/0603/MyAndroidTutorial/app/src/main/res/drawable/take_picture_icon.png
new file mode 100644
index 0000000..08fb514
Binary files /dev/null and b/examples/0603/MyAndroidTutorial/app/src/main/res/drawable/take_picture_icon.png differ
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/res/layout/activity_about.xml b/examples/0603/MyAndroidTutorial/app/src/main/res/layout/activity_about.xml
new file mode 100644
index 0000000..211a9b6
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/app/src/main/res/layout/activity_about.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/res/layout/activity_color.xml b/examples/0603/MyAndroidTutorial/app/src/main/res/layout/activity_color.xml
new file mode 100644
index 0000000..d25bbc5
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/app/src/main/res/layout/activity_color.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/res/layout/activity_item.xml b/examples/0603/MyAndroidTutorial/app/src/main/res/layout/activity_item.xml
new file mode 100644
index 0000000..80dc337
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/app/src/main/res/layout/activity_item.xml
@@ -0,0 +1,149 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/res/layout/activity_main.xml b/examples/0603/MyAndroidTutorial/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..30cdf98
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/res/layout/activity_maps.xml b/examples/0603/MyAndroidTutorial/app/src/main/res/layout/activity_maps.xml
new file mode 100644
index 0000000..5de477b
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/app/src/main/res/layout/activity_maps.xml
@@ -0,0 +1,7 @@
+
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/res/layout/activity_picture.xml b/examples/0603/MyAndroidTutorial/app/src/main/res/layout/activity_picture.xml
new file mode 100644
index 0000000..b667420
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/app/src/main/res/layout/activity_picture.xml
@@ -0,0 +1,10 @@
+
+
\ No newline at end of file
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/res/layout/activity_play.xml b/examples/0603/MyAndroidTutorial/app/src/main/res/layout/activity_play.xml
new file mode 100644
index 0000000..52db308
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/app/src/main/res/layout/activity_play.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/res/layout/activity_record.xml b/examples/0603/MyAndroidTutorial/app/src/main/res/layout/activity_record.xml
new file mode 100644
index 0000000..63d9e36
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/app/src/main/res/layout/activity_record.xml
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/res/layout/item_app_widget.xml b/examples/0603/MyAndroidTutorial/app/src/main/res/layout/item_app_widget.xml
new file mode 100644
index 0000000..92bb45a
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/app/src/main/res/layout/item_app_widget.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/res/layout/single_item.xml b/examples/0603/MyAndroidTutorial/app/src/main/res/layout/single_item.xml
new file mode 100644
index 0000000..8acc60a
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/app/src/main/res/layout/single_item.xml
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/res/menu/menu_main.xml b/examples/0603/MyAndroidTutorial/app/src/main/res/menu/menu_main.xml
new file mode 100644
index 0000000..3ea061c
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/app/src/main/res/menu/menu_main.xml
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/res/transition/explode_transition.xml b/examples/0603/MyAndroidTutorial/app/src/main/res/transition/explode_transition.xml
new file mode 100644
index 0000000..d2320b1
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/app/src/main/res/transition/explode_transition.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/res/transition/fade_transition.xml b/examples/0603/MyAndroidTutorial/app/src/main/res/transition/fade_transition.xml
new file mode 100644
index 0000000..ea54111
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/app/src/main/res/transition/fade_transition.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/res/transition/slide_transition.xml b/examples/0603/MyAndroidTutorial/app/src/main/res/transition/slide_transition.xml
new file mode 100644
index 0000000..afd9869
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/app/src/main/res/transition/slide_transition.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/res/values-en/strings.xml b/examples/0603/MyAndroidTutorial/app/src/main/res/values-en/strings.xml
new file mode 100644
index 0000000..c532533
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/app/src/main/res/values-en/strings.xml
@@ -0,0 +1,12 @@
+
+
+
+ MyAndroidTutorial
+ Hello world!
+ Settings
+
+ Title
+ Enter title
+ Content
+ Enter content
+
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/res/values-v14/dimens.xml b/examples/0603/MyAndroidTutorial/app/src/main/res/values-v14/dimens.xml
new file mode 100644
index 0000000..4db8c59
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/app/src/main/res/values-v14/dimens.xml
@@ -0,0 +1,10 @@
+
+
+
+
+ 0dp
+
+
\ No newline at end of file
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/res/values-v21/styles.xml b/examples/0603/MyAndroidTutorial/app/src/main/res/values-v21/styles.xml
new file mode 100644
index 0000000..606e45f
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/app/src/main/res/values-v21/styles.xml
@@ -0,0 +1,12 @@
+
+
+
+
\ No newline at end of file
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/res/values-w820dp/dimens.xml b/examples/0603/MyAndroidTutorial/app/src/main/res/values-w820dp/dimens.xml
new file mode 100644
index 0000000..63fc816
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/app/src/main/res/values-w820dp/dimens.xml
@@ -0,0 +1,6 @@
+
+
+ 64dp
+
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/res/values/colors.xml b/examples/0603/MyAndroidTutorial/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..6b13c1d
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/app/src/main/res/values/colors.xml
@@ -0,0 +1,7 @@
+
+
+ #CCCCCC
+ #AAAAAA
+ #DD999999
+ #111111
+
\ No newline at end of file
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/res/values/dimens.xml b/examples/0603/MyAndroidTutorial/app/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..7fa5a6f
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/app/src/main/res/values/dimens.xml
@@ -0,0 +1,13 @@
+
+
+ 16dp
+ 16dp
+
+ 6dp
+ 24sp
+ 2dp
+
+ 8dp
+
+ 2sp
+
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/res/values/strings.xml b/examples/0603/MyAndroidTutorial/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..a59f440
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/app/src/main/res/values/strings.xml
@@ -0,0 +1,59 @@
+
+
+
+ MyAndroidTutorial
+ Hello world!
+ Settings
+ 標題
+ 輸入標題
+ 內容
+ 輸入內容
+ 這是Android Tutorial應用程式
+ AboutActivity
+ 版本:AndroidTutorial_0.2.4
+ ItemActivity
+ ColorActivity
+ 刪除
+ 確定要刪除 %1$d 個項目?
+ 預設的顏色
+ 新增記事的預設顏色
+
+ 預設提醒時間
+ 在指定的時間之前通知
+
+
+ - 五分鐘
+ - 十分鐘
+ - 二十分鐘
+ - 三十分鐘
+ - 六十分鐘
+
+
+
+ - 5
+ - 10
+ - 20
+ - 30
+ - 60
+
+
+ 語音備忘
+ 播放語音備忘
+ 播放
+ 重新錄製
+ Map
+
+ 記事儲存的位置
+ 更新或清除儲存的位置資訊?
+ 更新
+ 清除
+
+ 目前位置
+ 是否儲存目前位置?
+
+ 裝置沒有安裝Google Play服務
+ EXAMPLE
+ Configure
+ Add widget
+
+
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/res/values/styles.xml b/examples/0603/MyAndroidTutorial/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..766ab99
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/app/src/main/res/values/styles.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/res/xml/item_app_widget_info.xml b/examples/0603/MyAndroidTutorial/app/src/main/res/xml/item_app_widget_info.xml
new file mode 100644
index 0000000..043d27b
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/app/src/main/res/xml/item_app_widget_info.xml
@@ -0,0 +1,15 @@
+
+
+
\ No newline at end of file
diff --git a/examples/0603/MyAndroidTutorial/app/src/main/res/xml/mypreference.xml b/examples/0603/MyAndroidTutorial/app/src/main/res/xml/mypreference.xml
new file mode 100644
index 0000000..33e714c
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/app/src/main/res/xml/mypreference.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/0603/MyAndroidTutorial/app/src/release/res/values/google_maps_api.xml b/examples/0603/MyAndroidTutorial/app/src/release/res/values/google_maps_api.xml
new file mode 100644
index 0000000..c4e2431
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/app/src/release/res/values/google_maps_api.xml
@@ -0,0 +1,18 @@
+
+
+
+ YOUR_KEY_HERE
+
+
diff --git a/examples/0603/MyAndroidTutorial/build.gradle b/examples/0603/MyAndroidTutorial/build.gradle
new file mode 100644
index 0000000..6356aab
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/build.gradle
@@ -0,0 +1,19 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+ repositories {
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:1.0.0'
+
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+}
+
+allprojects {
+ repositories {
+ jcenter()
+ }
+}
diff --git a/examples/0603/MyAndroidTutorial/gradle.properties b/examples/0603/MyAndroidTutorial/gradle.properties
new file mode 100644
index 0000000..1d3591c
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/gradle.properties
@@ -0,0 +1,18 @@
+# Project-wide Gradle settings.
+
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+# Default value: -Xmx10248m -XX:MaxPermSize=256m
+# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
+
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
\ No newline at end of file
diff --git a/examples/0603/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.jar b/examples/0603/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
Binary files /dev/null and b/examples/0603/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/examples/0603/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.properties b/examples/0603/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..0c71e76
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
diff --git a/examples/0603/MyAndroidTutorial/gradlew b/examples/0603/MyAndroidTutorial/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/examples/0603/MyAndroidTutorial/gradlew.bat b/examples/0603/MyAndroidTutorial/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/examples/0603/MyAndroidTutorial/settings.gradle b/examples/0603/MyAndroidTutorial/settings.gradle
new file mode 100644
index 0000000..e7b4def
--- /dev/null
+++ b/examples/0603/MyAndroidTutorial/settings.gradle
@@ -0,0 +1 @@
+include ':app'
diff --git a/images/icons/alarm_icon.png b/images/icons/alarm_icon.png
new file mode 100755
index 0000000..c6cac88
Binary files /dev/null and b/images/icons/alarm_icon.png differ
diff --git a/images/icons/location_icon.png b/images/icons/location_icon.png
new file mode 100755
index 0000000..4c3c514
Binary files /dev/null and b/images/icons/location_icon.png differ
diff --git a/images/icons/pause_icon.png b/images/icons/pause_icon.png
new file mode 100755
index 0000000..a5aee6f
Binary files /dev/null and b/images/icons/pause_icon.png differ
diff --git a/images/icons/play_icon.png b/images/icons/play_icon.png
new file mode 100755
index 0000000..6a40cd5
Binary files /dev/null and b/images/icons/play_icon.png differ
diff --git a/images/icons/record_dark_icon.png b/images/icons/record_dark_icon.png
new file mode 100755
index 0000000..bcf83ca
Binary files /dev/null and b/images/icons/record_dark_icon.png differ
diff --git a/images/icons/record_red_icon.png b/images/icons/record_red_icon.png
new file mode 100755
index 0000000..2b44af0
Binary files /dev/null and b/images/icons/record_red_icon.png differ
diff --git a/images/icons/record_sound_icon.png b/images/icons/record_sound_icon.png
new file mode 100755
index 0000000..a1382ac
Binary files /dev/null and b/images/icons/record_sound_icon.png differ
diff --git a/images/icons/select_color_icon.png b/images/icons/select_color_icon.png
new file mode 100755
index 0000000..8567d5e
Binary files /dev/null and b/images/icons/select_color_icon.png differ
diff --git a/images/icons/selected_icon.png b/images/icons/selected_icon.png
new file mode 100755
index 0000000..b891571
Binary files /dev/null and b/images/icons/selected_icon.png differ
diff --git a/images/icons/stop_icon.png b/images/icons/stop_icon.png
new file mode 100755
index 0000000..20df415
Binary files /dev/null and b/images/icons/stop_icon.png differ
diff --git a/images/icons/take_picture_icon.png b/images/icons/take_picture_icon.png
new file mode 100755
index 0000000..08fb514
Binary files /dev/null and b/images/icons/take_picture_icon.png differ
diff --git a/images/launcher/mipmap-hdpi/ic_launcher.png b/images/launcher/mipmap-hdpi/ic_launcher.png
new file mode 100755
index 0000000..1a74b60
Binary files /dev/null and b/images/launcher/mipmap-hdpi/ic_launcher.png differ
diff --git a/images/launcher/mipmap-mdpi/ic_launcher.png b/images/launcher/mipmap-mdpi/ic_launcher.png
new file mode 100755
index 0000000..6d99fde
Binary files /dev/null and b/images/launcher/mipmap-mdpi/ic_launcher.png differ
diff --git a/images/launcher/mipmap-xhdpi/ic_launcher.png b/images/launcher/mipmap-xhdpi/ic_launcher.png
new file mode 100755
index 0000000..8b6e57a
Binary files /dev/null and b/images/launcher/mipmap-xhdpi/ic_launcher.png differ
diff --git a/images/launcher/mipmap-xxhdpi/ic_launcher.png b/images/launcher/mipmap-xxhdpi/ic_launcher.png
new file mode 100755
index 0000000..43a1744
Binary files /dev/null and b/images/launcher/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/images/launcher/mipmap-xxxhdpi/ic_launcher.png b/images/launcher/mipmap-xxxhdpi/ic_launcher.png
new file mode 100755
index 0000000..779edb4
Binary files /dev/null and b/images/launcher/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/images/migrate/AndroidTutorial5_migrate_01.png b/images/migrate/AndroidTutorial5_migrate_01.png
new file mode 100644
index 0000000..ee35916
Binary files /dev/null and b/images/migrate/AndroidTutorial5_migrate_01.png differ
diff --git a/images/migrate/AndroidTutorial5_migrate_02.png b/images/migrate/AndroidTutorial5_migrate_02.png
new file mode 100644
index 0000000..54d6130
Binary files /dev/null and b/images/migrate/AndroidTutorial5_migrate_02.png differ
diff --git a/images/migrate/AndroidTutorial5_migrate_03.png b/images/migrate/AndroidTutorial5_migrate_03.png
new file mode 100644
index 0000000..95b5222
Binary files /dev/null and b/images/migrate/AndroidTutorial5_migrate_03.png differ
diff --git a/images/migrate/AndroidTutorial5_migrate_04.png b/images/migrate/AndroidTutorial5_migrate_04.png
new file mode 100644
index 0000000..7e80141
Binary files /dev/null and b/images/migrate/AndroidTutorial5_migrate_04.png differ
diff --git a/images/migrate/AndroidTutorial5_migrate_05.png b/images/migrate/AndroidTutorial5_migrate_05.png
new file mode 100644
index 0000000..be3dea1
Binary files /dev/null and b/images/migrate/AndroidTutorial5_migrate_05.png differ
diff --git a/images/migrate/AndroidTutorial5_migrate_06.png b/images/migrate/AndroidTutorial5_migrate_06.png
new file mode 100644
index 0000000..b584fa9
Binary files /dev/null and b/images/migrate/AndroidTutorial5_migrate_06.png differ