Android PAI (PlayAutoInstall)預裝APK 功能


最近剛找到工作,是手機方案公司,剛接觸手機系統預裝的APP,以及解決方案MTK平台下預裝APP的bug,也接觸到了Launcher的東西。

然后接觸到了第一個需求

PAI預裝APK功能

下面是我用到的帖子,也很感謝第一個博客主人,加了他QQ,問了很多東西

https://blog.csdn.net/xct841990555/article/details/80896429#commentsedit

這個帖子可能配置方面更加詳細

http://wossoneri.github.io/2017/06/19/[Android][Framework]PlayAutoInstall/?tdsourcetag=s_pcqq_aiomsg

什么是PAI

PAI(PlayAutoInstall)是一個自動下載安裝APK到手機,並且擺放在Launcher對應位置的一個機制。

因為國內沒有大湄公河次區域,所以很多人沒接觸過這個機制。這個機制其實對於運營商定制來說非常重要,比如美國的運營商,一個運營商有很多地區很多種類的SIM卡,當插上不同地區的SIM卡,運營商定制的手機就會下載不同的APP擺放在界面不同的位置。

 

其實主要是要兩個APK,一個預裝進的Android系統中(stub.apk),一個上傳到谷歌的合作伙伴服務器網站上(配置),然后在合作伙伴上進行一些配置就OK了。下面具體介紹這兩個APK的制作。

 

 

PAI流程

 

本地編譯一個PlayAutoInstallConfig.apk,簽名上傳到APFE服務器,APFE會驗證配置信息,並提供給Play商店中。當目標設備第一次開機啟動並且聯網(現在不必要登錄谷歌帳號),這些應用就會加入下載隊列,自動下載到手機。

配置菜單

先聊一下APFE會驗證的配置信息。

需要的配置信息包括:

  • 指紋(必須)
  • 城市(可選)
  • 運營商(可選)
  • 需要下載的應用程序列表
  • 應用在桌面的位置信息

后兩項是編譯在PlayAutoInstallConfig.apk中的,前三項是把APK上傳到服務器時需要填寫的。

上傳服務器配置頁面如下:

配置信息的前三項匹配項如果填寫,就必須要完全匹配才能應用到手機。我遇到一個問題是配置上傳后PlayAutoInstallConfig.apk會在設定精靈過程中下載到手機,但需要Play商店中下載的應用怎么都不下載。后來發現是在上傳APK到服務器時運營商填的不對,導致無法下載。因為嘗試填寫幾種運營商名稱都不能正常工作,最后解決方案是只匹配指紋,不匹配城市和運營商(減少過濾項),這樣手機就可以和Play商店中信息匹配,然后就可以自動下載了。

關於其余配置,參考下面表格:

下面具體放代碼:分為2個APK,一個是預裝手機的APK(stub.apk)一個是放到服務器的APK(config.apk)

stub.apk

手機內必須要先預置一個符合下列條件的stub APK:

  • 為一個系列的設備設置唯一的包名,包名格式為android.autoinstalls.config ..
  • 必須配置一個接收器“android.autoinstalls.config.action.PLAY_AUTO_INSTALL”,並且設置export for flase
  • 在預置的應用程序里只能有一個定義這個接收機
  • 的versionCode必須定義成1
  • APK必須預置在/ system / app(不能定義成特權,即不能放/ priv-app)
  • 必須用私有密鑰簽名(汞用的TCL簽名)
  • 不能定義權限/活動/其他接收者/內容提供者/服務
  •  

è¿éåå¾çæè¿°

MK文件的代碼

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_PACKAGE_NAME := LavaPAIStub
LOCAL_CERTIFICATE := platform
LOCAL_SDK_VERSION := current
LOCAL_AAPT_FLAGS := -x
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_PATH := $(TARGET_OUT_JAVA_LIBRARIES)
LOCAL_EXPORT_PACKAGE_RESOURCES := true LOCAL_MODULE_PATH := $(TARGET_OUT_APPS) include $(BUILD_PACKAGE)

 

AndroidManifest.xml中

