Android11 MTK 安装apk时进行密码验证
1、客户需求
客户要求,在安装apk文件时,进行密码验证。apk文件来源包括浏览器下载、内存中、外接SDK中、adb命令安装等。之后在测试过程,又添加了一个限制,输入错误密码超过3次,则放弃本次安装。
2、解决
路径:frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
private void showConfirmPwd(final InstallArgs args, final int currentStatus){
mHandler.post(new Runnable(){
@Override
public void run(){
AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
builder.setCancelable(false);
builder.setTitle(R.string.pwd_dialog_title);
final EditText et = new EditText(mContext);
builder.setView(et);
builder.setPositiveButton(R.string.pwd_sure, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
String etPwd = et.getText().toString();
if(etPwd == null || etPwd.equals("")){
inputCount++;
if(inputCount >= 3){
processPendingInstall2(args,PackageManager.INSTALL_FAILED_USER_RESTRICTED );
}else{
Toast.makeText(mContext,R.string.pwd_dialog_title,Toast.LENGTH_SHORT).show();
showConfirmPwd(mLzyArgs,mLzyCurrentStatus);
}
}else{
if(!etPwd.equals(android.provider.Settings.System.getString(mContext.getContentResolver(),android.provider.Settings.System.SYS_PASSWORD))){
inputCount++;
if(inputCount >= 3){
processPendingInstall2(args,PackageManager.INSTALL_FAILED_USER_RESTRICTED );
}else{
Toast.makeText(mContext, R.string.pwd_correct,Toast.LENGTH_LONG).show();
showConfirmPwd(mLzyArgs,mLzyCurrentStatus);
}
}else{
dialog.dismiss();
processPendingInstall2(args,currentStatus);
}
}
}
});
builder.setNegativeButton(R.string.pwd_cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialog.dismiss();
processPendingInstall2(args,PackageManager.INSTALL_FAILED_USER_RESTRICTED );
}
});
dialog = builder.create();
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
dialog.show();
}
});
}
private String getInstallPkgName(InstallArgs args){
PackageParser parser = new PackageParser();
if((args.getCodePath() == null) || (args.getCodePath().equals(""))){
return null;
}
try {
PackageParser.Package pkg = parser.parsePackage(new File(args.getCodePath()), 0, true);
return pkg.packageName; // 返回包名
} catch (PackageParser.PackageParserException e) {
// 处理异常,例如打印错误日志
Log.d("InstallArgs", "Unable to parse package at " + args.getCodePath(), e);
return null;
}
}
private InstallArgs mLzyArgs;
private int mLzyCurrentStatus;
private int inputCount = 0;
private void processPendingInstall(final InstallArgs args, final int currentStatus) {
mLzyArgs = args;
mLzyCurrentStatus = currentStatus;
String mInstallPackageName = getInstallPkgName(args);
if(mInstallPackageName == null){
processPendingInstall2(args,PackageManager.INSTALL_FAILED_USER_RESTRICTED);
}else if (mInstallPackageName.equals("com.android.vending") || mInstallPackageName.equals("com.google.android.gms")){
processPendingInstall2(args,currentStatus);
}else{
inputCount = 0;
showConfirmPwd(args,currentStatus);
}
}
private void processPendingInstall2(final InstallArgs args, final int currentStatus) {
if (args.mMultiPackageInstallParams != null) {
args.mMultiPackageInstallParams.tryProcessInstallRequest(args, currentStatus);
} else {
PackageInstalledInfo res = createPackageInstalledInfo(currentStatus);
processInstallRequestsAsync(
res.returnCode == PackageManager.INSTALL_SUCCEEDED,
Collections.singletonList(new InstallRequest(args, res)));
}
}
注:如果是谷歌服务等更新,则不需要输入密码,直接安装。