Android應用雙開實現
Android應用雙開是某些特殊人群的需要,目前已知的雙開方案個人總結為3種:
1.反編譯apk,然後修改uid等相關資訊讓系統弄認為apk有不同,然後重新安裝。這個方法是簡單粗暴的,不過目前主流的app估計都會預防這種修改方法的。對於手機廠商來說,擁有整個系統的程式碼許可權,不會用這麼低階的手段。此種方法我個人也無深入研究。
2.外掛化,在啟動代理apk後動態載入需要雙開的apk,此種方法是雙開實現中最複雜最有技術含量的實現方式。外掛化開源的有360 釋出的DroidPlugin,未開源最有名氣的就是lbe的MultiDroid,據我所知MultiDroid也是諸多手機廠商使用的較多的方案。此種方案的好處是無需修改系統程式碼,問題隔離的完善,對已有系統沒有任何影響。關於外掛化的原理見http://www.jianshu.com/u/e347b97e2f0c,weishu的多篇文章講解的很透徹了。
3.多使用者,小米使用的是這種實現方案,也是我個人想到雙開第一個冒出的想法就是多使用者。使用者系統是Android系統支援的完整的一套東西,基於此開發就相當於站在巨人的肩膀上。基於賬戶系統的雙開本來以為有一定的難度,要改不少地方,最近看了不少UserManagerService的文章和相關原始碼,最後發現一行程式碼不改就能看到雙開的效果。
見原生程式碼的demo
development/samples/browseable/BasicManagedProfile
此demo的本意是展示android5.0的新特性,裝置管理managed profiles 。原始碼相關就是DevicePolicyManager,它可以限制app的行為,例如無法使用攝像頭,瀏覽器只能開啟固定幾個網頁等等。基本原理是新建了一個擁有FLAG_MANAGED_PROFILE flag的user,並且建立想要控制的app到該user,然後控制app行為。該user的app和原有的app都會顯示在launcher上面,這個是市面主流的雙開app需要的所要的效果是一樣一樣的.......
不僅桌面同時顯示,按history鍵顯示的歷史堆疊會顯示所有開啟的app,兩個user的同app也都會顯示。
原生的demo只顯示了system app的使用,如果是三方app需要修改幾行程式碼。
development/samples/browseable/BasicManagedProfile/src/com/example/android/basicmanagedprofile/BasicManagedProfileFragment.java
private void setAppEnabled(String packageName, boolean enabled) { // devicePolicyManager.enableSystemApp( // BasicDeviceAdminReceiver.getComponentName(activity), packageName); int userId = UserHandle.myUserId(); packageManager.installExistingPackageAsUser(packageName, userId); }
註釋的程式碼是原有程式碼,後面的是我針對三方app寫的程式碼。注意AndroidManifest中要加相應的許可權
<uses-permission android:name="android.permission.INSTALL_PACKAGES"/>
<uses-permission android:name="android.permission.DELETE_PACKAGES"/>
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
基本功能ok了,其餘的雙開需求就是苦力活了。
再次證明了對系統程式碼熟悉的話,實現功能可能異常的簡單。