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(){@Overridepublic 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() {@Overridepublic 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() {@Overridepublic 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)));}}
注:如果是谷歌服务等更新,则不需要输入密码,直接安装。