2015年9月19日 星期六

APP 上架: 「電影即時通」看電影, 一點就通

身為電影的愛好者,  一直想寫個方便看電影的 APP,
只是事情繁多, 一延再延,
上個月終於空出時間來完成它,



首頁可以一目了然看到各種功能, 也刻意將電影排行榜移到首頁, 方便查找:


電影專欄的設計, 更容易掌握熱門電影的資訊:


簡化的電影訊息設計, 點擊圖集會有大張的電影海報, 點擊影片則會有預告片:


完整的電影新聞與影評:


各家電影訂票系統, 幫您準備好:


不可錯過的信用卡優惠訊息:



除此之外, 還有許多大大小小的功能,
這是電影愛好者做給愛好者的 APP,
希望您會喜歡 ~


附上其他美圖:






2015年6月21日 星期日

寫一本新手看得完的程式書

市售的書有個通病, 就是希望把書寫全了, 不要有所遺漏才好,
但, 即使勤奮的學⽣,學到後面的時候,往往前⾯就忘了。
不信的話,隨便抓⼗個工程師來問,有誰記得書上藍芽的⽤法?!

學了就忘,學⽽而從來不⽤,都是學習時間上的⼀種浪費,
本書的目的是希望讀者花最少的時間,
最少的⼒氣就能學到「如何開發 Android APP」。

所以⼀些冗⾔贅字我們就不寫在這本書裡了,例如:
Android 的歷史, Android 的市場, 多點觸控, 藍芽, Sensor...等.

我們假設這本書的讀者是「Android 的新手」,
你可能學過 Java 或你沒有學過 Java 都沒有關係,
本書從 Java 說起, 我們只要學會⾜夠可用的 Java 即可.

除了 Java 之外, 本書教你如何製作⼀個列表式的APP,
這類 APP 在許多地⽅都會看到, 例如報章類或者食譜類的 APP 等。
透過製作這個 APP, 新⼿可以了解 Android App 的製作過程, 也就算是⼊了門。

總之, 就讓我們開始吧!

這本書只有 100 頁, 無冗言贅字, 相信你一定讀得完.連結: http://jasonandroid.com/




2015年4月14日 星期二

第一堂, 進入 Android 的世界



Jason 的 Android 快樂應用程式學習班,

在第一堂課裡, 會先帶領大家進入 Android 的世界,
對於開發者而言, 要學 Android 還是 iOS, 常常有激烈的辯論.
其實兩個各有優劣, 我會帶領大家比較異同之處,
同時說明重要的數據是什麼,

接著, 我們會安裝開發環境, 並開發第一個程式.
這部分會採取現場操作教學.
只要上完這堂, 就對開發重點有些瞭解囉.



2015年4月7日 星期二

快速打造後端應用, 使用 Android studio + App Engine + EndPoints

如果我們開發的 App 沒有使用到 Server 服務器, 就稱為本機端應用,
如果有用到 Server 來提供資料, 則稱之後端應用.

大部份的 App 都需要透過 Server (後端) 來提供資料,
例如美食App, 小說 App, 新聞 App, 股市 App 等等.
這類的 App 不可能一開始就把所有資料塞在 App 裡,
因為一來資料是即時的, 二來資料量大的話,  Apk 打包起來也會很大.

許多人學了 Android,  但沒學過網頁程式,
很難獨力完成這類的 App, 開發能力因此受限.

Google 提供了一套 Android Studio + App Engine + EndPoints 的解法.
在打造後端應用上非常快速, 我來大略提一下.

ㄧ. 建立 app module 和 endpoints module
1. 建立 Android Project (會產生  App module)
2. 增加新的 Module => App Engine Java Endpoints Module

二. 在手機端應用
1. 使用 AsyncTask 呼叫 Endpoints Module (Api)

實作請參考這一篇
https://github.com/GoogleCloudPlatform/gradle-appengine-templates/tree/master/HelloEndpoints


 P.S
如果碰到找不到 endpoints api (MyApi) 的問題,
只要執行 build and run 就可以產生 api 檔了! ( 網路上許多開發者也碰到此問題 )


這是因為在這過程中,  會為我們執行以上幾個步驟去產生所需的 Source 檔.


