如何使用Android原生介面,實現“應用雙開”

丿灬安之若死發表於2017-11-08

第一次使用應用雙開功能的時候,感覺好神奇,一直想研究他是怎麼實現的,無奈反編譯後看不懂,就此作罷。

前端時間做專案的時候,突然發現android 5.0以後引入的一個神奇的功能--Android in the Enterprise,我稱之為--企業空間。

Android 5.0以後允許在原本使用者上面,建立一個企業空間,在企業空間裡,可以包含有多個應用,這些應用和原本使用者的應用是獨立的。2個空間(企業空間和使用者空間)之前的資料也是分開的。這樣可以更好的保證企業空間內應用資料的保密性,在企業空間內甚至可以設定一個遠端的管理員,管理員可以設定企業空間內的各個應用的 許可權,比如說能否訪問某個網址之類的,還有非常多的高階功能,有興趣的同學可以閱讀google的官方文件。

https://developer.android.com/work/overview.html


由於企業空間和原本使用者空間是獨立的,而且可以獨立同時執行,所以我們可以用這個來實現一個“”應用雙開“。

我參考google官方demo做了一個類似應用雙開的功能。

這邊大概介紹下流程:
1:建立一個企業空間
  1. /** 
  2.  * Initiates the managed profile provisioning. If we already have a managed profile set up on 
  3.  * this device, we will get an error dialog in the following provisioning phase. 
  4.  */  
  5. private void provisionManagedProfile() {  
  6.     Activity activity = getActivity();  
  7.     if (null == activity) {  
  8.         return;  
  9.     }  
  10.     Intent intent = new Intent(ACTION_PROVISION_MANAGED_PROFILE);  
  11.     intent.putExtra(EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME,  
  12.                     activity.getApplicationContext().getPackageName());  
  13.     if (intent.resolveActivity(activity.getPackageManager()) != null) {  
  14.         startActivityForResult(intent, REQUEST_PROVISION_MANAGED_PROFILE);  
  15.         activity.finish();  
  16.     } else {  
  17.         Toast.makeText(activity, "Device provisioning is not enabled. Stopping.",  
  18.                 Toast.LENGTH_SHORT).show();  
  19.     }  
  20. }  

2:建立成功後
   通過之前傳入的DeviceAdminReceiver,可以接收到訊息,這邊可以提醒使用者
3:啟動企業空間配置應用
   企業空間建立成功之後,會在桌面生成企業空間的組,系統會預設將一些應用加入企業空間
啟動這邊的BoboUtils就可以對需要雙開的應用進行配置。
主要呼叫以下方法開啟、關閉需要雙開的應用
  1. /** 
  2.      * Enables or disables the specified app in this profile. 
  3.      * 
  4.      * @param packageName The package name of the target app. 
  5.      * @param enabled     Pass true to enable the app. 
  6.      */  
  7.     private void setAppEnabled(String packageName, boolean enabled) {  
  8.         Activity activity = getActivity();  
  9.         if (null == activity) {  
  10.             return;  
  11.         }  
  12.         PackageManager packageManager = activity.getPackageManager();  
  13.         DevicePolicyManager devicePolicyManager =  
  14.                 (DevicePolicyManager) activity.getSystemService(Context.DEVICE_POLICY_SERVICE);  
  15.         try {  
  16.             ApplicationInfo applicationInfo = packageManager.getApplicationInfo(packageName,  
  17.                     PackageManager.GET_UNINSTALLED_PACKAGES);  
  18.             // Here, we check the ApplicationInfo of the target app, and see if the flags have  
  19.             // ApplicationInfo.FLAG_INSTALLED turned on using bitwise operation.  
  20.             if (0 == (applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED)) {  
  21.                 // If the app is not installed in this profile, we can enable it by  
  22.                 // DPM.enableSystemApp  
  23.                 if (enabled) {  
  24.                     devicePolicyManager.enableSystemApp(  
  25.                             BasicDeviceAdminReceiver.getComponentName(activity), packageName);  
  26.                 } else {  
  27.                     // But we cannot disable the app since it is already disabled  
  28.                     Log.e(TAG, "Cannot disable this app: " + packageName);  
  29.                     return;  
  30.                 }  
  31.             } else {  
  32.                 // If the app is already installed, we can enable or disable it by  
  33.                 // DPM.setApplicationHidden  
  34.                 devicePolicyManager.setApplicationHidden(  
  35.                         BasicDeviceAdminReceiver.getComponentName(activity), packageName, !enabled);  
  36.             }  
  37.             Toast.makeText(activity, enabled ? R.string.enabled : R.string.disabled,  
  38.                     Toast.LENGTH_SHORT).show();  
  39.         } catch (PackageManager.NameNotFoundException e) {  
  40.             Log.e(TAG, "The app cannot be found: " + packageName, e);  
  41.         }  
  42.     }  

  1.   
原始碼可以從 https://github.com/bobohuang1985/android-utils-api 下載,具體程式碼位置在
utils.bobo.com.boboutils.MultiApp包內,

相關文章