当您阅读标题时,我正在尝试从手机下载文件夹中读取 JSON 文件。 但它一直给我错误提示,这是我在其中一个函数中实现的(获取文件路径时出错)。
这是 github 链接 https://github.com/giorgishubitidze3/Blaezar
主要功能可以在UploadFragment和viewModel中找到
编辑:我添加了这个 testPush 函数用于测试目的,它给了我 即使我授予应用程序所需的所有权限,FileNotFoundException 也会出现 EACCES(权限被拒绝)错误。 (也将它们添加到清单文件中)
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
fun testPush(){
val file =
File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS),
"ads_interests.json")
val result = file.readText()
myDataReference.setValue(result)
}
private fun openFilePicker() {
val intent = Intent(Intent.ACTION_GET_CONTENT)
intent.type = "*/*"
intent.addCategory(Intent.CATEGORY_OPENABLE)
intent.putExtra(Intent.EXTRA_MIME_TYPES, arrayOf("application/json", "application/zip"))
val tempFile = createTempFile("temp", ".json", requireContext().getExternalFilesDir(null))
val fileUri = FileProvider.getUriForFile(
requireContext(),
"${requireContext().packageName}.fileprovider",
tempFile
)
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri)
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
startActivityForResult(intent, FILE_PICK_REQUEST_CODE)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == FILE_PICK_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
data?.data?.let { uri ->
val filePath = getPathFromUri(requireActivity().application, uri)
if (filePath != null) {
view?.findViewById<TextView>(R.id.selectedItemTv)?.text =
"Selected item: $filePath"
selectedFileUri = Uri.parse("file://$filePath")
} else {
Toast.makeText(requireContext(), "Error getting file path", Toast.LENGTH_SHORT).show()
}
}
}
}
private fun getPathFromUri(application: Application, uri: Uri): String? {
var path: String? = null
try {
val cursor = application.contentResolver.query(uri, null, null, null, null)
cursor?.use {
if (it.moveToFirst()) {
val columnIndex = it.getColumnIndex(MediaStore.Images.Media.DATA)
if (columnIndex != -1) {
path = it.getString(columnIndex)
}
}
}
} catch (e: Exception) {
e.printStackTrace()
}
return path
}
fun handleFileSelection(
application: Application,
appContext: Context,
fileUri: Uri,
callback: (String) -> Unit
) {
viewModelScope.launch(Dispatchers.IO) {
val fileName = getFileName(application, fileUri)
if (fileName != null) {
callback(fileName)
}
try {
// Read the JSON file from the assets folder
val inputStream = fileName?.let { appContext.assets.open(it) }
val reader = BufferedReader(InputStreamReader(inputStream))
val jsonString = reader.use { it.readText() }
// Parse JSON using Gson
val gson = Gson()
val jsonData = gson.fromJson(jsonString, jsonData::class.java)
// Upload interests to Firebase
uploadInterests(jsonData)
} catch (e: Exception) {
e.printStackTrace()
// Handle any errors during file reading or Firebase upload
// For example, show an error message to the user
callback("Error: $e")
}
}
}
当我在 android 清单文件应用程序标记中添加 android:requestLegacyExternalStorage="true" 时,问题已得到解决
还稍微清理了代码并使其工作。
uploadButton.setOnClickListener {
openFilePicker()
}
sendButton.setOnClickListener {
if (fileNamee != null || fileNamee != " ") {
val fileName = fileNamee
fileName?.let { it1 -> viewModel.testPush(it1) }
} else {
Toast.makeText(requireContext(), "No file selected", Toast.LENGTH_SHORT).show()
}
}
private fun openFilePicker() {
val intent = Intent(Intent.ACTION_GET_CONTENT)
intent.type = "*/*"
intent.addCategory(Intent.CATEGORY_OPENABLE)
intent.putExtra(Intent.EXTRA_MIME_TYPES, arrayOf("application/json", "application/zip"))
val tempFile = createTempFile("temp", ".json", requireContext().getExternalFilesDir(null))
val fileUri = FileProvider.getUriForFile(
requireContext(),
"${requireContext().packageName}.fileprovider",
tempFile
)
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri)
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
startActivityForResult(intent, FILE_PICK_REQUEST_CODE)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == FILE_PICK_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
data?.data?.let { uri ->
val fileName = getFileNameFromUri(uri)
if (fileName != null) {
view?.let { view ->
viewModel.setFileName(fileName, view.findViewById<TextView>(R.id.selectedItemTv)
)
fileNamee=fileName
}
Toast.makeText(requireContext(), "Selected file: $fileName", Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(requireContext(), "Error getting file name", Toast.LENGTH_SHORT).show()
}
}
}
}
private fun getFileNameFromUri(uri: Uri): String? {
var fileName: String? = null
try {
val cursor = requireContext().contentResolver.query(uri, null, null, null, null)
cursor?.use {
if (it.moveToFirst()) {
val columnIndex = it.getColumnIndex(OpenableColumns.DISPLAY_NAME)
if (columnIndex != -1) {
fileName = it.getString(columnIndex)
}
}
}
} catch (e: Exception) {
e.printStackTrace()
}
return fileName
}
private val database = FirebaseDatabase.getInstance()
private val myDataReference = database.reference
fun testPush(fileName: String){
val file = File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS),
fileName)
val result = file.readText()
myDataReference.setValue(result)
}
fun setFileName(name:String, textView: TextView){
textView.text = name
}