當我將專案從 Eclipse 遷移至 Android Studio 並將 application 上線後,發現有小部分的使用者無法安裝。 使用者表示在 Google Play 安裝時會跳出錯誤訊息: 代碼 -505
遇到問題可以先思考兩件事:
- 該版更新有更改了什麼?其中又有哪部分可能影響到安裝?
- 這些使用者有什麼共通點
才發現是 AndroidManifests.xml 中的 applicationId 出了差錯,導致安裝失敗。 接下來將使用「寄包裹」來進行舉例說明:
環境
- Mac @Mojave
- Homebrew @2.2.17
- Android Studio
- Android SDK 23
前提
如果你還不知道 Android 裡 Provider 的用途,最好先摸懂會比較好理解:
點此
可以把它想像成「發言人」,也就是對外的溝通窗口。
角色
device ☞ 郵局 provider ☞ 包裹 authority ☞ 寄件人
前提
☞ 一個人(authority)只能寄一個包裹(provider) ☞ 郵局認名不認人,若兩人姓名相同會被視為同一人 ☞ 先寄先贏 ☞ 全台只有一間郵局
故事
「台北 周支支」(authority)來到台中旅行 將要寄給周媽媽的「太陽餅」及「鳳梨酥」分成了兩個包裹(provider) 抵達郵局後「台北 周支支」將太陽餅順利寄出
當「台北 周支支」打算再寄出鳳梨酥時被郵局拒絕(因為一人只能寄一個包裹) 於是鳳梨酥被貼上退件通知(-505)後,退回給「台北 周支支」
接著郵局又來了位「台南 周支支」 打算寄生活費要給爸爸 但因為「周支支」的發送櫃已有太陽餅包裹 所以郵局一樣在生活費貼上了退件通知(-505),退回給「台南 周支支」
狀況
就在「台北 周支支」的太陽餅等待寄出時
【問題一】 周媽媽打來說她不想要太陽餅,比較想吃鳳梨酥,怎麼辦?
【問題二】 「台南 周支支」急著寄生活費給爸爸怎麼辦?
【解答】 「台北 周支支」必須先撤銷他原先的太陽餅
問題
「台南 周支支」很確定自己並沒有寄過任何東西,為什麼郵局會退回包裹? 於是跑到郵局問個清楚 請郵局查詢寄送紀錄(android studio log):
Can't install because provider
name com.google.android.gms.measurement.google_measurement_service
(in package com.test) is already used by com.test2.app
我們可以發現郵局屬於 周支支
的發送櫃已有一個包裹等待被寄出,但寄件者不是「台南 周支支」本人
而是「台北 周支支」更早到郵局寄了包裹
對應到專案裡,已被註冊的 provider 稱為:com.google.android.gms:play-services-gcm
奇怪,郵局真的這麼笨嗎? 那同名同姓的人又該怎麼辦? 「台南 周支支」重新詢問了郵局審核包裹流程,發現其中一段寫著:
<provider
tools:replace="android:authorities"
android:name="com.google.android.gms.measurement.AppMeasurementContentProvider"
android:authorities="${applicationId}.google_measurement_service"
android:exported="false" />
果然,流程中有留一手可以略過這種同名同姓的情況。
可以看到在姓名處有個亮點:
android:authorities="${applicationId}
.google_measurement_service"
${applicationId}
可以視為是屬於自己的 id
意指我們可以主動建立屬於自己的 id(例如案例中的台北、台南)
這樣郵局審核寄件人時,就會把 id 加在寄件人名字前
舉例:
id 寫上台南,包裹寄件人就會變成是 台南.支支
如此一來即可處理掉姓名重複的問題
問題又來了,id 要寫在哪呢? 「台南 周支支」檢查包裹紙箱(AndroidManifests.xml)發現上面寫著:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.tainan">
奇怪? 台南郵局買的紙箱上,已在 package 上印了「台南」呀,那為何郵局還是不收呢? 立刻前往郵局拿取新的寄送人填寫單(可使用 android studio 建立專案) 才發現原來事有蹊蹺
defaultConfig {
applicationId "tainan"
minSdkVersion 21
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
看出來了嗎?
原來新版寄送單上需要添加 applicationId,但舊版寄送單沒有這一個欄位,難怪郵局不收。
備註
其實目前直接使用郵局給的寄送填寫單(請用 android studio 建立專案)都不會有這個問題 因為 applicationId 預設會被填好 但把程式碼從 eclipse(舊版寄送單)土炮轉到 android studio 時 需要自行添加上這一欄 才不會產生 provider 衝突