Android 5.1.1源码修改添加白名单和静默安装功能
最近弄项目都是些要改源码才能实现的,像静默安装和白名单功能.
静默安装:
1:在源码的AndroidMainfest.xml中添加权限
--- a/frameworks/base/core/res/AndroidManifest.xml
+++ b/frameworks/base/core/res/AndroidManifest.xml
@@ -2451,6 +2451,10 @@
<p>Not for use by third-party applications. -->
<permission android:name="android.permission.INSTALL_PACKAGES"
android:protectionLevel="signature|privileged" />
+ <permission android:name="android.permission.HIDE_INSTALL_PACKAGES"
+ android:protectionLevel="normal" />
+ <permission android:name="android.permission.HIDE_UNINSTALL_PACKAGES"
+ android:protectionLevel="normal" />
2 :在IPackManger.Stub中添加权限判断
--- a/frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -11704,7 +11704,13 @@ public class PackageManagerService extends IPackageManager.Stub {
public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer,
int installFlags, String installerPackageName, int userId) {
android.util.SeempLog.record(90);
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
+ //mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
+ if(mContext.checkCallingPermission(android.Manifest.permission.HIDE_INSTALL_PACKAGES) == PackageManager.PERMISSION_GRANTED) {
+ Slog.i(TAG, "installerPackageName: checkCallingPermission "+installerPackageName);
+ } else {
+ Slog.i(TAG, "installerPackageName: checkCallingPermission PERMISSION_DENIED"+PackageManager.PERMISSION_DENIED);
+ mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
+ }
3:在APP的libs添加pminstall.jar
4:在APP中添加<uses-permission android:name="android.permission.HIDE_INSTALL_PACKAGES" />权限
静默安装就成功了!!!撒花庆祝。
demo的连接地址:https://github.com/ChloeDimen/pmApplication
白名单功能:因为也是在在源码中修改,查了很多资料和自己的理解,有可能有问题。希望大家理解,有问题大家在评论中提出。
本人希望白名单是可以在SD卡中修改的,查资料是把白名单打包到系统的,所有自己修改验证。
先说下android的apk安装方式,在修改源码。
1:直接调用安装接口
Uri mPackageURI = Uri.fromFile(new File(Environment.getExternalStorageDirectory() + apkName));
int installFlags = 0;
PackageManager pm = getPackageManager();
try{
PackageInfo pi = pm.getPackageInfo(packageName,
PackageManager.GET_UNINSTALLED_PACKAGES);
if(pi != null) {
installFlags |= PackageManager.REPLACE_EXISTING_PACKAGE;
}
}
catch (NameNotFoundException e){}
PackageInstallObserver observer = new PackageInstallObserver();
pm.installPackage(mPackageURI, observer, installFlags);
这种方式一般在APP中,我们是用AIDl的集成,在调用pm.installpackage(mPackageURI, observer, installFlags)。不过要配置很多东西,AIDl导入也要很多错误,要自己修改。app还需要在AndroidManifest增加一句 android:sharedUserId=”android.uid.system”,而且还要用系统的签名工具。因为每个版本和每种不同手机的签名工具不一样,所有在手机上不适合。在市面上像完成静默安装,我知道的只有开发应用市场类的APP。
我现在可以修改源码,就是在自己的板子上开发了!!!
2:通过intent机制,调用packageInstall进行安装(有弹框)
String fileName = Environment.getExternalStorageDirectory() + apkName;
Uri uri = Uri.fromFile(new File(fileName));
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri, application/vnd.android.package-archive");
startActivity(intent)
3:通过命令进行安装 pm install
修改源码:
1:packageMangerServer修改
源码位置:frameworks\base\services\core\java\com\android\server\pm\PackageMangerServer.java,对源码不熟悉找位置找了好久(后面的现在方便了)。
1)添加函数判断
/*add for installer white list*/
private boolean isInstallerEnable(String packagename){
ArrayList<String> whiteListApp = new ArrayList<String>();
Log.e(TAG, "mCallingApp:==5 " );
try{
BufferedReader br = new BufferedReader(new InputStreamReader(
new FileInputStream("/sdcard/WhiteListAppFilter.properties")));
Log.e(TAG, "mCallingApp:==6 " );
String line ="";
while ((line = br.readLine()) != null){
Log.e(TAG, "mCallingApp:==7 " );
whiteListApp.add(line);
Log.e(TAG, "mCallingApp:==8 " );
}
br.close();
}catch(java.io.FileNotFoundException ex){
return false;
}catch(java.io.IOException ex){
return false;
}
Log.e(TAG, "mCallingApp:==9 " );
Iterator<String> it = whiteListApp.iterator();
Log.e(TAG, "mCallingApp:==10 " );
while (it.hasNext()) {
Log.e(TAG, "mCallingApp:==11 " );
String whitelisItem = it.next();
Log.e(TAG, "mCallingApp:==12 "+" ,whitelisItem"+whitelisItem+" ,packagename"+packagename );
if (whitelisItem.equals(packagename)) {
Log.e(TAG, "mCallingApp:==13 " );
return true;
}
}
Log.e(TAG, "mCallingApp:==14 " );
return false;
}
isWhiteListApp函数会去读取白名单文件/system/etc/whitelistapps,然后和我们传进来的包名进行匹配,在白名单中返回true,其他情况均返回false。这是在白名单不可以给别人修改的,我要在SD卡中"/sdcard/WhiteListAppFilter.properties"),自己修改,下面就统一这个地址。日志就不删除了,偷懒中。
重要的:要导包,查资料又是没有,苦逼。好的自己加
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Iterator;
2)获取调用的包名判断是否在白名单中
接下来要在installPackageLI函数对调用安装的apk进行匹配,判断是否在白名单中,如果不在的话则提示错误。注释start和end的代码。
private void installPackageLI(InstallArgs args, PackageInstalledInfo res) {
final int installFlags = args.installFlags;
String installerPackageName = args.installerPackageName;
File tmpPackageFile = new File(args.getCodePath());
boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
boolean onSd = ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0);
boolean replace = false;
final int scanFlags = SCAN_NEW_INSTALL | SCAN_FORCE_DEX | SCAN_UPDATE_SIGNATURE;
// Result object to be returned
res.returnCode = PackageManager.INSTALL_SUCCEEDED;
。。。。。。。。
try {
pp.collectCertificates(pkg, parseFlags);
pp.collectManifestDigest(pkg);
} catch (PackageParserException e) {
res.setError("Failed collect during installPackageLI", e);
return;
}
// start
if(!isInstallerEnable(pkg.packageName)) {
Log.e(TAG, "mCallingApp:==1 "+pkg.packageName);
res.setError(PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE,
"app is not in the whitelist. packageName:" + pkg.packageName);
Log.e(TAG, "mCallingApp:==2 " );
return;
}
// end
/* If the installer passed in a manifest digest, compare it now. */
if (args.manifestDigest != null) {
if (DEBUG_INSTALL) {
final String parsedManifest = pkg.manifestDigest == null ? "null"
: pkg.manifestDigest.toString();
Slog.d(TAG, "Comparing manifests: " + args.manifestDigest.toString() + " vs. "
+ parsedManifest);
}
3)添加白名单
/system/etc/whitelistapps内容如下,在编译时可以在mk中修改拷贝到etc目录下,例如下面就是允许这三个包名有安装权限。
com.xxx.xxx1
com.xxx.xxx2
com.xxx.xxx3
这是在系统的可以,但在在SD卡中汇报没有权限的错误。
2、packageInstall的修改
还是参考packageManagerService的修改,增加isInstallerEnable函数,去读取白名单文件/"/sdcard/WhiteListAppFilter.properties"),然后进行包名匹配,在白名单中返回true,其他情况均返回false。
我们在packageInstaller的PackageInstallerActivity.java中增加以下修改// add for installer enable/disable ,不在白名单中的app,会直接提示不允许安装后退出。
@Override
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
mPm = getPackageManager();
mInstaller = mPm.getPackageInstaller();
mUserManager = (UserManager) getSystemService(Context.USER_SERVICE);
final Intent intent = getIntent();
if (PackageInstaller.ACTION_CONFIRM_PERMISSIONS.equals(intent.getAction())) {
final int sessionId = intent.getIntExtra(PackageInstaller.EXTRA_SESSION_ID, -1);
final PackageInstaller.SessionInfo info = mInstaller.getSessionInfo(sessionId);
if (info == null || !info.sealed || info.resolvedBaseCodePath == null) {
Log.w(TAG, "Session " + mSessionId + " in funky state; ignoring");
finish();
return;
}
。。。。。。。。
//set view
setContentView(R.layout.install_start);
mInstallConfirm = findViewById(R.id.install_confirm_panel);
mInstallConfirm.setVisibility(View.INVISIBLE);
PackageUtil.initSnippetForNewApp(this, as, R.id.app_snippet);
mOriginatingUid = getOriginatingUid(intent);
// add for installer enable/disable
if (!isInstallerEnable(mPkgInfo.packageName)) {
Log.e(TAG, "mCallingApp:==1 " );
//Toast.makeText(this, R.string.install_not_allow, Toast.LENGTH_LONG).show();
this.finish();
Log.e(TAG, "mCallingApp:==2 " );
}
// Block the install attempt on the Unknown Sources setting if necessary.
if (!requestFromUnknownSource) {
initiateInstall();
return;
}
// If the admin prohibits it, or we're running in a managed profile, just show error
// and exit. Otherwise show an option to take the user to Settings to change the setting.
final boolean isManagedProfile = mUserManager.isManagedProfile();
if (!unknownSourcesAllowedByAdmin
|| (!unknownSourcesAllowedByUser && isManagedProfile)) {
showDialogInner(DLG_ADMIN_RESTRICTS_UNKNOWN_SOURCES);
mInstallFlowAnalytics.setFlowFinished(
InstallFlowAnalytics.RESULT_BLOCKED_BY_UNKNOWN_SOURCES_SETTING);
} else if (!unknownSourcesAllowedByUser) {
// Ask user to enable setting first
showDialogInner(DLG_UNKNOWN_SOURCES);
mInstallFlowAnalytics.setFlowFinished(
InstallFlowAnalytics.RESULT_BLOCKED_BY_UNKNOWN_SOURCES_SETTING);
} else {
initiateInstall();
}
}
/** Get the ApplicationInfo for the calling package, if available */
private ApplicationInfo getSourceInfo() {
String callingPackage = getCallingPackage();
if (callingPackage != null) {
try {
return mPm.getApplicationInfo(callingPackage, 0);
} catch (NameNotFoundException ex) {
// ignore
}
}
return null;
}
3、pm install 的修改
禁止pm install,因为有些APK安装竟然是调用pm install命令去安装的。
修改要在pm.java修改,修改方法和上面基本一致。
可以看到,pm install其实调用的是run再去判断参数。
最后还是调用
mPm.installPackageAsUser(apkFilePath, obs.getBinder(), installFlags,
installerPackageName, verificationParams, abi, userId);
应该修改了packagemangerServer.java 就可以了。
4、在网上还找到一种方式(有带验证),不过感觉还跟简单
1.定义一些全局变量,文件位置:
Build.java (frameworks\base\core\java\android\os)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
2.修改安装APK过程,在安装过程添加验证
修改文件的位置:
PackageManagerService.java (frameworks\base\services\core\java\com\android\server\pm)
首先添加一个函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
|
修改的函数:private void installPackageLI(InstallArgs args, PackageInstalledInfo res)
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 |
|
3.证书的压缩方式:
zip -r media.zip media.x509.pem
直接用命令把*.x509.pem 打包成zip文件,然后放到目标板的合适位置;
用第一步中的certificatePath指向存放该zip文件的位置。
总结:只适合自己开发板,正式版本可能有问题(比如在PackageMangerserver把白名单放在SD卡中,没有读写权限)不适合手机的方式。后续看可以解决吗??
Android 5.1.1源码修改添加白名单和静默安装功能相关推荐
- android 4.0模拟器启动不了,Android 4.0 framework源码修改编译,模拟器运行不起来,求助...
当前位置:编程学习 > wap >> Android 4.0 framework源码修改编译,模拟器运行不起来,求助 我下载编译了android 4.0 ICS的源码,然后能利用编译 ...
- 【Android RTMP】RTMPDumb 源码导入 Android Studio ( 交叉编译 | 配置 CMakeList.txt 构建脚本 )
文章目录 安卓直播推流专栏博客总结 一. RTMP 协议 二. RTMP 协议使用 三. RTMPDump 源码下载 四. RTMPDump 源码交叉编译 五. RTMPDump 源码导入 Andro ...
- Android开发让用户开白名单,Android 添加白名单实现保活
Android 白名单保活 最近有遇到保活的需求,一开始想到的就是之前的黑科技保活比如像素Activity,播放无声MP3,双进程等方法,但是随着Android系统的更新,这些非常规的方法或多或少都已 ...
- Android Dialer,Mms,Contacts源码修改笔记,移动端混合开发经验
②在AndroidManifest.xml中修改相应Activity的theme <activity android:name=".HomeActivity" android ...
- android系统源码中添加app源码(源码部署移植)
涉及到系统定制,需要在系统中加入自己的apk工程,但是上网找了很多资料都是不够全面的,或者看了还是没搞懂,我自己也是一点点摸索过来的,花了不少的时间,也是踩了不少的坑,因此特开一文,帮助大家渡河. 申 ...
- android打开volte代码,Android8.1 源码修改之插入SIM卡默认启用Volte功能
前言 公用电话产品,插入SIM卡后要求自动打开Volte功能,即插即用,用完拔卡就走 实现 第一步 开关对应的代码 通过打印日志和全局查找,源码位置 vendor/mediatek/proprieta ...
- Android系统定制源码修改 - MTK平台
Android系统定制源码修改 - MTK平台 1.修改开机弹出欢迎使用SIM MTK工程/mediatek/packag ...
- Android TV 源码修改默认输入法
前一阵子,应泰国客户需求,需要在Android TV系统定制一个多语言输入法,至少支持中.英.泰三种语言.拿到这个任务,对于至今还是小白的我来说,当然先去google一下有没有大神专门做过符合要求的输 ...
- Android6.0 源码修改之 仿IOS添加全屏可拖拽浮窗返回按钮...
Android6.0 源码修改之 仿IOS添加全屏可拖拽浮窗返回按钮 前言 之前写过屏蔽系统导航栏功能的文章,具体可看Android6.0 源码修改之屏蔽导航栏虚拟按键(Home和RecentAPP) ...
最新文章
- seq2seq编码器和解码器:TensorFlow实现
- 【渝粤题库】国家开放大学2021春2238个案工作题目
- 前端字符串内HTML标签无效的处理方式
- Visual studio 2012 ultimate 安装遇到 Prerequisites , 错误的函数 incorrect function
- thinkphp仿百度文库网站源码
- MBTI性格类型测试
- 抑制过拟合的方法之Dropout(随机删除神经元)
- tomcat启动后,页面浏览时报错 Unable to compile class for JSP的解决方案
- 深入学习 Intellij IDEA 调试技巧
- Facebook再遭黑客攻击 部分账户密码被盗
- 功能扩展——邮件发送、网页注册
- fastlane build 版本号自增
- 即时聊天工具混战中国
- 数字图像处理与Python实现-Scikit-Image-图像滤波(三)
- unity 扩展器添加脚本
- ArcGIS基础:全站仪或RTK采集的DAT文件生成点图形
- Tomcat DBCP连接池导致的线程阻塞问题
- Python识别垃圾邮件
- 【NLP基础】常见的距离公式说明
- 怎么录制教学视频?这两招解决你的录屏需求
热门文章
- JDK内置注解元注解++反射
- 达梦数据库恢复到指定时间点
- linux系统php连接dm达梦
- 欢迎广大编程爱好者为MyPage网站提供改进方案
- 2050热身赛 1001 1004
- 做电商网站如何选购云服务器?
- 夜神模拟器连接loaclhost
- 框架和平台的区别以及两者的重要性(出自“至简李云” 博客)
- Rasa课程、Rasa培训、Rasa面试、Rasa实战系列之Understanding Rasa Deployments Premade Rasa Containers
- DATEADD() 函数详细说明