根据SIM卡安装系统应用

功能:

1:如何安装系统应用,apk放在system/app系统分区下面。 2:根据SIM卡的归属国家选择性的安装应用。

一:本人使用方法:

在开机的服务里面添加接口(PackageManagerService.java),检测到SIM卡的信息调用该接口。 下面是具体的方法: 系统服务PackageManager服务调用的是aidl接口,所以添加接口要添加两个地方,一个是IpackageManager.aidl,还有一个是PackageManagerService.java里面添加接口。下面在PackageManagerService.java里面添加的接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
   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);   
»       »       }  
»       }

scanApkAndInstallAll()是安装预先放在system/app里面的文件,安装为系统app,而不是普通应用。 scanApkAndInstall(String apk),安装system/app下面的其他的文件。
IPackageManager.aidl文件里面添加对应的接口(如果你想开放该接口)。

1
2
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 void scanDirLI(File dir, int flags, int scanMode, long currentTime) 里面过滤这些apk。

1
2
3
4
5
6
7
8
9
10
11
12
private boolean isContainsMyApks(String appName){
  »       if(appName == null){   
  »       »       return false;  
  »       }  
  »       for(String app:mAddedPHICOMMApks){ 
  »       »       if(app.equals(appName)){   
  »       »       »       return true;   
  »       »       };
  »       }  
  »       return false;  
  »          
              }
1
2
3
4
5
6
7
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 .............下面的省略

三:使用这些接口。

我们在接收到SIM卡为ready的广播后,调用这个方法安装系统应用。我在settings里面写的接收广播。AndroidManifests.xml里面加上

1
2
3
4
5
<receiver android:name=".SIMStateReceiver">
            <intent-filter>
                     
            </action></intent-filter>  
        </receiver>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
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
»       »       »       }  
 
»       »       }  
»       }  
1
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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")) {
 
»       »       }  
»       }  
}

这些,为了避免开机重复安装,我们使用Systemproperties.set()往系统属性里面添加一个系统值,如果安装,则写入值,开机的时候读取这个值,避免重复安装。

推推族,免费得门票,游景区:www.tuituizu.com

结伴旅游,一个免费的交友网站:www.jieberu.com

Android如何安装系统应用,及自己增加安装系统应用的接口的更多相关文章

  1. unity3d开发的android应用中增加AD系统的详细步骤

    unity3d开发的android应用中增加AD系统的详细步骤 博客分类: Unity3d unity3d  Unity3d已经支持android,怎样在程序里增加admob?  试了一下,确实能够, ...

  2. Android逆向分析(2) APK的打包与安装

    http://blog.zhaiyifan.cn/2016/02/13/android-reverse-2/ 2/18日增加对aidl和java编译的描述. 前言 上一次我们反编译了手Q,并遇到了Ap ...

  3. 从零开始安装搭建win10与ubuntu20.04双系统开发环境——集安装、配置、软件、美化、常见问题等于一体的——超详细教程

    目录 **前言 ** 关于系统安装配置与软件安装 一.Win10安装ubuntu20.04双系统 1.按照自己的需求分区 2.配置软件镜像源 软件包管理工具介绍 更换APT源--使用国内镜像 3.解决 ...

  4. Android 开发环境在 Windows7 下的部署安装

    Android SDK Android SDK 为 Android 应用的开发.测试和调试提了必要的API库和开发工具. ADT Bundle 下载 如果你是一个android 开发新手,推荐你下载使 ...

  5. 如何安装win10+Red Hat Enterprise Linux双系统?

    1,如何安装win10+Red Hat Enterprise Linux双系统???? 有很多人(没做过调查,可能就我自己想装吧)想要安装Red Hat Enterprise Linux系统,但是又不 ...

  6. Android源码浅析(五)——关于定制系统,如何给你的Android应用系统签名

    Android源码浅析(五)--关于定制系统,如何给你的Android应用系统签名 今天来点简单的我相信很多定制系统的同学都会有一些特定功能的需求,比如 修改系统时间 静默安装 执行某shell命令 ...

  7. Android逆向分析(2) APK的打包与安装背后的故事

    前言 上一次我们反编译了手Q,并遇到了Apktool反编译直接crash的问题,虽然笔者很想在这次解决这个问题,但在解决途中,发现该保护依赖于很多知识,所以本次先插入一下,正所谓知其然知其所以然,授之 ...

  8. Windows 系统下 mysql workbench 的安装及环境配置

    1.MySQL的官网地址:https://www.mysql.com/ 2,选择DOWNLOADS 3.选择community 再MySQL workbench 4.安装MySQL workbench ...

  9. android开发(0):android studio的下载安装与简单使用 | sdk的安装与编译运行

    android studio,简称AS,是集成开发环境,所谓集成,就是集编辑.编译.调试.打包等于一体.简单来说,通过AS,就可以开发出在android系统上运行的APP. 我使用的是macos系统. ...

随机推荐

  1. HDU 1042 N!(高精度阶乘、大数乘法)

    N! Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Submi ...

  2. HDU 1263 水果 (STL map)

    水果 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submissi ...

  3. spring boot-7.日志系统

    日志系统分为两部分,一部分是日志抽象层,一部分是日志实现层.常见的日志抽象层JCL,SLF4J,JBoss-Logging,日志实现层有logback,log4j,log4j2,JUL.日志抽象层的功 ...

  4. spring boot-2.Hello world

    由于 个人习惯,我选择使用STS来作为开发工具.跳过手动构建spring boot 项目的环节,直接使用向导创建spring boot 项目. 1.创建spring boot项目 File ----& ...

  5. centos7下安装phpmyadmin

    安装环境 在同一台主机上部署LAMP Linux( CentOS 7.3 ) .Apache(httpd2.4).MariaDB(5.5).PHP(7.2) 主机IP:192.168.137.200 ...

  6. 均值滤波器(平滑空间滤波器)基本原理及Python实现

    1. 基本原理 使用元素的领域内像素的平均值代替该元素,可明显的降低图像灰度的尖锐变换.它的一种重要应用是模糊处理:得到感兴趣的区域的粗略表示,将次要的/小的元素与背景融合,使得主要的/较大的元素变得 ...

  7. 解决 SQLPlus无法登陆oracle,PLSql可以登陆,报错ORA-12560

    使用Oracle 11g 64位服务器,安装64位.32位客户端,出现SQLPlus无法连接数据库,PLSql可以连接问题. 网上查了很多,都不能解决问题,在下面提供一种. 环境变量 右击计算机属性- ...

  8. java.lang.IllegalArgumentException: id to load is required for loading

    java.lang.IllegalArgumentException: id to load is required for loading at org.hibernate.event.LoadEv ...

  9. Vue.nextTick 的原理和用途

    转载自https://segmentfault.com/a/1190000012861862 概览 官方文档说明: 用法: 在下次 DOM 更新循环结束之后执行延迟回调.在修改数据之后立即使用这个方法 ...

  10. symfony学习笔记——路由

    symfony的路由其实就是通过url映射到控制器的一个设置 _test:    path: /test/{type}/{page} methods: [GET]    defaults: {_con ...