Google Play 下架App之后的替身制作

前段時(shí)間升級(jí) qq sdk 實(shí)現(xiàn)第三方登錄功能。在用戶(hù)手機(jī)未安裝QQ時(shí),會(huì)引導(dǎo)用戶(hù)下載安裝。Google Play 商店以它的規(guī)則為由下架了我們的App。這個(gè)問(wèn)題很多開(kāi)發(fā)者都遇到過(guò),畢竟我們都得聽(tīng) Google 的,規(guī)則制定者不是開(kāi)玩笑的。經(jīng)過(guò)溝通,堅(jiān)決不讓重新上架,提議換個(gè)包名拷貝代碼,重新上傳一個(gè)新的應(yīng)用。我們當(dāng)時(shí)按照這個(gè)簡(jiǎn)單的方法上架了緊急修復(fù)的App,但是考慮到后續(xù)功能迭代以及兩個(gè)項(xiàng)目的維護(hù)成本,需要尋求一個(gè)新的方式來(lái)完成這些操作。

背景

公司有個(gè)老版本的讀書(shū)軟件一直在線(xiàn)上,但是很久沒(méi)維護(hù)了。這次事故正好可以把老的軟件作為殼子,替換成目前維護(hù)的新的App。這樣可以避免用戶(hù)流失(Google Play 渠道用戶(hù)量本身就不是很大)。

修改應(yīng)用ID

每個(gè) Android 應(yīng)用均有一個(gè)唯一的應(yīng)用 ID,像 Java 軟件包名稱(chēng)一樣,如 com.example.myapp。 此 ID 可以在設(shè)備上和 Google Play 商店中對(duì)您的應(yīng)用進(jìn)行唯一標(biāo)識(shí)。 如果您想要上傳新版本的應(yīng)用,應(yīng)用 ID(以及使用它簽署的證書(shū))必須與原始 APK 相同 - 如果您更改應(yīng)用 ID,Google Play 商店會(huì)將 APK 視為完全不同的應(yīng)用。所以您發(fā)布應(yīng)用后,絕不應(yīng)更改應(yīng)用 ID。

基于這個(gè)原則,我們實(shí)現(xiàn)的方式很簡(jiǎn)單,配置編譯變體,指定特定的 applicationId

應(yīng)用是基于 Walle 進(jìn)行多渠道打包的,那么我們需要配置兩個(gè) productFlavors ,其中一個(gè)是對(duì) Google Play 商店的定制版,另一個(gè)是使用 [Wally] 進(jìn)行多渠道打包的基礎(chǔ)apk。當(dāng)然如果你沒(méi)有做多渠道打包,那么也至少需要配置兩個(gè),畢竟你需要一個(gè) 未變體的 Apk 供其他渠道使用。

flavorDimensions "default" // 當(dāng)只有一個(gè)時(shí),不需要在 Flavors 中重復(fù)指定
productFlavors {
    google { // Google Play 商店的定制版
        applicationId "com.yun.reader"
    }

    yun { // 基礎(chǔ)版本 apk
        applicationId "com.yun.news"
    }
}

好了,現(xiàn)在我們可以編譯兩個(gè)不同的 apk 了。

指定不同的簽名

老版本的 Apk 簽名和新開(kāi)發(fā) Apk 并不是用的同一個(gè)簽名文件,所以,在productFlavors中需要指定簽名文件。

首先我們需要定義簽名文件:

android {
    signingConfigs {
        yun {
            if (System.getenv("YUN_NEWS_KEYSTORE_FILE") != null) {
                storeFile file(System.getenv("YUN_NEWS_KEYSTORE_FILE"))
                storePassword System.getenv("YUN_NEWS_KEYSTORE_PASSWORD")
                keyAlias System.getenv("YUN_NEWS_KEY_ALIAS")
                keyPassword System.getenv("YUN_NEWS_KEY_PASSWORD")
            }
        }

        google {
            if (System.getenv("YUN_READER_KEYSTORE_FILE") != null) {
                storeFile file(System.getenv("YUN_READER_KEYSTORE_FILE"))
                storePassword System.getenv("YUN_READER_KEYSTORE_PASSWORD")
                keyAlias System.getenv("YUN_READER_KEY_ALIAS")
                keyPassword System.getenv("YUN_READER_KEY_PASSWORD")
            }
        }
    }
}

看上面的代碼你會(huì)發(fā)現(xiàn),我們的路徑都是放在遠(yuǎn)程編譯服務(wù)器的環(huán)境變量中的,你也可以存放在本地的 local.properties 中,具體的操作可以自行Google。

兩個(gè)簽名定義完成,使用起來(lái)很簡(jiǎn)單:

flavorDimensions "default" // 當(dāng)只有一個(gè)時(shí),不需要在 Flavors 中重復(fù)指定
productFlavors {
    google { // Google Play 商店的定制版
        applicationId "com.yun.reader"
        signingConfig signingConfigs.google
    }

    yun { // 基礎(chǔ)版本 apk
        applicationId "com.yun.news"
        signingConfig signingConfigs.yun
    }
}

這里有幾點(diǎn)需要注意

  1. signingConfigs 聲明需要放在 productFlavors 之前,否則找不到對(duì)應(yīng)的自定義簽名
  2. productFlavors 中已指定簽名,需要把 buildTypes -> release 下面指定的簽名刪除,否則在編譯 Release 版本時(shí)會(huì)覆蓋掉 productFlavors 中指定的簽名。

微信支付相關(guān)報(bào)錯(cuò)

我們替換掉 applicationId 之后,其實(shí) Context.getPackageName() 方法返回的值也跟著變化了,那么,微信支付根據(jù)這個(gè)包名去查找相關(guān)的配置肯定是找不到的,所以,我們需要將 WXEntryActivityWXPayEntryActivity 拷貝一份到 com.yun.reader.wxapi 包名下面。記得在 manifests 中用絕對(duì)路徑聲明這兩個(gè) Activity。

有的同學(xué)就算這樣配置之后,微信支付仍然會(huì)報(bào)錯(cuò),因?yàn)槲覀兏牧?applicationId 導(dǎo)致以前默認(rèn)是 news 的相關(guān)配置對(duì) reader 是不適用的。所以我們需要為以前的代碼背鍋,將所有寫(xiě)死的地方改為配置型。

例如:
在微信支付時(shí),需要傳遞 app_code 字段,讓服務(wù)器在生成訂單時(shí),知曉當(dāng)前的應(yīng)用是哪一個(gè),方便后續(xù)的校對(duì)。如果服務(wù)器直接寫(xiě)死了是 news, 那么在后續(xù)匹配中,news 申請(qǐng)的 支付碼和 packageName 不能匹配,那么支付失敗是必然的。

類(lèi)似的問(wèn)題還有 cookie , 與Web端交互的時(shí)候,對(duì)方會(huì)根據(jù)cookie來(lái)判別應(yīng)用,所以Web端也需要做兼容。RN 端類(lèi)似。

參考:https://developer.android.com/studio/build/application-id?hl=zh-cn

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 最近在項(xiàng)目中遇到需要實(shí)現(xiàn) Apk 多渠道、定制化打包, Google 、百度查找了一些資料,成功實(shí)現(xiàn)了上述功能,在...
    看一季殘花落幕閱讀 2,650評(píng)論 1 8
  • 聽(tīng)說(shuō)生活很忙 ——瘦桶 山高細(xì)水長(zhǎng)流 秋風(fēng)十里 今夜的風(fēng)又吹向哪里 只有湖水 關(guān)閉了所有的秘密 安靜的守...
    瘦桶閱讀 407評(píng)論 1 23
  • 社會(huì)和諧與否,不僅取決于法律約束,更重要的是無(wú)形中的道德標(biāo)準(zhǔn)。而道德標(biāo)準(zhǔn)又取決于家庭背景,社會(huì)環(huán)境等多方面因素。協(xié)...
    梁夢(mèng)婷閱讀 188評(píng)論 0 1

友情鏈接更多精彩內(nèi)容