How to install system applications on Android and add the interface for installing system applications on Android
Install system applications based on SIM card features: 1: how to install system applications, apk placed under the system partition of system/app. 2: Install the application selectively according to the country where the SIM card belongs.
I. How to use it myself: add an interface (PackageManagerService. java) to the startup service and detect the SIM card information to call this interface. The following is a specific method: the system service PackageManager calls the aidl interface. Therefore, you need to add two interfaces: IpackageManager. aidl and PackageManagerService. java. The following interface is added in PackageManagerService. java.
private static String[] mAddedApks = { "HandwritePack.apk", "PinyinPack.apk",» » » "ChtPack_.apk", "TouchPal.apk" }; public String[] getApks(){ » return mAddedApks; } public void scanApkAndInstallAll(){» » File systemAppDir = new File(Environment.getRootDirectory(), "app");» » for (String appName : mAddedApks) {» » » File installApp = new File(systemAppDir, appName);» » » if(!installApp.exists()){» » » » continue;» » » }» » » » » » String addedPackage = null;» » » int addedAppId = -1;» » » int[] addedUsers = null;» » » /*» » » * if (!isPackageFilename(installApp)) { // Ignore entries which are» » » * not apk's continue; }» » » */» » » // Set flag to monitor and not change apk file paths when» » » // scanning install directories.» » » int scanMode = SCAN_MONITOR | SCAN_NO_PATHS | SCAN_UPDATE_TIME;» » » int flags = (PackageParser.PARSE_IS_SYSTEM» » » » » | PackageParser.PARSE_IS_SYSTEM_DIR | PackageParser.PARSE_CHATTY);» » » if (mNoDexOpt) {» » » » scanMode |= SCAN_NO_DEX;» » » }» » » synchronized (mInstallLock) {» » » » PackageParser.Package pkg = scanPackageLI(installApp, flags» » » » » » | PackageParser.PARSE_MUST_BE_APK, scanMode,» » » » » » System.currentTimeMillis(), UserHandle.ALL);» » » » // Don't mess around with apps in system partition.» » » » if (pkg == null1547» » » » » » && (flags & PackageParser.PARSE_IS_SYSTEM) == 0» » » » » » && mLastScanError == PackageManager.INSTALL_FAILED_INVALID_APK) {» » » » » // Delete the apk» » » » » installApp.delete();» » » » }» » » » if (pkg != null) {» » » » » /*» » » » » * TODO this seems dangerous as the package may have changed» » » » » * since we last acquired the mPackages lock.» » » » » */» » » » » // writer» » » » » synchronized (mPackages) {» » » » » » updatePermissionsLPw(» » » » » » » » pkg.packageName,» » » » » » » » pkg,» » » » » » » » pkg.permissions.size() > 0 ? UPDATE_PERMISSIONS_ALL» » » » » » » » » » : 0);» » » » » }» » » » » addedPackage = pkg.applicationInfo.packageName;» » » » » addedAppId = UserHandle.getAppId(pkg.applicationInfo.uid);» » » » » addedUsers = sUserManager.getUserIds();» » » » » // reader» » » » » synchronized (mPackages) {» » » » » » mSettings.writeLPr();» » » » » }» » » » }» » » }» » » if (addedPackage != null) {» » » » Bundle extras = new Bundle(1);» » » » extras.putInt(Intent.EXTRA_UID, addedAppId);» » » » sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, addedPackage,» » » » » » extras, null, null, addedUsers);» » » }» » } }» public void scanApkAndInstall(String apkName) {» » File systemAppDir = new File(Environment.getRootDirectory(), "app");» » File installApp = new File(systemAppDir, apkName);» » if (!installApp.exists()) {» » » return;» » }» » String addedPackage = null;» » int addedAppId = -1;» » int[] addedUsers = null;» » /*» » * if (!isPackageFilename(installApp)) { // Ignore entries which are not» » * apk's continue; }» » */» » // Set flag to monitor and not change apk file paths when» » // scanning install directories.» » int scanMode = SCAN_MONITOR | SCAN_NO_PATHS | SCAN_UPDATE_TIME;» » int flags = (PackageParser.PARSE_IS_SYSTEM» » » » | PackageParser.PARSE_IS_SYSTEM_DIR | PackageParser.PARSE_CHATTY);» » if (mNoDexOpt) {» » » scanMode |= SCAN_NO_DEX;» » }» » synchronized (mInstallLock) {» » » PackageParser.Package pkg = scanPackageLI(installApp, flags» » » » » | PackageParser.PARSE_MUST_BE_APK, scanMode,» » » » » System.currentTimeMillis(), UserHandle.ALL);» » » // Don't mess around with apps in system partition.» » » if (pkg == null» » » » » && (flags & PackageParser.PARSE_IS_SYSTEM) == 0» » » » » && mLastScanError == PackageManager.INSTALL_FAILED_INVALID_APK) {» » » » // Delete the apk» » » » installApp.delete();» » » }» » » if (pkg != null) {» » » » /*» » » » * TODO this seems dangerous as the package may have changed» » » » * since we last acquired the mPackages lock.» » » » */» » » » // writer» » » » synchronized (mPackages) {» » » » » updatePermissionsLPw(pkg.packageName, pkg,» » » » » » » pkg.permissions.size() > 0 ? UPDATE_PERMISSIONS_ALL» » » » » » » » » : 0);» » » » }» » » » addedPackage = pkg.applicationInfo.packageName;» » » » addedAppId = UserHandle.getAppId(pkg.applicationInfo.uid);» » » » addedUsers = sUserManager.getUserIds();» » » » // reader» » » » synchronized (mPackages) {» » » » » mSettings.writeLPr();» » » » }» » » }» » }» » if (addedPackage != null) {» » » Bundle extras = new Bundle(1);» » » extras.putInt(Intent.EXTRA_UID, addedAppId);» » » sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, addedPackage,» » » » » extras, null, null, addedUsers);» » }» }
ScanApkAndInstallAll () is a file pre-installed in the system/app, installed as a system app, rather than a common application. ScanApkAndInstall (String apk) to install other files under system/app.
Add the corresponding interface in the IPackageManager. aidl file (if you want to open this interface ).
void scanApkAndInstall(String apkName); void scanApkAndInstallAll();
Ii. Let's take a look at the APK installation process:
Android applications can be installed in the following four ways:
1. system application installation --- completed at startup, without the installation interface ---------> important: since we need to choose to install, some APK does not need to be installed upon first startup (SIM card installation is detected later)
2. download and install the application over the Internet. The installation page is not displayed through the market application.
3. Install the ADB tool --- there is no installation interface. ---------> In fact, when adb pushes to/system/app and system/priv-app, the installation is performed, but there is no interface.
4. Third-party application installation --- the installation interface is provided through the APK file in the SD card. The packageinstaller.apk application processes the installation and uninstallation processes.
Application installation process and Path
Application installation involves the following directories:
System/app --------------- the application that comes with the system can be deleted only after the adb root permission is obtained
Data/app --------------- directory where the user program is installed. Copy the apk file to this directory during installation
Data/data --------------- Store application data
Data/dalvik-cache -------- install the dex file in the apk to the dalvik-cache directory (the dex file is the executable file of the dalvik virtual machine)
Installation Process:
Copy the APK installation package to the data/app directory, decompress and scan the installation package, and save the dex file (Dalvik bytecode) to the dalvik-cache directory, and create the corresponding application data directory under the data/data directory.
Uninstall process:
Delete the files and directories created under the preceding three directories during installation.
Therefore, to avoid installation during startup, We need to filter out some apk installed only after detecting the SIM card. We filter these apk files in the private void scanDirLI (File dir, int flags, int scanMode, long currentTime) function of PackageManagerService. java.
private boolean isContainsMyApks(String appName){ » if(appName == null){ » » return false; » } » for(String app:mAddedPHICOMMApks){ » » if(app.equals(appName)){ » » » return true; » » }; » } » return false; » }
For (I = 0; I <files. length; I ++) {if (dir. getPath (). equals (mSystemAppPath) & isContainsMyApks (files [I]) {} else {File file File = new File (dir, files [I]); if (! IsPackageFilename (files [I]) {continue;} PackageParser. Package pkg = scanPackageLI (file, flags...
3. Use these interfaces. After receiving the broadcast with the SIM card ready, we call this method to install the system application. I wrote in settings to receive broadcasts. In AndroidManifests. xml, add
package com.android.settings;2import android.app.Service;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.content.pm.IPackageManager;import android.os.RemoteException;import android.os.ServiceManager;import android.os.SystemProperties;import android.telephony.TelephonyManager;import android.util.Log;/** * This doucment was added by haiyong.liu to install system/app if SIM iccid is from taiwan . * @author * */public class SIMStateReceiver extends BroadcastReceiver{» private static final String PERSIST_SYS_SIMAPK_INSTALL = "persist.sys.simapkinstall";» private static boolean isInstalling = false;» @Override» public void onReceive(Context context, Intent intent) {» » if (intent.getAction()» » » » .equals("android.intent.action.SIM_STATE_CHANGED")) {» » » TelephonyManager tm = (TelephonyManager) context» » » » » .getSystemService(Service.TELEPHONY_SERVICE);» » » int state = tm.getSimState();» » » switch (state) {» » » case TelephonyManager.SIM_STATE_READY:» » » » Log.e("haiyong.liu", "SIM_STATE_READY");» » » » if (!isInstalling) {» » » » » isInstalling = true;» » » » » installPHICOMMApksAndOther(tm);» » » » }» » » » break;» » » default:» » » » break;» » » }» » }» }
Private void installPHICOMMApksAndOther (TelephonyManager tm) {» String propSimString = SystemProperties. get (PERSIST_SYS_SIMAPK_INSTALL);» String iccidString = tm. getSimSerialNumber ();» if (iccidString. startsWith ("8988")» & (propSimString = null | propSimString. equals ("") {» IPackageManager iPackageManager = IPackageManager. stub »»»»». asInterface (ServiceManager. getService ("package"); pay attention to the use of this interface because "package" is used during registration at startup» try {» iPackageManager. scanPHICOMMApkAndInstallAll ();»} catch (RemoteException e) {» Log. e ("haiyong. liu "," SIMStateReceiver RemoteException: "+ e);»}» SystemProperties. set (PERSIST_SYS_SIMAPK_INSTALL, "installed");»} else if (propSimString. equals ("installed ")){»»}»}}
To avoid repeated installation at startup, we use Systemproperties. set () adds a system value to the system attribute. If it is installed, the value is written. The value is read during startup to avoid repeated installation.