作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
(这个问题是关于 Android 11 的)
我想将崩溃日志打印到其他应用程序可以读取的文件中(具体来说,我希望能够导航到该文件并使用"file"应用程序查看数据)。
我看过很多关于这个问题的答案,但它们都存在以下两个问题之一:
Environment.getExternalStoragePublicDirectory
,或者getExternalFilesDir
,但这会返回一个对其他应用不可见的目录。请注意,我想在我的 Application
类中而不是在 Activity 中执行此操作。
根据official docs我可以将它保存为“文档”,但是那里提供的示例有问题;它是从一个 Activity 中调用的。由于我试图从应用程序调用它,方法 startActivityForResult
不存在。
// Request code for creating a PDF document.
const val CREATE_FILE = 1
private fun createFile(pickerInitialUri: Uri) {
val intent = Intent(Intent.ACTION_CREATE_DOCUMENT).apply {
addCategory(Intent.CATEGORY_OPENABLE)
type = "application/pdf"
putExtra(Intent.EXTRA_TITLE, "invoice.pdf")
// Optionally, specify a URI for the directory that should be opened in
// the system file picker before your app creates the document.
putExtra(DocumentsContract.EXTRA_INITIAL_URI, pickerInitialUri)
}
startActivityForResult(intent, CREATE_FILE) // <--- This does not compile, a subclass of Application doesn't have this method avaiable...
}
最佳答案
对于 Android 11。在你的情况下,我认为 contentResolver.insert
会更合适。
您需要使用 MediaStore.Files.getContentUri
并将您的内容值放入其中。然后使用 openOutputStream
和 outputStream.write
将您的崩溃日志写入其中。
这也可以用在 Application
类中。
以下是在 Android 11 上测试的代码 fragment 。
class MyApp : Application() {
override fun onCreate() {
super.onCreate()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
saveFileToExternalStorage(
System.currentTimeMillis().toString(),
"This is test crash log"
)
} else {
//your old code for below Q
}
}
@RequiresApi(Build.VERSION_CODES.Q)
private fun saveFileToExternalStorage(displayName: String, content: String): Boolean {
val externalUri = MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
val relativeLocation = Environment.DIRECTORY_DOCUMENTS
val contentValues = ContentValues().apply {
put(MediaStore.Files.FileColumns.DISPLAY_NAME, "$displayName.txt")
put(MediaStore.Files.FileColumns.MIME_TYPE, "application/text")
put(MediaStore.Files.FileColumns.TITLE, "Log")
put(MediaStore.Files.FileColumns.DATE_ADDED, System.currentTimeMillis() / 1000)
put(MediaStore.Files.FileColumns.RELATIVE_PATH, relativeLocation)
put(MediaStore.Files.FileColumns.DATE_TAKEN, System.currentTimeMillis())
}
return try {
contentResolver.insert(externalUri, contentValues)?.also { uri ->
contentResolver.openOutputStream(uri).use { outputStream ->
outputStream?.let {
outputStream.write(content.toByteArray())
outputStream.close()
}
}
} ?: throw IOException("Couldn't create MediaStore entry")
true
} catch (e: IOException) {
e.printStackTrace()
false
}
}
}
我从这个 github 项目中得到了这个想法。我建议你也检查一下。 https://github.com/philipplackner/AndroidStorage
关于安卓 11 : Save a file that can other apps can access,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67759437/
我是一名优秀的程序员,十分优秀!