在Android系统定制开发中,我不知道该功能有没有用在商用的产品中,最近在看PMS的源码,PMS里面包含了应用的安装、卸载等功能,那我们能不能在PMS里面去限制某个应用的安装或者卸载呢?答案是当然能,因为整个系统的应用安装都要走PMS,我们只需要在PMS里面拦截安装,即可实现此功能,下面上代码。
PMS代码片段:
/* Called when a downloaded package installation has been confirmed by the user */
public void installPackage(
final Uri packageURI, final IPackageInstallObserver observer, final int flags) {
installPackage(packageURI, observer, flags, null);
}
/* Called when a downloaded package installation has been confirmed by the user */
public void installPackage(
final Uri packageURI, final IPackageInstallObserver observer, final int flags,
final String installerPackageName) {
installPackageWithVerification(packageURI, observer, flags, installerPackageName, null,
null, null);
}
@Override
public void installPackageWithVerification(Uri packageURI, IPackageInstallObserver observer,
int flags, String installerPackageName, Uri verificationURI,
ManifestDigest manifestDigest, ContainerEncryptionParams encryptionParams) {
VerificationParams verificationParams = new VerificationParams(verificationURI, null, null,
VerificationParams.NO_UID, manifestDigest);
installPackageWithVerificationAndEncryption(packageURI, observer, flags,
installerPackageName, verificationParams, encryptionParams);
}
public void installPackageWithVerificationAndEncryption(Uri packageURI,
IPackageInstallObserver observer, int flags, String installerPackageName,
VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
null);
final int uid = Binder.getCallingUid();
if (isUserRestricted(UserHandle.getUserId(uid), UserManager.DISALLOW_INSTALL_APPS)) {
try {
observer.packageInstalled("", PackageManager.INSTALL_FAILED_USER_RESTRICTED);
} catch (RemoteException re) {
}
return;
}
UserHandle user;
if ((flags&PackageManager.INSTALL_ALL_USERS) != 0) {
user = UserHandle.ALL;
} else {
user = new UserHandle(UserHandle.getUserId(uid));
}
final int filteredFlags;
if (uid == Process.SHELL_UID || uid == 0) {
if (DEBUG_INSTALL) {
Slog.v(TAG, "Install from ADB");
}
filteredFlags = flags | PackageManager.INSTALL_FROM_ADB;
} else {
filteredFlags = flags & ~PackageManager.INSTALL_FROM_ADB;
}
verificationParams.setInstallerUid(uid);
final Message msg = mHandler.obtainMessage(INIT_COPY);
msg.obj = new InstallParams(packageURI, observer, filteredFlags, installerPackageName,
verificationParams, encryptionParams, user);
mHandler.sendMessage(msg);
}
我们通过阅读代码可以知道,应用安装过程一定会经过installPackageWithVerificationAndEncryption这个函数方法,即上面列出的方法,在此处我们可以拦截安装,代码如下:
public void installPackageWithVerificationAndEncryption(Uri packageURI,
IPackageInstallObserver observer, int flags, String installerPackageName,
VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
null);
final int uid = Binder.getCallingUid();
if (isUserRestricted(UserHandle.getUserId(uid), UserManager.DISALLOW_INSTALL_APPS)) {
try {
observer.packageInstalled("", PackageManager.INSTALL_FAILED_USER_RESTRICTED);
} catch (RemoteException re) {
}
return;
}
UserHandle user;
if ((flags&PackageManager.INSTALL_ALL_USERS) != 0) {
user = UserHandle.ALL;
} else {
user = new UserHandle(UserHandle.getUserId(uid));
}
final int filteredFlags;
if (uid == Process.SHELL_UID || uid == 0) {
if (DEBUG_INSTALL) {
Slog.v(TAG, "Install from ADB");
}
filteredFlags = flags | PackageManager.INSTALL_FROM_ADB;
} else {
filteredFlags = flags & ~PackageManager.INSTALL_FROM_ADB;
}
verificationParams.setInstallerUid(uid);
//start add 20230724 by liu
try{
if(packageURI!=null){
Slog.v("liu-install", "apk url "+packageURI.getPath());
String pail=getPackageInfoLite(packageURI.getPath());
if(pail!=null){
Slog.v("liu-install", "Install "+pail);
if(pail.contains("com.dianshijia.newlive")){
Slog.v("liu-install", "not Install "+pail);
return;
}
}
}
}catch(RemoteException e){
}
//end add 20230724 by liu
final Message msg = mHandler.obtainMessage(INIT_COPY);
msg.obj = new InstallParams(packageURI, observer, filteredFlags, installerPackageName,
verificationParams, encryptionParams, user);
mHandler.sendMessage(msg);
}
/**
*start add 20230724 by liu
*/
private String getPackageInfoLite(String packageFilePath) throws RemoteException{
//file:///storage/emulated/0/dianshijia.apk
//
PackageParser.PackageLite pkg = PackageParser.parsePackageLite(packageFilePath, 0);
if (pkg == null) {
/*final File apkFile = new File(packagePath);
if (!apkFile.exists()) {
ret.recommendedInstallLocation = PackageHelper.RECOMMEND_FAILED_INVALID_URI;
} else {
ret.recommendedInstallLocation = PackageHelper.RECOMMEND_FAILED_INVALID_APK;
}*/
return null;
}
return pkg.packageName;
}
加上上面拦截代码,即可实现应用安装限制,adb 安装或者系统安装都可,以上可能还有需要完善的地方,欢迎留言!
QQ交流:3151365988