發表文章

透過程式碼輸出 SharedPreferences 與 SQLite DB

更新:追加輸出 Realm 與 Logcat 的方式。

應用程式中常會使用 SharedPreferences 及 SQLite DB 來儲存資料,但想檢視裡頭資料時該怎麼做呢?

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

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

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

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

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

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

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


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

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

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

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

提出申訴後過了幾個小時,收到回覆了。
原來是我的App有"分享APK檔案給朋友"的功能…

整合 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 Studio 輸出 APK 時出現 [MissingTranslation] 的問題

最近在用 Android Studio 輸出 Signed APK 時遇到了以下錯誤:
Error: "xxx" is not translated in ... [MissingTranslation]

原因是 Lint 檢查到某些字串沒有被翻譯所導致。但有些字串就是不需、不想或懶得翻譯時該怎麼辦呢?

方法有以下幾種:
1.對不需翻譯的字串加上 translatable="false"
<string name="xxx" translatable="false">"XXX"</string> 2.在 strings.xml 的 resources 加上以下屬性
<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation" > 3.在 app/build.gradle 中加上以下設定
android { ... lintOptions { disable 'MissingTranslation' } ... } 或
android { ... lintOptions { checkReleaseBuilds false abortOnError false } ... }
參考資料:
http://blog.csdn.net/KjunChen/article/details/50043487

升級 SDK Tools & ADT 22.6 後 ProGuard 錯誤的問題

升級 SDK Tools & ADT 22.6 後,從 Eclipse 輸出 Signed APK 可能出現以下錯誤:
Error: Unable to access jarfile ..\lib\proguard.jar

看起來是路徑有問題找不到 proguard.jar,解決方法如下:
到 SDK 中修改 proguard.bat 檔內容,proguard.bat 檔的位置如下:
yourSDK\tools\proguard\bin\proguard.bat

將 proguard.bat 裡面的這行
java -jar "%PROGUARD_HOME%"\lib\proguard.jar %* 修改成 proguard.jar 的絕對路徑 (SDK 路徑請依您安裝而定)
java -jar C:\yourSDK\tools\proguard\lib\proguard.jar %* 改好後再嘗試輸出 Signed APK 應該就會正常了~

參考資料:
https://code.google.com/p/android/issues/detail?id=66733

升級 SDK Tools & ADT 22.2 後無法創建新專案的解法

圖片
#此問題已經在 22.2.1 版被修正,請直接用SDK Manager更新即可。

又來了~
前幾天有升級 SDK Tools & ADT 到 22.2 的開發者,應該會發現怎麼無法建立新專案了?
當建立新專案到最後一步時,會出現下面這個畫面:


Unsupported template dependency: Upgrade your Android Eclipse plugin

This template depends on the Android Support library which is either not installed or the template depends on a more recent version than the one you have installed.
Required version:
Installed version: 18

真是令人摸不著頭緒,不是才剛更新的嗎...
而且不管按 Install/Upgrade 或 Check Again 都沒效

查了一下,又有人包了。
https://code.google.com/p/android/issues/detail?id=60149#c55
不過他也提供了解決方案,只要用上面連結中#55樓提供的 activities.zip 壓縮檔,解開後置換掉 sdk/tools/templates/activities 目錄就可以了!

使用<uses-feature>的注意事項

<uses-feature>最早是在Android 1.6 SDK (API Level 4)中出現的,他的用途是用來宣告App會使用到哪些軟硬體功能(比如Camera、Bluetooth、OpenGL ES version...)。不過事實上系統本身並不會去檢查這些設定,但Google Play確會用這些設定去過濾要呈現哪些App給使用者。

比如說我宣告了下面這行,表示我會使用到Camera功能。這樣Google Play就不會將我的App顯示在沒有Camera的裝置上。
<uses-feature android:name="android.hardware.camera" /> 不過後來在Android 2.0 SDK (API Level 5)中,<uses-feature>多了一個屬性叫android:required。當某功能在App中是必要時需設定為true,若是非必要時則設成false。咦?...若是不需要的話,我直接省略<uses-feature>不是更省事嗎?

在看完落落長的開發者文件後才瞭解,嚴格來說,每個App都應該要清楚宣告哪些功能是必要或非必要。但因為種種原因,開發者可能忽略或未正確宣告。所以Google Play除了檢查<uses-feature>外,還會參考<uses-permission>的設定。當有設定<uses-permission>時,Google Play會假定相關的功能是必要的,並加入過濾。

舉例來說,我的App會使用到Camera,但不是必要的。為此我宣告了Camera的<uses-permission>,卻忽略了<uses-feature>。
<uses-permission android:name="android.permission.CAMERA" /> 此時Google Play發現了這個<uses-permission>,便會將Camera視為必要而進行過濾,沒有Camera的裝置就看不到我的App了,這樣跟我想要的結果不同。

該怎麼改善呢? 只要加上Camera的<uses-feature>,並把android:re…