開發(fā)中有一個(gè)需求,是需要彈出彈窗,提示并引導(dǎo)用戶前往應(yīng)用商店中我們指定應(yīng)用的應(yīng)用詳情頁,填寫評價(jià)。這個(gè)需求其實(shí)很簡單,只需要喚起對應(yīng)的應(yīng)用商店,并加上我們應(yīng)用的包名作為參數(shù),即可打開。
首先上代碼,從最簡單的開始,直接打開當(dāng)前手機(jī)的應(yīng)用商店并跳轉(zhuǎn)到我們應(yīng)用的詳情頁:
fun startMarket(){
val intent = Intent(Intent.ACTION_VIEW)
intent.data = Uri.parse("market://details?id=${context.application.packageName}")
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
context.applicationContext.startActivity(intent)
}
原理其實(shí)就是通過intent隱式啟動(dòng)應(yīng)用商店的應(yīng)用詳情Activity,具體是哪個(gè)應(yīng)用的應(yīng)用詳情呢,就指定對應(yīng)的包名即可。
這樣簡單處理會(huì)有一個(gè)問題,加入手機(jī)內(nèi)同時(shí)安裝了多個(gè)應(yīng)用商店,系統(tǒng)會(huì)自己彈出一個(gè)彈窗提示用戶去選擇需要打開哪個(gè)應(yīng)用商店。這樣雖然能滿足大部分需求,但是假如我們的應(yīng)用并沒有在某些應(yīng)用商店商家,那在喚起應(yīng)用商店后會(huì)跳轉(zhuǎn)失敗,一般會(huì)是一個(gè)空白頁面。而且系統(tǒng)的彈窗會(huì)讓用戶選擇是否記住選擇等,如果誤操作打開了錯(cuò)誤的應(yīng)用商店那就白給了。所以一般我們還需要自己指定去打開特定的應(yīng)用商店,只需加一行代碼即可搞定:
fun startMarket(){
val intent = Intent(Intent.ACTION_VIEW)
intent.`package` = "com.xxx.xxx"http://這里指定要打開哪個(gè)應(yīng)用商店
intent.data = Uri.parse("market://details?id=${context.application.packageName}")
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
context.applicationContext.startActivity(intent)
}
通過 package 參數(shù)指定要打開的應(yīng)用商店包名,即可解決。這里有一份市面上的大部分應(yīng)用商店包名,可以參考:
Android應(yīng)用市場和應(yīng)用包名大全
這里要注意一下,oppo系統(tǒng)的應(yīng)用商店包名有兩個(gè),要做個(gè)兼容處理,即 "com.oppo.market" 和 "com.heytap.market"
不過假如手機(jī)上未安裝指定的應(yīng)用商店,這里就會(huì)有問題,所以一般還要先查詢一下當(dāng)前應(yīng)用商店是否安裝,如果未安裝,就不指定包名,另外最好是能根據(jù)當(dāng)前包體的渠道來打開對應(yīng)的應(yīng)用商店,所以最終版代碼如下:
val marketMap = mapOf(
"yyb" to listOf("com.tencent.android.qqdownloader"), //應(yīng)用寶
"huawei" to listOf("com.huawei.appmarket"), //華為
"oppo" to listOf("com.oppo.market", "com.heytap.market"), //oppo
"vivo" to listOf("com.bbk.appstore"), //vivo
"mi" to listOf("com.xiaomi.market") //小米
)
val channel = WalleChannelReader.getChannel(context.application)?:""http://獲取當(dāng)前包體的渠道名 這里涉及到另外一個(gè)多渠道打包庫 可以忽略
val channelMarkets = marketMap[channel]//當(dāng)前渠道對應(yīng)的應(yīng)用商店包名 一般只有一個(gè) oppo有兩個(gè) 要做兼容
val installedMarkets = context.packageManager.getInstalledPackages(0).map { it.packageName }//獲取手機(jī)當(dāng)前已安裝的應(yīng)用
val market = channelMarkets?.find { it in installedMarkets }//找到對應(yīng)的應(yīng)用商店包名
try {
//有成功找到,就打開對應(yīng)的應(yīng)用商店
val intent = Intent(Intent.ACTION_VIEW)
intent.data = Uri.parse("market://details?id=${context.application.packageName}")
intent.`package` = market
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
context.applicationContext.startActivity(intent)
} catch (e: Exception) {
//打開應(yīng)用商店失敗 則做其他兼容性處理
}