應用內需打開 PDF 檔案,但用戶裝置可能未安裝 PDF 閱讀器。理想流程:檢測是否存在可處理 application/pdf 的 Activity → 若無則引導用戶下載安裝(如 Adobe Reader)→ 安裝完成後自動打開目標 PDF。
File file = new File("/sdcard/sample.pdf");
PackageManager pm = getPackageManager();
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file), "application/pdf");
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
// 查詢所有能處理該 Intent 的 Activity
List<ResolveInfo> activities = pm.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
if (activities.isEmpty()) {
// 無 PDF 閱讀器,引導安裝
promptInstallPdfReader();
} else {
// 有閱讀器,直接啟動
startActivity(Intent.createChooser(intent, "選擇 PDF 閱讀器"));
}
此法比單純檢查包名更可靠,因為用戶可能安裝了非 Adobe 的 PDF 應用(如 Google PDF Viewer、WPS Office 等)。
無法直接「靜默安裝」第三方 APK(需系統簽名權限)。標準做法是跳轉應用商店或官網下載頁:
private void promptInstallPdfReader() {
new AlertDialog.Builder(this)
.setTitle("未找到 PDF 閱讀器")
.setMessage("是否前往應用商店下載 Adobe Acrobat Reader?")
.setPositiveButton("前往下載", (dialog, which) -> {
// 方案 A:Google Play 商店頁面(需裝置有 Play Store)
Uri marketUri = Uri.parse("market://details?id=com.adobe.reader");
Intent marketIntent = new Intent(Intent.ACTION_VIEW, marketUri);
marketIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(marketIntent);
// 方案 B:官網 APK 直鏈(需處理未知來源安裝權限)
// String apkUrl = "https://get.adobe.com/reader/otherversions/...";
// downloadAndInstallApk(apkUrl);
})
.setNegativeButton("取消", null)
.show();
}
若需應用內直接下載 APK,需處理:
REQUEST_INSTALL_PACKAGES 權限(Android 8.0+)。DownloadManager 或 OkHttp 下載至 getExternalFilesDir()。FileProvider 生成 content:// URI,調用 Intent.ACTION_INSTALL_PACKAGE 安裝。// 核心安裝代碼片段(Android 7.0+ 需 FileProvider)
File apkFile = new File(getExternalFilesDir(null), "AdobeReader.apk");
Uri apkUri = FileProvider.getUriForFile(this, getPackageName() + ".provider", apkFile);
Intent installIntent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
installIntent.setData(apkUri);
installIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(installIntent);
Intent.createChooser),尊重用戶偏好。MediaStore 或應用專屬目錄管理 PDF 檔案。