根据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_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 1547» » » » » » && (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); » » } » }
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; 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")); 注意该接口的使用,因开机注册的时候使用的是"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")) { » » } » } }