附帶一提,
我將於 2015 / 4 / 20 ~ 2015 / 5 / 15 在台中開課,
用意是教會更多人 Android 程式,  限 15 個名額.
詳情 http://jasonandroid.com/






2015年4月3日 星期五

來台中學 Android,快樂學習班

嗨 ,

各位朋友,我最近有個計劃,
台中開班教 Android 程式 ,課程融入幾年來開發的經驗,希望大家有所收獲。

網址是 http://jasonandroid.com/




課程綱要:

4月20日 禮拜一
第一堂:入門容易出師難 --- 進入 Android 的世界
1. Android 的歷史與市場介紹
2. 舉國內外的開發者故事為例,說明學會 Android 應用開發,可以完成哪些產品
3. 介紹 Android 的開發環境 --- AndroidStudio
4. 在電腦上跑 Andorid 模擬器
5. 第一個 Android 手機程式 --- “Hello World”


4月22日 禮拜三
第二堂:想飛要先會走路 --- 學習基本 JAVA 語法
1. Java 型態:String, int, Array
2. Java 判斷:if else, for loop, while loop
3. Java 物件繼承:Inheritance
4. 其他資料格式:JSON, XML


4月24日 禮拜五
第三堂:盤點手邊工具箱 --- 學習 Android 開發工具
1. Android 專案內容介紹
2. 介紹 SDK
3. 使用圖形化編輯器
4. 學習如何偵錯 Debug (DDMS)


4月27日 禮拜一
第四堂:小試身手 --- 計算機 APP 和 網站瀏覽 APP
1. APP 畫面佈局
2. Button 按鈕
3. 結合程式碼與元件
4. 網站瀏覽 APP


4月29日 禮拜三
第五堂:磨刀不誤砍柴工 --- Youtube 播放 APP 和 食譜 APP
1. Activity 的生命週期
2. Intent 的用法
3. 使用 ListView
4. Youtube 播放APP
5. 食譜 APP


5月1日 禮拜五
第六堂:默默的偉大勞工 --- 學習使用 Service
1. 使用 Asynctask
2. 使用 Service
3. 自己做鬧鐘 APP


5月4日 禮拜一
第七堂:資料保管如何做 --- 學會 Android 的手機資料存儲
1. 使用 SharePrefreance 保存資料
2. 使用 SQLite 保存資料
3. 記事本 APP


5月6日 禮拜三
第八堂:寶石要磨才會亮 --- 介紹 Android 5.0 Lollipop
1. 多螢幕的設計精神
2. Android Auto
3. Android Wear
4. 充滿設計感的 Materail Design


5月8日 禮拜一
第九堂:認識好幫手 --- Parse 以及 Google APIs
1. 線上資料處理專家 Parse
2. 免費的地圖 Google Map
3. 免費的使用情形數據分析 Google Analytics4. 個人的雲端資料庫 Google Cloud
* 這堂課之後,學員要構思自己想開發的 APP 內容


5月11日 禮拜一
第十堂:開發之前先拜神 --- Android Developer 官網大神
1. Android Developer 官網導讀
2. Sample Code 的學習


5月13日 禮拜三
第十一堂:上架的最後一哩路 --- 學習編譯 Compile 與上架
1. 學習 Gradle 編譯
2. 學習上架到 Google Play
3. 認識廣告財主 Google AdMob (並使用)



5月15日 禮拜五
第十二堂:光榮的時刻 --- 學員作品展示
1. 學員作品展示


P.S 最後一堂課,如果有多的時間,我們分析APP的各種獲利模式:廣告模式,訂閱模式,免費模式,遊戲模式等,是講者幾年來開發的經驗學習,光這課就物超所值囉!


講師介紹:
柯力中 Jason Ko,2009 成大物理系畢業


經歷介紹:
2011 年之初創投第四屆入選隊伍。
2011 年至 2015 年,與朋友開發 APP 超過 20 款,下載超過 300 萬人次,多項產品曾列 Google Play 分類排行第一,最高名列 Google Play 不分類排行榜第二。


2013年10月23日 星期三

淺談 Security

Android 的安全性依賴於本身系統的設計,  主要的設計如下

