2016年11月11日 星期五

透過程式碼輸出 SharedPreferences 與 SQLite DB

應用程式中常會使用 SharedPreferences 及 SQLite DB 來儲存設定或資料,但開發時想驗證裡面資料是否正確該怎麼做呢?

首先,SharedPreferences 以及 SQLite DB 都是以檔案方式儲存於 Internal Storage,路徑分別如下:

SharedPreferences:
如果是使用自訂設置(context.getSharedPreferences)
/data/data/YOUR_PACKAGE_NAME/shared_prefs/YOUR_PREFS_NAME.xml
如果是使用預設設置(PreferenceManager.getDefaultSharedPreferences)
/data/data/YOUR_PACKAGE_NAME/shared_prefs/YOUR_PACKAGE_NAME_preferences.xml

SQLite DB
/data/data/YOUR_PACKAGE_NAME/databases/YOUR_DB_NAME

但基本上 Internal Storage 是受保護的,想直接觀察會有點麻煩。
因此這邊提供了幾個函式幫助您把 SharedPreferences 及 SQLite DB 輸出到 External Storage。
輸出的檔案會在 External Storage 的 /Android/data/YOUR_PACKAGE_NAME/files 底下,方便您用其他的工具檢視。

此外,別忘了添加權限。
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

2016年8月9日 星期二

App在Google Play被停權與恢復的經驗分享


最近心情真像是洗了三溫暖~
前幾天把已經很久沒維護的EZ App安裝器稍微調整了UI,修了些Bug,提交更新。
幾個小時過去發現Google Play還沒反應,感覺有點怪...可能是系統忙碌吧。當下也沒想太多就跑去睡了。
隔天一早打開Email,登愣!App被停權了!!!
趕緊登入開發者控制台,又看到熟悉的景象...


為什麼說"又"呢?出來混總是要還的,被停權也不是第一次了。
多年前剛開始在Google Play(那時還叫Android Market)上架時,學別人在商店描述裡加了一堆Keyword,其實有沒有用也不知道。然後某次開發人員計劃政策調整後,這種行為被視為違規,於是一下子被停權兩隻App。
畢竟是自己沒注意到政策調整,而且罪證確鑿,只好摸摸鼻子認了。不過明明是很簡單就能修正的問題,Google總是完全不給機會就直接停權,手段實在狠毒!這也是讓開發人員最難以接受的地方。

順帶一題,Google Play的違規處分大概分為以下幾種:
  1. 拒絕:更新版本遭拒,但之前所發佈的版本仍會保留在Google Play商店中。
  2. 下架:應用程式會從Google Play下架。必須提交符合規範的更新版本,才能讓應用程式重新上架。
  3. 停權:應用程式會從Google Play下架。必須更改package name,才能讓應用程式重新上架。這意味著將失去原本累積的下載數、統計資料和評分,一切重頭來過。
  4. 終止開發者帳號:所有應用皆會下架,無法再上架新應用。"相關帳戶"也會一併處分,不允許再註冊新的開發者帳號。
我三次遇到的都是停權,但這次的原因是為什麼呢?
根據信裡的說明是違反了開發人員發佈協議的"其他商店"條款。
什麼是"其他商店"條款?

4.5 其他商店。凡是「產品」具有任何推廣其他商店之用途,藉此引導使用者透過這類替代性管道發佈 Android 軟體應用程式或遊戲,則一概禁止在「商店」中發佈或提供。

奇怪?我的App裡面沒有推廣其他應用程式商店啊?
信中有申訴的管道,寫信去問明白吧。網頁說可以用中文英文日文及韓文提出申訴,就直接寫中文吧。一來比較好溝通,同時看看都是說中文的會不會比較寬大為懷XDD~

提出申訴後過了幾個小時,收到回覆了。
原來是我的App有"分享APK檔案給朋友"的功能。因此被視為發佈應用程式的"替代性管道",所以維持原判,不給恢復。