<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android.autoinstalls.config.lava.A5s" android:versionCode="1" android:versionName="1">//versionCode和versionName一定要一樣,並且為1 //后面不變 <application android:allowBackup="false" android:label="@string/app_name" > <receiver android:name="DummyReceiver" android:exported="false" > <intent-filter> <action android:name="android.autoinstalls.config.action.PLAY_AUTO_INSTALL" /> </intent-filter> </receiver> </application> </manifest>

 

config.apk

 

這個APK是我們真正配置的APK。

它和前面的APK的關系是:包名一致因為PAI機制需要本地存在一個這個包名的APK,在開機的設定精靈階段,(如果聯網)它會從服務器下載這個寫有對應配置的APK到手機上,替換掉那個Stub APK。

關於PAIconfig APK的配置:

  • 上傳的APK(也就是我們編出來的APK)包名與指紋要和存根一致
  • APK簽名要一致
  • 和存根配置同樣的接收器
  • 的versionCode必須大於1000
  • APK必須包含啟動布局配置的XML文件(即后面會提到的default_layout),不然上傳會失敗,因為上傳前會檢查這個XML文件,然后會把要下載的應用程序顯示出來。所以也必須要求至少定義一個需要下載的app。最多50個,建議放10~15個。(文檔還要求autoinstall的應用必須在launcher上指定擺放位置,目前看來是不需要的,有可能bb launcher做了修改)
  • 界面會有文件夾,文件夾名稱字符串在APK本地資源定義,支持國際化。
  • 需要自動下載的APK對設備來講必須是在Play商店中發布的,並且對該地區用戶可見
  • 不能定義權限/活動/其他接收者/內容提供者/服務

è¿éåå¾çæè¿°

 

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_PACKAGE_NAME := LavaPAIConfig
LOCAL_CERTIFICATE := platform
LOCAL_SDK_VERSION := current
LOCAL_AAPT_FLAGS := -x
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_PATH := $(TARGET_OUT_JAVA_LIBRARIES)
LOCAL_EXPORT_PACKAGE_RESOURCES := true LOCAL_MODULE_PATH := $(TARGET_OUT_APPS) include $(BUILD_PACKAGE)

 

AndroidManifest.xml中

<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android.autoinstalls.config.lava.A5s" android:versionCode="1001" android:versionName="1001"> <application android:allowBackup="false" android:label="@string/app_name" > <receiver android:name="DummyReceiver" android:exported="false" > <intent-filter> <action android:name="android.autoinstalls.config.action.PLAY_AUTO_INSTALL" /> </intent-filter> </receiver> </application> </manifest>

default_layout.xml 
//選擇要安裝的apk,把他們的包名拿到,然后在這個文件中配置

<?xml version="1.0" encoding="utf-8"?> <workspace> <autoinstall packageName="com.twitter.android" className="com.twitter.android.StartActivity" screen="1" x="0" y="0" groupid="0" requiredPreload="true" installByDefault="true" /> <autoinstall packageName="com.instagram.android" className="com.instagram.android.activity.MainTabActivity" screen="1" x="1" y="0" groupid="1" requiredPreload="true" installByDefault="true" /> <autoinstall packageName="com.whatsapp" className="com.whatsapp.Main" screen="1" x="2" y="0" groupid="1" requiredPreload="true" installByDefault="true" /> </workspace>

auto.install.xml

<install> <!-- Group Index Mapping --> <autoinstallgrouplist> <installgroup groupId="0" type="GOOGLE" /> <installgroup groupId="1" type="OEM" /> </autoinstallgrouplist> </install> 

將配置上傳到服務器

 

 

下面我將代碼上傳到CSDN

猶豫我是系統預置,所以我是MK文件編譯。沒有Gradle,如果你們 要用gradle編譯,只需要把我的AndroidManifess.xml + res 這2個文件夾考入到你的項目

config + stub 里面都沒有 JAVA類

 

https://download.csdn.net/download/yangbin0513/10845496 

 

 

驗證流程

用一台新手機,插入對應的SIM卡,你在服務器段,配置好,對應的運營商,然后把APK燒錄到系統里面,恢復出廠設置,重新開始,在過程中聯網,登錄谷歌帳號,進入后在引導功能的時候,會出現,你點選擇安裝,它就開始下載了,等到進入啟動界面,啟動器就會加載這個APK,


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM