我正在提示用户将PDF文件下载到设备存储中,然后发送一条通知,该通知将使用在Uri
方法中返回的相同OnActivityResult()
打开该文件。但是似乎新的Intent
无法打开此Uri
,当我单击通知时什么也没有发生。这是代码:
private fun firePushNotification() {
val intent: Intent
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
intent = Intent(Intent.ACTION_VIEW).apply {
data = uri // From OnActivityResult()
type = "application/pdf"
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
}
} else {
intent = Intent(Intent.ACTION_VIEW).apply {
data = uri
type = "application/pdf"
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}
}
// Push logic
val pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT)
val builder = NotificationCompat.Builder(context, CHANNEL_ID)
.setSmallIcon(R.drawable.app_logo)
.setContentTitle("Download concluído")
.setContentText("Abrir PDF")
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setContentIntent(pendingIntent)
.setAutoCancel(true)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(CHANNEL_ID, "Channel 1",
NotificationManager.IMPORTANCE_DEFAULT).apply {
description = ""
}
// Register the channel with the system
val notificationManager: NotificationManager =
context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationManager.createNotificationChannel(channel)
}
NotificationManagerCompat.from(context).notify(NOTIFICATION_ID, builder.build())
}
我还尝试使用带有此代码的File
创建一个uri
:
private fun firePushNotification() {
val intent: Intent
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
val input = context.contentResolver.openInputStream(uri)
val file = File(Environment.getDownloadCacheDirectory().absolutePath, pdfName)
val output = FileOutputStream(file)
copyStream(input!!, output)
intent = Intent(Intent.ACTION_VIEW).apply {
data = FileProvider.getUriForFile(context, context.packageName + ".provider", file)
type = "application/pdf"
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
}
} else {
intent = Intent(Intent.ACTION_VIEW).apply {
data = uri
type = "application/pdf"
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}
}
// Push logic ...
}
copystream()
方法:
@Throws(IOException::class)
fun copyStream(inp: InputStream, out: OutputStream) {
val buffer = ByteArray(1024)
var read: Int
while (inp.read(buffer).also { read = it } != -1) {
out.write(buffer, 0, read)
}
}
但出现错误:
Caused by: java.io.FileNotFoundException: /data/cache/my_pdf.pdf (Permission denied)
是否有另一种方式可以使用用户输入提供的uri
打开最近下载的文件?
经过测试的智能手机操作系统版本为Android10吗?从Android10开始,存储访问已更改,因此您无法访问公共存储端。
您需要对其进行修改以将其存储在私有存储中,例如,
val file = File(Environment.getDownloadCacheDirectory().absolutePath, pdfName)
结果路径:/ data / cache
而不是,
val file = File(context.cacheDir.absolutePath, pdfName)
结果路径:/ data / user / 0 / {yourPackage} / cache
Google进行此更改的原因是为了防止不必要的容量即使由于不加选择地删除了应用程序也无法填充使用公共存储。
但是,在应用程序的AndroidManifest.xml中将requestLegacyExternalStorage属性设置为true不会应用范围存储策略,如下所示:
<manifest ... >
<!-- This attribute is "false" by default on apps targeting Android Q. -->
<application android:requestLegacyExternalStorage="true" ... >
...
</application>
</manifest>