協載安裝新版 APK 時提示「應用程序未安裝」,但先卸載舊版再安裝則正常。簽名一致,版本號升級 (1000 → 1001)。
| 原因 | 檢查方法 | 解決方案 |
|---|---|---|
| 簽名不一致 (最常見) | 1. apksigner verify --print-certs old.apk new.apk 對比2. 打包流程是否切換了 keystore/密鑰/別名 | 確保同一 keystore、同一別名、同一密碼打包。CI/CD 環境檢查密鑰注入。 |
| versionCode 未遞增 | aapt dump badging new.apk | grep versionCode | versionCode 必須嚴格大於舊版 (整數)。versionName 可任意。 |
| 包名變更 | 對比 package 屬性 | 包名必須完全一致,區分大小寫。 |
| Android 6.0+ (API 23) 安裝權限 | 目標設備 Android 版本 | 安裝意圖添加 FLAG_GRANT_READ_URI_PERMISSION,或使用 FileProvider 生成 content:// URI,禁用 file://。 |
| 存儲路徑/文件損壞 | 下載完成後校驗 MD5/SHA1 | 下載完成驗證校驗和,確保文件完整。 |
| 應用未正常卸載 (殘留數據) | adb shell pm list packages | grep pkg 顯示仍存在 | adb uninstall pkg 徹底卸載,或用戶手動設置→應用→卸載。 |
| minSdkVersion / targetSdkVersion 不兼容 | 新版 manifest 對比 | 新版 minSdkVersion 不能大於設備 API;targetSdkVersion 升級可能觸發新權限要求。 |
| 同一設備多用戶/工作空間 | 設備為工作模式或多用戶 | 當前用戶未安裝但其他用戶/工作空間已安裝,導致包名衝突。 |
public static void installApk(Context context, File apkFile) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Uri uri;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { // 7.0+
// 必須用 FileProvider 生成 content:// URI
uri = FileProvider.getUriForFile(context,
context.getPackageName() + ".fileprovider", apkFile);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
} else {
uri = Uri.fromFile(apkFile); // 7.0 以下可用 file://
}
intent.setDataAndType(uri, "application/vnd.android.package-archive");
context.startActivity(intent);
}
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="https://schemas.android.com/apk/res/android">
<files-path name="apks" path="apks/"/> <!-- Context.getFilesDir()/apks -->
<cache-path name="apks_cache" path="apks/"/> <!-- Context.getCacheDir()/apks -->
<external-files-path name="apks_ext" path="apks/"/> <!-- getExternalFilesDir()/apks -->
</paths>
<!-- AndroidManifest.xml -->
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
PackageManager / PackageInstaller 具體錯誤碼 (如 INSTALL_FAILED_VERSION_DOWNGRADE, INSTALL_FAILED_UPDATE_INCOMPATIBLE)。adb install -r new.apk 直接推送安裝,觀察輸出錯誤信息,排除代碼邏輯問題。