问题描述
在我的 Android 应用程序中,我有一个重命名文件的功能。我通过在同一路径上创建一个具有新名称的新文件,然后将原始文件的内容复制到新文件来实现此功能,毕竟我删除了旧名称的文件。
这里的问题是原始文件的时间戳没有保留,重命名的文件随着重命名的时间被创建。
到目前为止我尝试过的
1- 我使用了 file.renameTo() 函数。
2-1 永远不会工作,所以我对新文件使用 setLastModified
方法并将原始文件的最后修改日期传递给它。使用 existingFile.lastModified()
获得了上次修改日期。
3- 在使用 Media Store 获取文件的功能之后,我按 DATE_MODIFIED
4- 第 3 点工作不正常,因为它一直在顶部显示带有原始文件日期的重命名文件,因此我从媒体商店中删除了按 DATE_MODIFIED
排序并尝试了 fetchedFiles.sortByDescending { it.getMFileDate() }
5- 第 4 点也有同样的问题,重命名的文件显示在顶部。
renameTo 函数使用代码无法正常工作
try {
val existingFile = File(selectedFile.getMAbsolute_path())
val separator = "."
val arrValues: Array<String> =
selectedFile.getMAbsolute_path()?.split(separator)!!.toTypedArray()
val newFileName = inputText
val newFilePath =
selectedFile.getMParent_file() + "/$newFileName.${arrValues[arrValues.size - 1]}"
val newFile = File(newFilePath)
existingFile.renameTo(newFile)
} catch (e: Exception) {
e.printStackTrace()
}
上面的代码在设备版本 8 上重命名了文件,但在 Android 版本 7 上它只是删除了文件。它不会在不同设备上显示相同的结果
以下是我当前的代码:
权限
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
<uses-permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT" />
<uses-permission android:name="com.android.launcher.permission.READ_PHONE_STATE" />
更新 [23-12-2020]
我对 proceedRenaming
函数进行了更改,首先我创建了新的文件对象,然后复制了它,之后我设置了 lastModified,最后调用了 Media Store 扫描。
这是正确的调用层次结构。它适用于大于或等于 Android 版本 8 (OREO) 的设备。
我发现 setLastModified
函数在 Android 版本 8 (OREO) 以下的设备上不起作用。它不断将当前日期设置为新文件。
重命名函数
private fun proceedRenaming(
context: Context,selectedFile: MyFileModel,positionOfDeleted: Int,inputText: String,isFileShortcutCreated: Boolean
) {
try {
//delete shortcut if exists
deleteFileShortCut(context,selectedFile,positionOfDeleted)
val existingFile = File(selectedFile.getMAbsolute_path())
val separator = "."
val arrValues: Array<String> =
selectedFile.getMAbsolute_path()?.split(separator)!!.toTypedArray()
val newFileName = inputText
val newFilePath = selectedFile.getMParent_file() + "/$newFileName.${arrValues[arrValues.size - 1]}"
val newFile = File(newFilePath)
copy(existingFile,newFile)
//print the original last modified date
val sdf = SimpleDateFormat("MM/dd/yyyy")
val date1 = "" + sdf.format(existingFile.lastModified())
Log.d("Origina Date :",date1)
//set this date
//need convert the above date to milliseconds in long value
val newDate: Date = sdf.parse(date1)
newFile.setLastModified(newDate.time)
//print the latest last modified date
val date2 = "" + sdf.format(newFile.lastModified())
Log.i("Lastest Date : ",date2)
context?.sendBroadcast(
Intent(
Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,Uri.fromFile(newFile)
)
)
if (existingFile.exists()) {
existingFile.delete()
existingFile.canonicalFile.delete()
if (existingFile.exists()) {
BaseApplication.applicationContext()
.deleteFile(existingFile.getName())
}
}
MediaScannerConnection.scanFile(
context,arrayOf<String>(selectedFile.getMAbsolute_path().toString()),null
) { path,uri ->
Log.i("ExternalStorage","Scanned $path:")
Log.i("ExternalStorage","-> uri=$uri")
context?.contentResolver
?.delete(uri,null,null)
}
selectedFile.setOldFileName(selectedFile.getMFile_name()!!)
selectedFile.setOldFileParentFileh(selectedFile.getMParent_file()!!)
selectedFile.setOldFilePath(selectedFile.getMAbsolute_path()!!)
selectedFile.setMAbsolute_path(newFilePath)
selectedFile.setMFile_name(newFileName)
selectedFile.setPosition(positionOfDeleted)
renamedFile.postValue(selectedFile)
if (isFileShortcutCreated) {
createFileShortCut(context,positionOfDeleted)
}
} catch (e: Exception) {
e.printStackTrace()
Toast.makeText(
context,context?.getString(R.string.text_rename_error),Toast.LENGTH_SHORT
).show()
}
}
复制功能
@Throws(IOException::class)
fun copy(src: File?,dst: File?) {
val inStream = FileInputStream(src)
val outStream = FileOutputStream(dst)
val inChannel: FileChannel = inStream.getChannel()
val outChannel: FileChannel = outStream.getChannel()
inChannel.transferTo(0,inChannel.size(),outChannel)
inStream.close()
outStream.close()
}
我从 MediaStore 获取文件的功能
private fun readFiles(
args: Array<String?>,where: String
): ArrayList<MyFileModel> {
val fetchedFiles = ArrayList<MyFileModel>()
var fileCursorExternal: Cursor? = null
var fileCursorInternal: Cursor? = null
try {
//Tables
val tableExternal = MediaStore.Files.getContentUri("external")
val tableInternal = MediaStore.Files.getContentUri("internal")
//Column
val column = arrayOf(
MediaStore.Files.FileColumns.DATE_ADDED,MediaStore.MediaColumns.DATA,MediaStore.MediaColumns.TITLE,MediaStore.MediaColumns.SIZE,MediaStore.Files.FileColumns.DATE_MODIFIED
)
//Sort by date
val orderBy = MediaStore.Files.FileColumns.DATE_MODIFIED
fileCursorExternal = context.contentResolver.query(
tableExternal,column,where,args,"$orderBy DESC"
)
while (fileCursorExternal!!.moveToNext()) {
fetchedFiles.add(setMyFileModel(fileCursorExternal))
}
fileCursorInternal = context.contentResolver.query(
tableInternal,"$orderBy DESC"
)
while (fileCursorInternal!!.moveToNext()) {
fetchedFiles.add(setMyFileModel(fileCursorInternal))
}
} catch (ex: java.lang.Exception) {
ex.printStackTrace()
} finally {
fileCursorExternal?.close()
fileCursorInternal?.close()
}
//fetchedFiles.sortByDescending { it.getMFileDate() } //commented as not working
return fetchedFiles
}
将游标数据转化为MyFileModel类对象的函数
private fun setMyFileModel(cursor: Cursor): MyFileModel {
val MyFileModel = MyFileModel()
if (cursor != null) {
try {
MyFileModel.setMFileDate(
getReadableDate(
cursor.getLong(
cursor.getColumnIndexOrThrow(
MediaStore.Files.FileColumns.DATE_MODIFIED
)
)
)
)
MyFileModel.setMAbsolute_path(
cursor.getString(
cursor.getColumnIndexOrThrow(
MediaStore.MediaColumns.DATA
)
)
)
MyFileModel.setMFile_name(
cursor.getString(
cursor.getColumnIndexOrThrow(
MediaStore.MediaColumns.TITLE
)
)
)
MyFileModel.setMFile_size(
getReadableSize(
cursor.getLong(
cursor.getColumnIndexOrThrow(
MediaStore.MediaColumns.SIZE
)
)
)
)
MyFileModel.setFileType(getFileType(MyFileModel.getMAbsolute_path()).name)
if (MyFileModel.getMAbsolute_path() != null) {
val file = File(MyFileModel.getMAbsolute_path())
MyFileModel.setMParent_file(file.parent)
}
} catch (ex: Exception) {
ex.printStackTrace()
}
}
return MyFileModel
}
长日期转字符串函数
private fun getReadableDate(dateVal: Long): String {
try {
var date = dateVal
date *= 1000L
return SimpleDateFormat("dd MMM yyyy").format(Date(date))
} catch (ex: Exception) {
ex.printStackTrace()
}
return ""
}
所需输出
1- 重命名文件时,应创建新文件,应删除旧文件。
2- 新文件应该有旧文件的时间戳,这样排序就不会受到干扰。
我可以尝试什么来解决这个问题?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)