根据SIM卡安装系统应用
功能:
一:本人使用方法:
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_CH
ATTY);
» » » 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 1547
» » » » » » && (flags & PackageParser.PARSE_IS_SYSTEM) == 0
» » » » » » && mLastScanError == PackageManager.INSTALL_FAILED_I
NVALID_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_A
PK) {
» » » » // 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_PERMISSI
ONS_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);
» » }
» }
void scanApkAndInstall(String apkName);
void scanApkAndInstallAll();
二:下面我们看看APK安装过程:
Android应用安装有如下四种方式:
1.系统应用安装---开机时完成,没有安装界面--------->>重要:既然我们需要选择安装,所以第一次开机就不需要安装某些APK(以后检测到SIM卡在安装)
2.网络下载应用安装---通过market应用完成,没有安装界面。
3.ADB工具安装---没有安装界面。 --------->其实adb push到/system/app,system/priv-app的时候执行了安装动作,只是没有界面。
4.第三方应用安装---通过SD卡里的APK文件安装,有安装界面,由 packageinstaller.apk应用处理安装及卸载过程的界面。
应用安装的流程及路径
应用安装涉及到如下几个目录:
system/app ---------------系统自带的应用程序,获得adb root权限才能删除
data/app ---------------用户程序安装的目录。安装时把apk文件复制到此目录
data/data ---------------存放应用程序的数据
data/dalvik-cache--------将apk中的dex文件安装到dalvik-cache目录下(dex文件是dalvik虚拟机的可执行文件)
安装过程:
复制APK安装包到data/app目录下,解压并扫描安装包,把dex文件(Dalvik字节码)保存到dalvik-cache目录,并data/data目录下创建对应的应用数据目录。
卸载过程:
删除安装过程中在上述三个目录下创建的文件及目录。
所以,为了避免开机的时候安装,我们需要过滤某些检测到SIM卡之后才安装的apk。我们在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 = new File(dir, files[i]);
if (!isPackageFilename(files[i])) {
continue;
}
PackageParser.Package pkg = scanPackageLI(file, flags .............下面的省略
三:使用这些接口。
<receiver android:name=".SIMStateReceiver">
<intent-filter>
<action android:name="android.intent.action.SIM_STATE_CHANGED" />
</intent-filter>
</receiver>
package com.android.settings;
2
import 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")); 注意该接口的使用,因开机注册的时候使用的是"package"
"
» » » 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")) {
» » }
» }
}