* Sandbox 的設計, 讓App的資料與程式碼不為其他 App 所用
* Android 本身的架構設計就包含了 cryptography(加密), permissions, IPC (inter-process communication 進程間通訊).
* 還有些降低 memory 出錯的設計, 如: ASLR, NX, ProPolice....等
* 加密的檔案系統, 即使裝置遺失或被偷, 依然可以保護 data 免於被取出
* 使用者的 permission 設計, 讓使用者可以自行限制系統資源與使用者資料的讀取.
* 利用 App 設定的 permission 來控制 application 在每個 app 的基本資料.

藉由熟悉 Android 的 security 設計, 可以讓我們更容易地降低使用者的資安問題.

資料儲存 Storing Data

Android 的資料儲存分為三種:

使用內部儲存 Using internal storage

在預設的情況下, internal storage 的資料只能夠被自身的 App 讀取, 在大部分的情況下已然夠用.

要盡量避免使用 MODE_WORLD_WRITEABLE 或 MODE_WORLD_READABLE 來做 IPC 檔案, 因為這麼做的話, 所有的 App 都能讀到自身 App 的任何(格式)資料. 正確的做法是利用 content provider 來提供資料給某些你認同的 App.

要更謹慎處理的資料, 可以透過 KeyStore 來替該資料加密. 這個 Key 的密碼不直接存在裝置上, 如此便降低了遺失時的風險. 需要提防的是, 如果竊取者有 root 權限, 在輸入密碼的時候還是會被擷取到. (此舉應該是在認證還未過時, 更降低被破解的可能)

使用外部儲存 Using external storage

在 external storage (ex. SD卡) 上的資料, 通常可以被其他程式寫入並讀取. 因為外部儲存裝置可以被使用者取下, 所以最好不要存入任何重要資料.

因為 external storage 的資料可以被寫入, 我們使用前應該做 input validation 的測試. 最好不要將可執行的檔案放在 external storage, 而是應該透過伺服器作動態讀取. 如果真的要使用, 也應該加密並驗證.

使用 content providers

Content provider 是 Android 用來與其他 App 交流資料的機制. 如果設定permission 為 android:exported=false 則資料不會被其他 App 讀取到. 反之, 設 true 才能提供資料給其他 App.

透過  permission 可以控制其他 App 讀取或寫入的權限, 應該在一開始就設好, 畢竟之後修改的話可能就會影響到已使用的用戶.

如果 content provider 只有在自己開發的 Apps 用到, 可以設 android:protectionLevel="signature". 這樣 user 就不必認證, 可以有較佳的使用者體驗.

更細節一些, 可以提供 android:grantUriPermissions 的 permission, 這樣就可以進一步限制 permission 的路徑.

一但使用了 content provider, 最好也使用 query(), update(), delete() 這些帶有參數的方法, 可以避免一些不必要的 SQL 輸入錯誤.

要注意的是只提供 write 的 permission 並不表示竊資者無法讀取資料, 因為他們依然可以修改 WHERE 的參數來取得資料. 因此, 有了 write 的權限, 對竊取者來說也有了 read 的權限.

用戶的  Permissions

因為 Android 不同的 Apps 之間權限是相隔開的, 必須透過 permission 才能取得彼此的資源. 包括相機, 網路...等等.

要求 Permissions

原則上如果能不需要這個 permission, 那就不要去要求 permission.
Permission 要求的越少, 越不容易有資料外洩的問題.

創造 Permission

也可以要求 Android 系統預設之外的 permission,
有分 "signature" protection level 跟 "dangerous" protection level.
"dangerous" protection level 不為使用者接受的可能性較高些.

網路的使用 Using Networking

網路傳輸相對上比較危險一些, 可能會泄漏使用者的個資, 因此要小心處理.

網路 IP 的使用

盡量使用 HTTPS 的伺服器而非 HTTP, 因為行動裝置連上的網路通常沒有安全防護, 例如 wifi 熱點.

如果是使用 Socket 通訊, 可以使用 SSLSocket 這個 class. 建議整個通訊的內容都要特別加密.

