在Android上安装apk往往有多种方式,但对于一般的操作来说有两种:1,通过U盘点击安装;2,通过网站、应用市场安装。
第一种安装方式会提示:“来历不明的应用会损坏。。。”,点击继续安装,才能进行下一步操作。
第二种安装方式会提示:“出于安全。。。”,需要在设置->应用 把对应的应用的未知来源应用设置为允许,才能继续安装。
跟踪安装Apk时的logcat输出,发现上面所描述的弹窗处理的代码在:frameworks/base/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java
主要触发函数如下图

第一情况是由于此次安装没有发起方,引起了DLG_ANONYMOUS_SOURCE,继续深入解读代码,发现下一步仅仅是提示弹窗,并根据客户操作来确定是否继续安装,改法就比较简单,不弹窗直接安装即可。
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.ja
va
@@ -196,7 +196,10 @@ public class PackageInstallerActivity extends AlertActivity {
case DLG_EXTERNAL_SOURCE_BLOCKED:
return ExternalSourcesBlockedDialog.newInstance(mOriginatingPackage);
case DLG_ANONYMOUS_SOURCE:
- return AnonymousSourceDialog.newInstance();
+ //return AnonymousSourceDialog.newInstance();
+ mAllowUnknownSources = true;
+ initiateInstall();
+ break;
}
return null;
}
第二种情况是由于安装发起方没有打开允许权限(可在 设置->应用 中的对应应用查看)导致的ExternalSourcesBlockedDialog,继续往下看代码流程,弹窗提示 “出于安全考虑,目前已禁止您的平板电脑安装来自此来源的未知应用。您可以在“设置”中对此进行更改。”,点击确定的话,会通过(ACTION_MANAGE_UNKNOWN_APP_SOURCES = "android.settings.MANAGE_UNKNOWN_APP_SOURCES")打开权限设置界面(packages/apps/Settings/AndroidManifest.xml 中关联内容如下图,有兴趣可以去研究代码)。

这种情况的改法也比较粗暴,无非就是自动赋予允许权限,直接上代码(参考packages/apps/Settings 中打开允许权限):
@@ -514,10 +517,29 @@ public class PackageInstallerActivity extends AlertActivity {
// Shouldn't use static constant directly, see b/65534401.
final int appOpCode =
AppOpsManager.permissionToOpCode(Manifest.permission.REQUEST_INSTALL_PACKAGES);
- final int appOpMode = mAppOpsManager.noteOpNoThrow(appOpCode, mOriginatingUid,
+ int appOpMode = mAppOpsManager.noteOpNoThrow(appOpCode, mOriginatingUid,
mOriginatingPackage, mCallingAttributionTag,
"Started package installation activity");
if (mLocalLOGV) Log.i(TAG, "handleUnknownSources(): appMode=" + appOpMode);
+
+ if(AppOpsManager.MODE_ALLOWED != appOpMode){
+ try {
+ PackageManager mPm = this.getPackageManager();
+ PackageInfo mPackageInfo = mPm.getPackageInfo(mOriginatingPackage,
+ PackageManager.MATCH_DISABLED_COMPONENTS |
+ PackageManager.MATCH_ANY_USER |
+ PackageManager.GET_SIGNATURES |
+ PackageManager.GET_PERMISSIONS);
+ mAppOpsManager.setMode(AppOpsManager.OP_REQUEST_INSTALL_PACKAGES,
+ mPackageInfo.applicationInfo.uid, mOriginatingPackage, AppOpsManager.MODE_ALLOWED);
+ } catch(NameNotFoundException e) {
+ Log.e(TAG, "Exception:" + e);
+ }
+ }
+
+ appOpMode = mAppOpsManager.noteOpNoThrow(appOpCode, mOriginatingUid,
+ mOriginatingPackage, mCallingAttributionTag,
+ "Started package installation activity");
switch (appOpMode) {
case AppOpsManager.MODE_DEFAULT:
mAppOpsManager.setMode(appOpCode, mOriginatingUid,
~