Kotlin中点击通知打开PDF文件失败,求解决方案
解决通知点击无法打开PDF文件的问题
Android 7.0(API 24)及以上系统限制了跨应用的file:// URI访问,直接用Uri.fromFile()生成的URI会导致PDF查看器等外部应用没有权限读取文件,因此弹出“无法打开文件”的提示。必须使用FileProvider生成content://格式的安全URI来共享文件,具体解决步骤如下:
步骤1:在AndroidManifest.xml注册FileProvider
在<application>标签内添加以下配置:
<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>
步骤2:创建文件路径配置文件
在res/xml目录下新建file_paths.xml文件(若xml目录不存在则手动创建),根据你的PDF存储目录填写对应配置:
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 示例:文件存储在APP外部私有下载目录 --> <external-files-path name="downloads" path="Download/" /> <!-- 若文件存放在公共外部存储,可使用: <external-path name="external_files" path="." /> --> </paths>
注:
path字段为文件所在的相对路径,需和你的实际存储路径匹配。
步骤3:修改NotificationUtil工具类
核心修改点:替换URI生成方式、合并Intent Flags、适配Android 12+的PendingIntent Flags:
object NotificationUtil { private const val CHANNEL_ID = "download_notification_channel" private var NOTIFICATION_ID = 123 fun showNotification(context: Context, file: File, typeFile: String) { val channel = NotificationChannel( CHANNEL_ID, "Descargas", NotificationManager.IMPORTANCE_DEFAULT ) val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager notificationManager.createNotificationChannel(channel) // 使用FileProvider生成安全的content:// URI val fileUri = FileProvider.getUriForFile( context, "${context.packageName}.fileprovider", // 与Manifest中配置的authorities保持一致 file ) val intent = Intent(Intent.ACTION_VIEW) intent.setDataAndType(fileUri, typeFile) // 合并Flags,避免覆盖原有配置 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) val pendingIntentFlags = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { PendingIntent.FLAG_CANCEL_CURRENT or PendingIntent.FLAG_IMMUTABLE } else { PendingIntent.FLAG_CANCEL_CURRENT } val pendingIntent = PendingIntent.getActivity(context, 0, intent, pendingIntentFlags) val builder = NotificationCompat.Builder(context, CHANNEL_ID) .setContentTitle(file.name) .setContentText("Se completó la descarga") .setSmallIcon(R.drawable.download) .setPriority(NotificationCompat.PRIORITY_HIGH) .setContentIntent(pendingIntent) .setAutoCancel(true) notificationManager.notify(NOTIFICATION_ID++, builder.build()) } }
关键注意事项
- 确保传入的
typeFile为PDF正确的MIME类型:"application/pdf" - 调用前可通过
file.exists()验证文件是否存在 - Android 12及以上必须指定PendingIntent的
FLAG_IMMUTABLE或FLAG_MUTABLE,此处使用FLAG_IMMUTABLE即可
内容的提问来源于stack exchange,提问作者Mauricio Carmen Liñan
相关产品推荐
相关产品推荐