在 IPC 的使用上, 必須使用 Android IPC mechanism; 不要使用 localhost, 因為這個界面可能會被其他任何的 App 所觀察到. (INADDR_ANY 也不能用, 因為自身的 App 會收到來自任何地方的 request)

此外, 也不要相信其它 Http 或不安全協定下載的檔案.

電話網路的使用 Using Telephony Networking

SMS (簡訊) 是設計給用戶間通訊用的, 不適合檔案傳輸. 建議使用 Google Cloud Messaging (GCM) 以及 IP 網路來傳遞檔案.

SMS 沒有經過特別的加密, 任何 SMS 的接收器都可能會收到惡意的 SMS. 因此不要信任這些 SMS. 當手機收到 SMS 時, 會發送 braoadcast intents, 因此任何有 READ_SMS permission 的 App 都可以接收到.

使用輸入驗證 Performing Input Validation

不正確的輸入驗證, 可能會導致 App 無法順利執行.  建議使用Android 系統提供的驗證.

如果是開發者使用自己的程式碼, 可能產生如 buffer overflow, use after free, 和 off-by-one errors 等問題. Android 有提供 ASLR(Address Space Layout Randomization) 以及 DEP(Data Execution Prevention) 來協助處理. (但最根本的 pointers 跟 buffer 還是要自己處理.)

動態上, JavaScript 跟 SQL 都有可能被 script injection (腳本攻擊, 因為 JavaScript 跟 SQL 都是 Script Language)

要減小 SQL injection 的方式是使用 content providers 提供的接口, 以及設置 permission.

雖然 blacklisting 也是一種方法, 但是不建議. ( blacklisting 只能預想切取者如何攻擊)

使用者的個資處理 Handling User Data

原則上, 越少索取 User data 就會越安全一些. 如果你取得了 User 資料可以不儲存, 也可以不傳遞, 那就不要. 如果把 email 當作是 hash 的 (primary) key, 就能減少所有資料被竊的可能.

如果開發者的應用儲存的使用者的名稱與密碼, 記得要對個資的使用作聲明. 避免有法律上的問題.

另外, 要減少暴露個資給第三方 App 的機會, 最好的方式就是減少個資讀取.

如果個資能不上傳到網站, 則盡量別上傳,  在本機端處理就好.

謹慎處理 IPC 的資料, 確認個資不會外洩.

如果需要長串的辨識碼(GUID), 不要使用手機號碼 或 IMEI .

Log 的寫入也要小心, 因為其他 App 也看得到 Log 的資料.

使用 WebView

WebView 的資料是由 HTML 與 JavaScript 所構成, 不當使用就會有 cross-site-scripting (JavaScript injection) 的問題.

如果, 你的應用沒有使用到 JavaScript, 則不要設  setJavaScriptEnabled(). (預設是沒有開啟)

使用 addJavaScriptInterface() 也是一樣必須小心, 只連上值得信任的網站是比較安全的. 最好是只有當 App 的 APK 本身有使用到 JavaScript 才開啓這項.

另外, 使用 clearCache() 可以刪除本機端的 Cache; 伺服器端如果 header 有 no-cache 則可避免資料存在手機端.

憑證處理 Handling Credentials

要避免資料外洩, 就要減少憑證要求, 也不要將個資存於手機, 尤其是賬號密碼.

比較好的方式是,  使用者透過賬號密碼取得 token; token 的生存時間短, 減少被竊的危險.

如果開發者的服務 (Service) 可以被很多 Apps 使用, 則使用 AccountManager 這個 class, 並且不用將密碼存於裝置上是比較好的. 此外, 也要注意 AccountManager 取回的 Account 別傳給錯誤的 App.

如果某個憑證(Credential) 只有開發者的 Apps 能用, 則可使用  checkSignature() 來達成 App 的認證. 相對的, 如果只有一個 App 會使用, 則可用 KeyStore 來儲存.

加密使用 Using Cryptography

網路的使用最好使用 HttpsURLConnection 或  SSLSoket.

如果要自行加密, 則有 Cipher 這個  class. 也有 SecureRandom, KeyGenerator 來產生加密代碼.

如果某個 Key 要重復用, 則可用 KeyStore 來加密儲存.

使用 IPC  Using Interprocess Communication

