2014年7月5日

如何發佈 App 到 Google Play - 建造出 APK 檔案

前言

當完成一個 App 時,想分享給大家使用時,或許可以透過幾種方式分享給大家

  • 將 Apk 檔案放到網站上讓任何人下載到手機上安裝或將檔案傳送給朋友
  • 將 App(Apk 檔案) 發佈到 Google Play 商店

但相對安全也是比較有系統性的當然是放到 Google Play 商店上,而且還有許多優點:

  • 發佈時
    • 可以有不同階段性的測試版本 Alpha / Beta / Release
    • 協助翻譯
    • 設定可下載的國家 / 電信商 / 手機
    • 給予不同國家的使用者有相對應語系的簡介或圖片
    • 檢驗 Apk 是否符合預期,例如 versionCode 是否有比前一個版本大,簽署的 keystore 是否有符合規定
    • 是否要營利,付費與否,程式內部購買,廣告
  • 統計
    • 透過管理介面看到各項數據統計,安裝人數、安裝使用者來源、安裝使用者 Android 版本…等等
    • 財報
    • 當機或 ANR 的報告
    • 使用者的評論、感想、建議,也有不錯的回覆系統,跟使用者搭上橋梁

以上種種優點不只可以讓你輕易的管理你的 App,也能夠讓你的 App 得到最好的建議與回饋。那既然要放到 Google Play 上,當然也就要好好的遵守 Google Play 所訂的遊戲規定。今天來談談幾個比較關鍵的規定!

Build 出你的 APK 然後發佈到 Google Play

在開發的過程中要生成一個 App 是非常容易的。

在 Android Studio 中點 Run->Run ‘android’ 就會自動產生一個 Apk 檔案並安裝進手機中,也可以在目前工作目錄下{$ProjectFolder}/android/build/outputs/apk/{$ProjectName}.apk 找到所產生出來的 apk 檔案

PS. 由 Eclipse build 出來的 apk 則在{$ProjectFolder}/bin/{$ProjectName}.apk

接著馬上把它發佈到 Google Play Developer Console 的時候就會發生錯誤,也表示要上傳到 Google Play 商店並不那麼的容易需要動一些手腳,來看看發生了哪些錯誤

  • 要在 AndroidManifest.xml 中設定 android:debuggable 設成 false
  • 要用自己的憑證來簽署這個 apk
  • 第三個錯誤是因為 Google Play 上面已經有個同樣 package name 的 App

Fail to publish Apk file

解決問題

問題1

從錯誤提示中給的連結可以看到可以直接在 AndroidManifest.xml 中設定

android:debuggable="false"

讓 Android 系統無法針對你的 App 偵錯,達成停用偵錯功能,但新增這行以後你會發現 Lint(*1) 會顯示錯誤 (ID : AndroidLintHardcodedDebugMode(*2))

Avoid hardcoding the debug mode; leaving it out allows debug and release builds to automatically assign one

從錯誤提示來看,就是不要 hardcode 而是在決定要 build 成哪種 apk 的時候系統就會自動切換設定,要切換的話只要在 Android Studio 畫面的左下方有個 Build Variants 的 tab 點開來後可以選擇要生成 release / debug 版本的 apk 了
Android Sudio - Build Variants

問題2

主要是因為我們在測試開發時期的 keystore 若沒有去變動的話其實都是用 debug.keystore (~/.andriod/debug.keystore),當然也可以手動去更改要簽署的 keystore 為何(看個人需求,有些 App 需要系統的權限,就要簽署系統的 keystore),從

File->Project Structure 點開後,選擇你的 module 再選右邊的 Signing tab 就可以去更改不同的 keystore
Debug Signing

而這個錯誤就是要要求開發者要簽署自己的憑證,那憑證怎麼來呢?直接使用 keytool 指令來產生,在執行時,keysize 一定要用 2048 bit(太少 bit 已經不安全),若要上 Google Play 其憑證的有效日期一定要晚於2033/10/22,不然一定會發佈失敗也就是建議 validity 至少要填 10000

keytool -genkey -v -keystore release-mine.keystore
-alias alias_name -keyalg RSA -keysize 2048 -validity 10000

KeyTool 更多的資訊

產生出來的 keystore 就是你自己的憑證了!只要 Project Structure 選擇你的 module 再點選 release(如下圖,沒有的話可以自己新增),再將 Key Alias / Key Password / Key path / Store Password 填到對應的欄位,圖例為35around.keystore
Release Signing

或者是在 build.gradle 裡面寫,也可以設定不同的版本使用不同的 keystore

android {
    signingConfigs {
        release {
            storeFile file('yourKeyStoreFilePath')
            keyAlias 'yourKeyAlias'
            keyPassword 'yourKeyPassword'
            storePassword 'yourStorePassword'
        }
        debug {
            storeFile file('yourDebugKeyStoreFilePath')
            ...
        }
    }
}

問題3

將 package name 改成沒有人用過得就可以了!

最後

以上問題都解決以後,在 Android Studio IDE 中點 Build->Generate Signed APK… 按照著步驟走就會看到要選 keystore 的畫面,填完選下一步
Generate Signed APK Wizard - KeyStore
接著是選擇要不要跑 ProGuard 和設定輸出的 APK 檔案,最後點 Finish
Generate Signed APK Wizard -
再等個一下 APK 檔案就產生了!也就可以把檔案發佈到 Google Play 上了!

Eclipse呢?

簡單的步驟如下:
1.在專案點右鍵 Andriod Tools->Export Unsigned Application Package 選擇 APK 檔案路徑
2.簽署你的 APK

jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore {$my-release-key.keystore} {$my_application.apk} alias_name

3.壓縮並校準你的 APK

zipalign -v 4 {$my_unaligned_application.apk} {$my_protect_application.apk}

接著就可以上傳你的 APK 了!
詳細的可以參考 簽署你的APK

PS.
1. 要在 Android Studio 跑 Lint 的測試,點選 Analyze->Inspect Code->OK 後就會跑出一大串分析結果其中一個就是 Anrodid Lint
2. ID 為 AndroidLintHardcodedDebugMode 的描述

Checks for hardcoded values of android:debuggable in the manifest It’s best to leave out the android:debuggable attribute from the manifest. If you do, then the tools will automatically insert android:debuggable=true when building an APK to debug on an emulator or device. And when you perform a release build, such as Exporting APK, it will automatically set it to false. If on the other hand you specify a specific value in the manifest file, then the tools will always use it. This can lead to accidentally publishing your app with debug information.

9 則留言:

  1. 您好:
    我再上船時發生錯誤,"com.example"受到限制
    後來我將package name中的com.example都去除
    結果變成另一個錯誤,APK套件名稱標準為"com.example.myapp"....
    請問應該如何修正呢?
    謝謝

    回覆刪除
    回覆
    1. package name 的命名, google 本身是有一些限制的, 例如你遇到的 com.example 開頭的 package name 是不合法的, 另外你把 com.example 都刪除掉只剩一下組字也是不合法的

      你只要把 com.example 開頭的字換成其他的 例如 com.miracolab.xxx(至少要兩組字以上組成) 這樣就不會有問題了~ 當然最基本的就是不要跟其他人重複, 在上傳 apk 時, google 也是會幫忙檢查

      先試試看~ 如果有問題再回我

      刪除
  2. 上傳失敗

    您上傳的 APK 所簽署的憑證與您先前的 APK 不同,您必須使用相同的憑證。您現有的 APK 簽署時使用的憑證指紋是:

    [ SHA1: xx:xx:xx:......]

    ,而您上傳的 APK 簽署時所用的憑證指紋則是:
    [SHA1:zz:zz:zz:.......]

    請問我該在哪裏修改 [SHA1....] 碼,使之為相同的碼 ? [我使用的是 : eclipse] 謝謝 !!!

    回覆刪除
    回覆
    1. 你要去找出當初你第一次 sign apk 的 keystore , 以後上傳 apk 都必須是一樣的 keystore 所簽署的, 以確保這個 apk 是出自於你本人

      文中問題2的部份, 有一段是要經由 Keytool 來產生 keystore 就是這個

      刪除
    2. 謝謝您的回覆,但是,第一次的sign apk 的 keystore 已被我弟弟給刪除了,請問我現在有任何補救的辦法嗎? 因為被google play 拒絕發布了.

      刪除
    3. 重新定義你的 package name

      再 gen 一把 keystore 簽署後再重新上架吧 看來這是唯一解了

      刪除
  3. 我要上傳我的unity apk
    以一般名稱 "all.apk"
    跟範例一樣的名稱 "com.example.myapp.apk"
    改了其他的名稱"com.wmlab.all.apk"
    都會不行 一直得到
    "上傳失敗
    APK 套件名稱標準格式如下:「com.example.myapp」,可使用字母 (a-z)、數字和底線 (_),開頭必須為小寫字元,且長度不可超過 150 個字元。"
    我unity匯出的apk裡,有使用eclipse的藍芽插件,會因為這樣不給我過嗎

    請問我如何解決這個問題?

    回覆刪除
  4. 已經有apk, 可以幫我發佈到Google play 嗎?願意付費用的,WhatsApp 96439737

    回覆刪除
  5. 我想問我是unity上傳左個and....手機game,但有個問題 unity的APK是google play不能正常使用(down load 玩不到)有咩方法可以令APK是google play
    正常使用

    回覆刪除