实现调用下载DownloadManager需要密码
注:无法管控下载可以通过okhttp等形式
frameworks/base/core/java/android/app/DownloadManager.java
packages/providers/DownloadProvider/src/com/android/providers/downloads/DownloadProvider.java
packages/providers/DownloadProvider/src/com/android/providers/downloads/DownloadJobService.java
frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
1.思路当app调用DownloadManager的enqueue方法时,会DownloadProvider的insert方法,然后DownloadJobService执行onStartJob方法启动或取消mThread()
2.systemui中弹框会报window BadToken,可以继承SystemUIDialog
3.防止当弹框显示时,第二个下载任务调用,通过SystemProperties标志在DownloadProvider的insert方法中return或throw new 异常出去
在enqueue时发送广播A,在systemui等常驻应用上监听广播A并弹出dialog,用户验证密码,成功发送广播B 取消或失败发送广播C,在DownloadJobService中注册监听广播B执行mThread.start();, 广播C执行mThread.requestShutdown();移除下载.
参考文献:
实现调用安装PackageManagerService需要密码
/frameworks/base/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java
frameworks/base/services/core/java/com/android/server/pm/InstallPackageHelper.java
frameworks/base/services/core/java/com/android/server/pm/InstallingSession.java
frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
1.区别
未验证来源会走PackageInstallerActivity显示弹框让用户确认后通过PMS调用InstallPackageHelper
Google play不会走PackageInstallerActivity,直接创建InstallingSession后通过PMS调用InstallPackageHelper
2.安装步骤:
1):把APK的信息通过IO流的形式写入到PackageInstaller.Session中
2):调用PackageInstaller.Session的commit方法,把APK的信息交给PackageManagerService处理
3):进行Apk的Copy操作,进行安装
4):installPackagesLI方法中,以原子的方式安装一个或多个包。此操作分为四个阶段:
阶段1.Prepare准备:分析任何当前安装状态,分析包并对其进行初始验证。
阶段2.Scan 扫描:扫描分析准备阶段拿到的包
阶段3.Reconcile 协调:包的扫描结果,用于协调可能向系统中添加的一个或多个包
阶段4. Commit 提交:提交所有扫描的包并更新系统状态,这是安装流程中唯一可以修改系统状态的地方放,必须在此阶段之前确定所有的可预测的错误
阶段5.完成APK的安装
InstallingSession.start()
handleStartCopy(requests);
handleReturnCode(requests);
-->
processPendingInstall(requests)
-->
processInstallRequests( mRet == PackageManager.INSTALL_SUCCEEDED /* success */, Collections.singletonList(installRequest));
-->
processApkInstallRequests(success, installRequests)
-->
mPm.installPackagesTraced(installRequests);
for (InstallRequest request : installRequests) {
doPostInstall(request);
}
for (InstallRequest request : installRequests) {
mPm.restoreAndPostInstall(request);
}
其中的mPm就是PMS
mInstallPackageHelper.installPackagesTraced(requests);
-->
installPackagesLI(requests);
-->
preparePackageLI(request);
scanPackageTracedLI()
ReconcilePackageUtils.reconcilePackages();
commitPackagesLocked(reconciledPackages, mPm.mUserManager.getUserIds());
3.思路
在InstallPackageHelper中添加tag,及set方法,PackageManagerService.java中添加调用Helper的方法
在InstallPackageHelper.preparePackageLI中判断tag为false时抛出用户取消的异常
调用InstallingSession.start时设置tag为false,并出现弹框只有用户输入密码时tag为true.
参考文献: