英文:
Android app fails to write to downloads directory: java.io.FileNotFoundException (Permission denied)
问题
我有一个旧的应用程序,使用以下代码行将一个APK文件下载到设备的下载目录:
File downloadsDirectory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
File outputFile = new File(downloadsDirectory, "appname.apk");
FileOutputStream fileOutputStream = new FileOutputStream(outputFile);
// ...
我不确定这些代码行是否曾经起作用过,但根据客户的说法,它确实起作用过。因此,现在我需要维护该应用程序,并且我必须找出一种使其再次工作的方法。使用上述代码,我收到以下错误消息:
E/my.appname.services.UpdateService: 下载最新版本失败
my.appname.exceptions.NetworkException: java.io.FileNotFoundException: /storage/emulated/0/Download/appname.apk(权限被拒绝)
at my.appname.services.UpdateRepository.download(UpdateRepository.java:89)
at my.appname.services.UpdateService.onUpdateFound(UpdateService.java:78)
at my.appname.services.UpdateService.checkForUpdates(UpdateService.java:61)
at my.appname.services.UpdateService.onHandleIntent(UpdateService.java:48)
at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:68)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.os.HandlerThread.run(HandlerThread.java:65)
Caused by: java.io.FileNotFoundException: /storage/emulated/0/Download/appname.apk(权限被拒绝)
at java.io.FileOutputStream.open0(Native Method)
at java.io.FileOutputStream.open(FileOutputStream.java:287)
at java.io.FileOutputStream.<init>(FileOutputStream.java:223)
at java.io.FileOutputStream.<init>(FileOutputStream.java:171)
at my.appname.services.UpdateRepository.download(UpdateRepository.java:81)
at my.appname.services.UpdateService.onUpdateFound(UpdateService.java:78)
at my.appname.services.UpdateService.checkForUpdates(UpdateService.java:61)
at my.appname.services.UpdateService.onHandleIntent(UpdateService.java:48)
at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:68)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.os.HandlerThread.run(HandlerThread.java:65)
考虑到该应用程序非常旧,我立即怀疑缺少某些权限,的确在清单文件中没有android.permission.WRITE_EXTERNAL_STORAGE
和android.permission.READ_EXTERNAL_STORAGE
的条目。但即使在添加了这些权限后,我仍然收到相同的错误消息。
有什么想法,还需要什么其他内容才能访问下载目录?
英文:
I've got an old app that uses the following lines to download an APK into the devices downloads directory:
File downloadsDirectory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
File outputFile = new File(downloadsDirectory, "appname.apk");
FileOutputStream fileOutputStream = new FileOutputStream(outputFile);
// ...
I don't know for sure if those lines ever worked, but according to the client it did. So, now I'm stuck with maintaining that app and I'll have to figure out a way to make it working again. With the above lines I get the following error message:
E/my.appname.services.UpdateService: downloading of latest release failed
my.appname.exceptions.NetworkException: java.io.FileNotFoundException: /storage/emulated/0/Download/appname.apk (Permission denied)
at my.appname.services.UpdateRepository.download(UpdateRepository.java:89)
at my.appname.services.UpdateService.onUpdateFound(UpdateService.java:78)
at my.appname.services.UpdateService.checkForUpdates(UpdateService.java:61)
at my.appname.services.UpdateService.onHandleIntent(UpdateService.java:48)
at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:68)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.os.HandlerThread.run(HandlerThread.java:65)
Caused by: java.io.FileNotFoundException: /storage/emulated/0/Download/appname.apk (Permission denied)
at java.io.FileOutputStream.open0(Native Method)
at java.io.FileOutputStream.open(FileOutputStream.java:287)
at java.io.FileOutputStream.<init>(FileOutputStream.java:223)
at java.io.FileOutputStream.<init>(FileOutputStream.java:171)
at my.appname.services.UpdateRepository.download(UpdateRepository.java:81)
at my.appname.services.UpdateService.onUpdateFound(UpdateService.java:78) 
at my.appname.services.UpdateService.checkForUpdates(UpdateService.java:61) 
at my.appname.services.UpdateService.onHandleIntent(UpdateService.java:48) 
at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:68) 
at android.os.Handler.dispatchMessage(Handler.java:105) 
at android.os.Looper.loop(Looper.java:164) 
at android.os.HandlerThread.run(HandlerThread.java:65) 
Given that the app is quite old, I immediately suspected some missing permissions and indeed there was no android.permission.WRITE_EXTERNAL_STORAGE
and android.permission.READ_EXTERNAL_STORAGE
entires in the manifest. But even after adding those I still get the same error message.
Any ideas, what else might be missing to get access to the downloads directory?
答案1
得分: 2
如上面的评论所述,我将引用它作为答案:
> 如果您正在运行 Android 6.0 Marshmallow(API 23)或更高版本,则应请求运行时权限。
英文:
As comment above I will quote it as answer
> If you are running on Android 6.0 Marshmallow (API 23) and a above you
> should request runtime permission
答案2
得分: 2
请确保在您的清单文件中添加 requestLegacyExternalStorage = true
,如果您的目标是 Android 10 或更高版本,则可以临时选择退出受限存储。
英文:
And remember to add requestLegacyExternalStorage = true in your Manifest if you target Android 10 or higher to temporarily opt-out of scoped storage
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论