在授予权限的 android sdcard 上创建文件时出现 IO 异常
IO exception while creating file on android sdcard with permissions granted
我正在尝试将文件从内部 phone 内存移动到 SD 卡。
val oldFile = File(oldPath) //oldPath is string
val newFile = File(newPath) //newPath is string
if(newFile.exists()) {
newFile.delete()
}
newFile.parentFile.mkdirs()
newFile.createNewFile() //crashes here
// copy file code
路径是绝对的。
旧文件路径为:
/storage/emulated/0/Android/data/com.package/files/2ec37ce3-ca72-4a35-a6e6-2d7f8e864c6c
新文件路径为:
/storage/48EE-C144/chosenDirectory/2ec37ce3-ca72-4a35-a6e6-2d7f8e864c6c
其中 2ec37ce3-ca72-4a35-a6e6-2d7f8e864c6c
是文件。
路径正确,新文件路径由用户使用外部目录选择器库手动选择,效果很好。
当然,应用程序会要求用户提供权限,并且在未授予权限之前不会将用户传递给应用程序。
int perm = this.checkSelfPermission(permission.WRITE_EXTERNAL_STORAGE);
int perm2 = this.checkSelfPermission(permission.READ_EXTERNAL_STORAGE);
if (perm != PackageManager.PERMISSION_GRANTED || perm2 != PackageManager.PERMISSION_GRANTED) {
/*ask for permissions and show explain dialog*/
}
清单中的权限也已添加。
调用 newFile.createNewFile()
时应用程序崩溃,异常日志:
05-07 13:02:14.995 14004-14004/com.packagename E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.packagename, PID: 14004
java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1451)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1563)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1451)
Caused by: java.io.IOException: Permission denied
at java.io.UnixFileSystem.createFileExclusively0(Native Method)
at java.io.UnixFileSystem.createFileExclusively(UnixFileSystem.java:280)
at java.io.File.createNewFile(File.java:948)
at com.packagename.backend.localApi.changePath.PathChanger.changePath(PathChanger.kt:29)
at com.packagename.backend.localApi.changePath.PathChangeService$changePath.onSelect(PathChangeService.kt:49)
at com.codekidlabs.storagechooser.fragments.ChooserDialogFragment.onItemClick(ChooserDialogFragment.java:169)
at android.widget.AdapterView.performItemClick(AdapterView.java:343)
at android.widget.AbsListView.performItemClick(AbsListView.java:1665)
at android.widget.AbsListView$PerformClick.run(AbsListView.java:4075)
at android.widget.AbsListView.run(AbsListView.java:6552)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6816)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1563)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1451)
需要在AndroidManifest.xml文件中添加权限。
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
我的解决方案是停止使用 java 类 并迁移到 Storage Access Framework
我正在尝试将文件从内部 phone 内存移动到 SD 卡。
val oldFile = File(oldPath) //oldPath is string
val newFile = File(newPath) //newPath is string
if(newFile.exists()) {
newFile.delete()
}
newFile.parentFile.mkdirs()
newFile.createNewFile() //crashes here
// copy file code
路径是绝对的。
旧文件路径为:
/storage/emulated/0/Android/data/com.package/files/2ec37ce3-ca72-4a35-a6e6-2d7f8e864c6c
新文件路径为:
/storage/48EE-C144/chosenDirectory/2ec37ce3-ca72-4a35-a6e6-2d7f8e864c6c
其中 2ec37ce3-ca72-4a35-a6e6-2d7f8e864c6c
是文件。
路径正确,新文件路径由用户使用外部目录选择器库手动选择,效果很好。
当然,应用程序会要求用户提供权限,并且在未授予权限之前不会将用户传递给应用程序。
int perm = this.checkSelfPermission(permission.WRITE_EXTERNAL_STORAGE);
int perm2 = this.checkSelfPermission(permission.READ_EXTERNAL_STORAGE);
if (perm != PackageManager.PERMISSION_GRANTED || perm2 != PackageManager.PERMISSION_GRANTED) {
/*ask for permissions and show explain dialog*/
}
清单中的权限也已添加。
调用 newFile.createNewFile()
时应用程序崩溃,异常日志:
05-07 13:02:14.995 14004-14004/com.packagename E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.packagename, PID: 14004
java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1451)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1563)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1451)
Caused by: java.io.IOException: Permission denied
at java.io.UnixFileSystem.createFileExclusively0(Native Method)
at java.io.UnixFileSystem.createFileExclusively(UnixFileSystem.java:280)
at java.io.File.createNewFile(File.java:948)
at com.packagename.backend.localApi.changePath.PathChanger.changePath(PathChanger.kt:29)
at com.packagename.backend.localApi.changePath.PathChangeService$changePath.onSelect(PathChangeService.kt:49)
at com.codekidlabs.storagechooser.fragments.ChooserDialogFragment.onItemClick(ChooserDialogFragment.java:169)
at android.widget.AdapterView.performItemClick(AdapterView.java:343)
at android.widget.AbsListView.performItemClick(AbsListView.java:1665)
at android.widget.AbsListView$PerformClick.run(AbsListView.java:4075)
at android.widget.AbsListView.run(AbsListView.java:6552)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6816)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1563)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1451)
需要在AndroidManifest.xml文件中添加权限。
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
我的解决方案是停止使用 java 类 并迁移到 Storage Access Framework