我有一个Android Kotlin应用程序。我正在使用API 27+。我的应用程序中生成了一个.csv文件。我正试图将这个应用程序创建的.csv文件写入android设备";文件";应用程序。
我可以在应用程序的缓存目录中创建文件。缓存文件看起来很棒!
当我使用意图来编写Files应用程序时;文件";文件已创建,但为空。
我需要更改什么才能将我的应用程序的.csv文件复制到";文件";有数据的应用程序?如果CREATE_DOCUMENT是错误的意图,哪一个是正确的?如果我更改意向类型,我需要对清单/等级进行哪些更改才能共享数据。
在我的应用程序中创建伪.csv文件的代码:
private fun downloadFile() {
val CSV_HEADER = "id,name,address,age"
val myToyBoxFile = File.createTempFile("MyToyBox", ".csv")
var fileWriter: FileWriter? = null
try {
fileWriter = FileWriter(myToyBoxFile)
fileWriter.append(CSV_HEADER)
fileWriter.append('n')
fileWriter.append("aaaaa")
fileWriter.append(',')
fileWriter.append("bbbbb")
fileWriter.append(',')
fileWriter.append("cccccc")
fileWriter.append(',')
fileWriter.append("dddddd")
fileWriter.append('n')
println("Write CSV successfully!")
} catch (e: Exception) {
println("Writing CSV error!")
e.printStackTrace()
}
fileWriter!!.close()
val uriForFile = Uri.fromFile(myToyBoxFile)
createFile(uriForFile)
}
意向代码。
val CREATE_FILE = 1
private fun createFile(pickerInitialUri: Uri) {
val intent = Intent(Intent.ACTION_CREATE_DOCUMENT).apply {
putExtra(Intent.EXTRA_STREAM, pickerInitialUri)
addCategory(Intent.CATEGORY_OPENABLE)
type = "text/csv"
putExtra(Intent.EXTRA_TITLE, "myToyBox.csv")
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
}
startActivityForResult(intent, CREATE_FILE)
}
我没有集成到"Files"应用程序,但我确实访问了"共享";允许我通过电子邮件发送文件。
大部分是安卓页面及其链接以及许多堆叠页面安卓安全Fiile共享
高级
- 将提供者添加到清单中
- 添加res->xml->具有文件共享"路径"位置的file_path文档
- 编写代码以使用"路径"位置共享文件
详细步骤
-
更新清单->带有"提供商"详细信息的应用程序部分
<显示。。。<应用。。。
<category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <provider android:name="androidx.core.content.FileProvider" android:authorities="com.com.YOURDOMAIN.YOURAPP.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider>
-
添加res->xml->具有文件共享"路径"位置的file_path文档
如果你在res位置(即布局所在的位置(下还没有xml目录/包,请添加它并添加一个文件。我称之为file_paths。根据你已经编码的内容,你可能已经有了一个。我写了我的文档以共享到docs/文件夹。实际代码中需要这个位置。
docs/位于File(requireContext().filesDir, "docs")
docs/位于data/data/com.YOURDOMAIN.YOURAPP/files/docs
下的模拟器中
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<files-path name="my_docs" path="docs/"/>
</paths>
编写代码以使用"路径"位置和文件提供程序引用共享文件
私人娱乐下载文件(({
val filePath: File = File(requireContext().filesDir, "docs") filePath.mkdirs() val newFile = File(filePath, "MyToyBox.csv") newFile.delete() newFile.createNewFile() val contentUri = FileProvider.getUriForFile( requireContext(), "com.YOURDOMAIN.YOURAP.fileprovider", newFile ) val CSV_HEADER = "Series,My Toy Box ID,Debut Year,Phase,Wave,Action Figure Package Name," + "Movie Scene," + "Estimated New Value,Have the New Figure,Have New Count," + "Want the New Figure,Want New Count," + "Sell the New Figure,Sell New Count," + "Order the New Figure,Order New Count," + "Order from Text," + "Have the Loose Figure,Have Loose Count" + ",Want the Loose Figure,Want Loose Count" + ",Sell the Loose Figure,Sell Loose Count" + ",Notes" + "n" var fileWriter: FileWriter? = null try { fileWriter = FileWriter(newFile) fileWriter.append(CSV_HEADER) figureList.forEach { figure -> val specifics = figure.specifics val noText = "No" val yesText = "Yes" val new_haveCount = specifics.new_haveCount.toString() val new_wantCount = specifics.new_wantCount.toString() val new_sellCount = specifics.new_sellCount.toString() val new_orderCount = specifics.new_orderCount.toString() val new_orderText = specifics.new_orderText val loose_haveCount = specifics.loose_haveCount.toString() val loose_wantCount = specifics.loose_wantCount.toString() val loose_sellCount = specifics.loose_sellCount.toString() // set yes/no text based on count val new_haveTheFigure = if (specifics.new_haveCount == 0) noText else yesText val new_wantTheFigure = if (specifics.new_wantCount == 0) noText else yesText val new_sellTheFigure = if (specifics.new_sellCount == 0) noText else yesText val new_orderTheFigure = if (specifics.new_orderCount == 0) noText else yesText val loose_haveTheFigure = if (specifics.loose_haveCount == 0) noText else yesText val loose_wantTheFigure = if (specifics.loose_wantCount == 0) noText else yesText val loose_sellTheFigure = if (specifics.loose_sellCount == 0) noText else yesText val notes = specifics.notes // formatted value var newValueString = kUnknownMTBValue val currencyFormat = NumberFormat.getCurrencyInstance() currencyFormat.maximumFractionDigits = 2 currencyFormat.currency = Currency.getInstance("USD") if (figure.saleSummary != null) { val formattedValue = currencyFormat.format(figure.saleSummary!!.estimatedValueMean).toString() newValueString = context?.getString(R.string.saleSummaryValueCount, formattedValue, figure.saleSummary!!.saleCount).toString() } // need to escape , with " in front and back, such as in wave and names. val row: String = ""${figure.series.seriesName}"," + "${figure.figureUniqueId}," + "${figure.debutYear}," + ""${figure.phase}"," + ""${figure.wave}"," + ""${figure.figurePackageName}"," + ""${figure.scene}"," + ""$newValueString"," + "$new_haveTheFigure,$new_haveCount," + "$new_wantTheFigure,$new_wantCount," + "$new_sellTheFigure,$new_sellCount," + "$new_orderTheFigure,$new_orderCount," + ""$new_orderText"" + ",$loose_haveTheFigure,$loose_haveCount," + "$loose_wantTheFigure,$loose_wantCount," + "$loose_sellTheFigure,$loose_sellCount," + ""$notes"" + "n" fileWriter.append(row) } } catch (e: Exception) { println("Writing CSV error!") e.printStackTrace() } fileWriter!!.close() createFile(contentUri)
}
private fun createFile(pickerInitialUri:Uri({
val shareIntent: Intent = Intent().apply { action = Intent.ACTION_SEND putExtra(Intent.EXTRA_STREAM, pickerInitialUri) type = "text/plain" setDataAndType(pickerInitialUri, requireContext().contentResolver.getType(pickerInitialUri)) } startActivity(Intent.createChooser(shareIntent, "My Toy Box"))
}