果然規則都Google說了算。
但內心覺得這條款有模糊的空間,應該還有爭取的機會,於是再次回信給他們。

這次我提出"分享APK檔案給朋友"與"商店"的概念應有一定程度的差異。 且"這類替代性管道"的範圍太過含糊? 在對條文有歧義的狀況下未給予修正機會而直接停權,是否又過於強硬。
同時也表明修改意願,讓App更符合政策規定。懇請將處分層級調整為輕一點的拒絕或下架,而不是直接停權。

隔天,收到回信。
這次帶來了好消息,說再次審查後已核准我的申訴,並有條件地將應用程式解除停權。
只要在接下來的 7 天內,提交符合政策的應用程式更新,App就能重新上架。
回到開發者控制台,果然狀態從停權變成了下架。


應用程式資訊也恢復可以編輯的狀態,當然也能重新上傳Apk了。
立刻把App裡跟分享有關的功能拿掉,商店描述與圖檔素材也一併修改。
重新上傳修正版本,過了幾個小時,耶!我的App回來了!

經過一番折騰,總算有了好結果。這次運氣還算不錯,也感謝Google Play審核小組。
不過還是建議Google不要一下就把開發者打得無法翻身,這不是維繫客戶關係的好方法。
最後也建議所有開發者熟讀政策條款,並時時注意其改變。同時應用描述盡量精簡扼要,以免多說多錯。


參考資料:
開發人員計劃政策
開發人員發佈協議
瞭解應用程式遭拒、下架或停權
瞭解終止 Google Play 開發人員帳戶
申訴頁面

2016年3月23日 星期三

整合 Android In-app Billing 的注意事項

提醒,您必須擁有 Google Play 開發者帳戶以及 Google Payments 商家帳戶。

整合流程:
1. 將 App 加上以下權限。(程式內其他 Billing 相關的部分可暫時先不實作)
<uses-permission android:name="com.android.vending.BILLING" />
2. 將 Apk Sign 好,上傳到 Google Play 的 Alpha 測試階段。(需要一段時間生效)
3. 開始在 Developer Console 中建立應用程式內商品,並記得啟用。
4. 開發者不能購買自己的程式內商品,所以請準備另一個 Google 帳戶作為測試用。
5. 將測試帳號加入 Alpha 測試群組。
6. 將測試帳號加入授權測試帳戶(Developer Console -> 設定 -> 帳戶詳細資料 -> 測試用 Gmail 帳戶),這樣測試交易才不被真的扣款。
7. 參考範例開始實作 In-app Billing 的程式碼。
8. 若有使用 ProGuard 也請記得加上
-keep class com.android.vending.billing.**
9. 將實作好的 Apk 傳到實機測試(不能使用模擬器)。請務必確認實機上已有測試帳號,且 Version Code & 簽章跟之前上傳到 Google Play 上的相同。

注意事項:
1. 測試交易會在 14 天後自動取消。所以若要重複測試的話,請至 Google Payments 商家帳戶取消交易。(更新:從2016/6/20開始,測試交易將不再出現於商家帳戶,要重複測試的話,只能透過consume的方式來消耗掉已購買的項目。)
2. 若您沒有自己的Server處理交易紀錄,而是靠 Google Play Client 來記錄的話。因為他有 Local Caching 的機制,有時不會立即反映交易狀態的改變。比如說您從 Google Payments 商家帳戶取消了交易,但 App 透過 In-app Billing API 去查詢卻還是"已購買"的狀態。此時可以試著重啟裝置讓 Google Play Client 去同步交易狀態。

參考資料:
http://developer.android.com/intl/zh-tw/google/play/billing/index.html
http://developer.android.com/intl/zh-tw/training/in-app-billing/index.html
http://stackoverflow.com/questions/38130035/cancelling-orders-on-google-play-iab-test-purchases-after-june-20-2016