Android 的 IPC 方式有 Intent, Binder 或 Messenger, 加上Service, BroadCastReceiver.
如果不需要被其他 App 使用, 則 android:exported 設為 "false".
如果只給開發者的 Apps 使用, 則 android:protectionLevel 設為 "signature".

Intent 使用,  Using intent

Intent 有分 explicit 跟 implicit,
explicit intent 會直接呼叫開發者指定的 class,
implicit intent 會透過 intent filter 以及 permission 查看有哪些 class 可接收這個 intent.

所以傳遞重要資料時, 更要特別小心 permission 的設置.

Service 使用 Using Services

Service 預設不能為其他 App 所用, 但如果透過 intent filter 就可以截取 implicit intent.

使用 Binder 跟 Messenger Interfaces, Using binder and messenger interfaces

Binder 跟 Messenger 並不需要另設 permission, 它們的 permission 會延伸至 Service 或 Activity.

使用 Broadcast Receiver, Using broadcast receivers

BroadcastReceiver 預設可以接受任何的 intent, 但可以透過 permission 來限制只有特定的 intent 可以使用.

動態讀取程式碼, Dynamically Loading Code

不建議, 因為非常容易就會發生 code injection 的問題.

模擬器的安全性, Security in a Virtual Machine

模擬器有兩點需要注意:
* 模擬器的 Apps 之間沒有 sandboxes 隔開
* 使用時注意資料下載的來源, 避免惡意網路下載竊取資料.

Native Code 的安全性, Security in Native Code

不建議使用 Linux 原生語言, 可能會產生其他的問題. 如果真使用時, 也要瞭解 Linux 本身的安全性.

Android 的 Apps 之間有 sandboxes, 即使使用原生語言也是一樣. 可以想成是每個 App 自己有不同的 UID.



參考來源: http://developer.android.com/training/articles/security-tips.html






2013年10月21日 星期一

淺談 Saving Files

Android 使用檔案儲存的方式, 就像將檔案存在硬碟是一樣的, 主要會透過一個名為 File 的 API 來運作.

File 這個 API 適合用來寫入或讀取大量的資料而不間斷, 因此也常跟網路下載一起使用, 尤其是圖片.

選擇 Internal 或 External

儲存的位置可以分為 Internal 跟 External,
Internal 指的是內存, External 指的是 SD 卡.
如果檔案很大, 最好是存在 SD 卡上.
(通常預設 APP的 apk 檔是裝在 internal 裡, 如果檔案很大, 也可以設定裝在 SD 卡上)

下表是 Internal 跟 External 的比較



取得 External 的 Permission

要將檔案存至 SD 卡, 需要在 AndroidManifest.xml 取得 permission



將檔案存在 Internal

內部儲存的位置還分為兩個, 一個是 getFilesDir(), 一個是 getCacheDir().


Cache 是緩存(或稱暫存), 如果不想要 User 在短時間內不斷地 request 伺服器資料, 就可以先存在 Cache 裡. 但存在 Cache 裡的風險是, 一旦系統的資源不夠, 很可能就會把 Cache 理的資料清除掉, 所以使用上要小心.

如果要存在 internal 裡, 可以透過
或者 (使用 openFileOutput(), FileOutputStream )

如果要使用 Cache, 則透過 createTempFile()

將檔案存在 External (SD卡)

可以透過 getExternalStorageState() 來知道是否裝置是否可存(例如, 是否有 SD 卡)

External 儲存可分為  public 跟 private,
public 可以被使用者的其他 App 查到, private 預設則是查不到.
兩個各有各的用法.


如果是 public file, 則取得儲存路徑要透過 getExternalStoragePublicDirectory(),

如果是 private file, 則取得儲存路徑要透過 getExternalFilesDir(),

其中的 Environment.DIRECTORY_PICTURES 是副檔名, 指定存放的位置, 好讓其他系統資源找到.

刪除檔案

刪除檔案可以透過
或者

當 App 刪除時, 會刪除所有 internal 以及 getExternalFilesDir() 的資料.
但 getChcheDir() 的並不會自動刪除 (可考慮手動刪除, 或讓系統自動刪除)

參考來源: http://developer.android.com/training/basics/data-storage/files.html