I'm experiencing some interesting behavior on a few Android 11 devices in regards to reading and writing to external storage. I know some changes were implemented with Android 10/11 in regards to storage but I was under the assumption than an app could access it's own app-specific directories (internal and external) without incident. Any suggestions are welcome.
Device #1: Throws the EPERM Error (Operation Not permitted) when writing to the removable external storage card with the following code:
val externalDirectories = applicationContext.getExternalFilesDirs(null)
externalFile =
File(externalDirectories[1].path + "/sampletextfile.txt")
externalFile.writeText("sample text")
Here's the stack trace:
java.io.IOException: close failed: EPERM (Operation not permitted) at libcore.io.IoBridge.closeAndSignalBlockedThreads(IoBridge.java:254) at java.io.FileOutputStream.close(FileOutputStream.java:431) at java.io.FileOutputStream.finalize(FileOutputStream.java:500) at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:291) at java.lang.Daemons$FinalizerDaemon.runInternal(Daemons.java:278) at java.lang.Daemons$Daemon.run(Daemons.java:139) at java.lang.Thread.run(Thread.java:923) Caused by: android.system.ErrnoException: close failed: EPERM (Operation not permitted) at libcore.io.Linux.close(Native Method) at libcore.io.ForwardingOs.close(ForwardingOs.java:88) at libcore.io.BlockGuardOs.close(BlockGuardOs.java:110) at libcore.io.ForwardingOs.close(ForwardingOs.java:88) at libcore.io.IoBridge.closeAndSignalBlockedThreads(IoBridge.java:252) at java.io.FileOutputStream.close(FileOutputStream.java:431) at java.io.FileOutputStream.finalize(FileOutputStream.java:500) at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:291) at java.lang.Daemons$FinalizerDaemon.runInternal(Daemons.java:278) at java.lang.Daemons$Daemon.run(Daemons.java:139) at java.lang.Thread.run(Thread.java:923)
Device #2: It is able to perform the above code successfully but cannot provide a list of files from a directory. The code below always yields false:
externalDirectories[1].canRead()
Also, and to add, the following always returns null even when there are files in the directory:
externalDirectories[1].listFiles()
Related
I have an app which records videos, it has about 80K current installations (more than 100K downloads), Crashlytics statistics seems to be good - Crash-free users 99.66% and rating on Google Play is also OK - 4.5
But still for some of my users can happen the next error (it may happened for each user once or a couple of times by now, so not often, but still happens from time to time):
java.io.FileNotFoundException:
/storage/7886-1D16/Android/media/MY_APP_PACKAGE_NAME_HERE/2021-03-18
21h 18m 06s.mp4: open failed: EROFS ... blah blah blah ... android.media.MediaRecorder.prepare(MediaRecorder.java:1028)
Here's the code (similar to real one in my project), as you can see before mediaRecorder.prepare() and video recording I check if output directory is good, if File.canWrite() returns true then it means that files exists, app has needed permission to write at this path and storage is mounted https://developer.android.com/reference/java/io/File#canWrite()
// canWrite() - means that file exists and app is allowed to write
if (outputFolderFile.canWrite()) {
// directory is OK, Android says that there is nothing wrong...
val videoFile = File(outputFolderFile, videoFileName)
... // MediaRecorder settings
mediaRecorder.setOutputFile(videoFile.absolutePath)
... // other MediaRecorder settings
try {
mediaRecorder.prepare() // FileNotFoundException here from time to time
} catch (e: Exception) {
e.printStackTrace()
openReportErrorDialog(e)
}
}
Additionally I was trying to add && Environment.getExternalStorageState(outputFolderFile).equals(Environment.MEDIA_MOUNTED)) or || (outputFolderFile.mkdirs() && outputFolderFile.canWrite()) to that condition (outputFolderFile.canWrite()) but it doesn't matter, error still happens
I also was trying to add createNewFile(videoFile ) line before mediaRecorder.prepare() but doesn't help and in this case the error is java.io.IOException: No such file or directory, java.io.IOException: No such file or directory at java.io.UnixFileSystem.createFileExclusively0(Native Method)
So Android says that directory exists, everything is ok and app can write files there but...
Here I almost added all reports from my users about this error:
HUAWEI CAG-L22
java.io.FileNotFoundException: /storage/7886-1D16/Android/media/MY_APP_PACKAGE_NAME_HERE/2021-03-18 21h 18m 06s.mp4: open failed: EROFS (Read-only file system)
HUAWEI FIG-LX1
java.io.FileNotFoundException: /storage/5309-1D08/Android/media/MY_APP_PACKAGE_NAME_HERE/2021-04-10/2021-04-10 10h 17m 18s.mp4: open failed: EROFS (Read-only file system)
LGE LG-K350
java.io.FileNotFoundException: /storage/4CA1-71F9/Android/media/MY_APP_PACKAGE_NAME_HERE/2021-04-02/2021-04-02 14h 53m 31s.mp4: open failed: ENOENT (No such file or directory)
LGE LM-K300
java.io.FileNotFoundException: /storage/C5F6-15E4/Android/media/MY_APP_PACKAGE_NAME_HERE/2021-03-06/2021-03-06 02h 26m 40s PM.mp4: open failed: ENOENT (No such file or directory)
LGE LM-X420
java.io.FileNotFoundException: /storage/B15A-170A/Android/media/MY_APP_PACKAGE_NAME_HERE/2021-02-12/2021-02-12 13h 31m 42s.mp4: open failed: ENOENT (No such file or directory)
OPPO CPH1931
java.io.FileNotFoundException: /storage/02EB-1B18/Android/media/MY_APP_PACKAGE_NAME_HERE/2021-03-13/2021-03-13 12h 15m 30s.mp4: open failed: EROFS (Read-only file system)
Prestigio PMT3257_3G
java.io.FileNotFoundException: /storage/emulated/0/Android/media/MY_APP_PACKAGE_NAME_HERE/2021-04-10/2021-04-10 10h 32m 21s.mp4: open failed: ENOENT (No such file or directory),
samsung SM-G900F
java.io.FileNotFoundException: /storage/161A-0B3C/Android/media/MY_APP_PACKAGE_NAME_HERE/2021-03-02/2021-03-02 08h 06m 33s.mp4: open failed: ENOENT (No such file or directory)
samsung SM-N960W
java.io.FileNotFoundException: /storage/2A2C-40A4/Android/media/MY_APP_PACKAGE_NAME_HERE/2021-04-14/2021-04-14 02h 35m 45s AM.mp4: open failed: ENOENT (No such file or directory)
Xiaomi M2004J19C
java.io.FileNotFoundException: /storage/emulated/0/Android/media/MY_APP_PACKAGE_NAME_HERE/2021-03-11 11h 09m 18s AM.mp4: open failed: ENOENT (No such file or directory)
Xiaomi M2007J20CG
java.io.FileNotFoundException: /storage/82AD-49E3/Android/media/MY_APP_PACKAGE_NAME_HERE/2021-04-06/2021-04-06 06h 51m 14s.mp4: open failed: ENOENT (No such file or directory)
Xiaomi M2007J3SG
java.io.FileNotFoundException: /storage/emulated/0/Movies/MY_APP_NAME_HERE/2021-03-31/2021-03-31 15h 39m 27s.mp4: open failed: EPERM (Operation not permitted)
Xiaomi M2007J3SY
java.io.FileNotFoundException: /storage/emulated/0/Movies/MY_APP_NAME_HERE/2021-04-10/2021-04-10 01h 30m 42s PM.mp4: open failed: EPERM (Operation not permitted)
Xiaomi M2102J20SG
java.io.FileNotFoundException: /storage/emulated/0/Movies/MY_APP_NAME_HERE/2021-04-17/2021-04-17 16h 16m 59s.mp4: open failed: EPERM (Operation not permitted)
Xiaomi POCO F2 Pro
java.io.FileNotFoundException: /storage/emulated/0/Movies/MY_APP_NAME_HERE/2021-02-05/2021-02-05 19h 20m 36s.mp4: open failed: EPERM (Operation not permitted)
Xiaomi Redmi 5A
java.io.FileNotFoundException: /storage/577D-D95B/Android/media/MY_APP_PACKAGE_NAME_HERE/2021-03-13/2021-03-13 16h 33m 21s.mp4: open failed: EROFS (Read-only file system)
Xiaomi Redmi 7A
java.io.FileNotFoundException: /storage/4DC6-1515/Android/media/MY_APP_PACKAGE_NAME_HERE/2021-03-12/2021-03-12 09h 18m 35s.mp4: open failed: EIO (I/O error)
Xiaomi Redmi Note 8T
java.io.FileNotFoundException: /storage/A018-ED55/Android/media/MY_APP_PACKAGE_NAME_HERE/2021-02-06/2021-02-06 17h 29m 59s.mp4: open failed: EIO (I/O error)
ZTE A2017G
java.io.FileNotFoundException: /storage/emulated/0/Movies/MY_APP_NAME_HERE/2021-03-26/2021-03-26 08h 27m 42s.mp4: open failed: ENOENT (No such file or directory)
So it mostly happens for Xiaomi devices, and mostly when recording to external micro SD Card (e.g. path is /storage/2A2C-40A4/***), though for built-in storage of phone (/storage/emulated/0/***) it also happens sometimes...
Versions of Android are different, from 6 (old) to 11 (newest), so it doesn't matter.
You can see that error is similar (starting with FileNotFoundException and file absolute path) but sometimes it changes at the end between
open failed: EROFS (Read-only file system)
open failed: ENOENT (No such file or directory)
open failed: EIO (I/O error)
open failed: EPERM (Operation not permitted)
Of course users don't send such error report everyday but still it happens often.
I don't have any idea why it happens. I can't reproduce this issue on my own devices (two Samsung, one Lenovo, one Huawei and one Xiaomi devices).
Maybe it happens because read/write time to storage was very slow or freezed (heavy load on it storage controller) at this point and Android (MediaRecorder) could not create an output video file for recording?
Any ideas or solutions?
p.s. full example of error:
java.io.FileNotFoundException:
/storage/5309-1D08/Android/media/MY_APP_PACKAGE_NAME_HERE/2021-04-10/2021-04-10
10h 17m 20s.mp4: open failed: EROFS (Read-only file system) at
libcore.io.IoBridge.open(IoBridge.java:485) at
java.io.RandomAccessFile.(RandomAccessFile.java:288) at
java.io.RandomAccessFile.(RandomAccessFile.java:151) at
android.hsm.HwMediaPermWrapper.setOutputFile(HwMediaPermWrapper.java:127)
at android.media.MediaRecorder.prepare(MediaRecorder.java:1028)
With the recent changes on Android 10 (Q), trying to play a song from the user's device on an app (that targets sdk version 29 and runs Android 10) using ExoPlayer, prints the following log on the console and fails (the song is not played):
E/libprocessgroup: Error encountered killing process cgroup uid 99420 pid 20294: Permission denied
com.google.android.exoplayer2.upstream.FileDataSource$FileDataSourceException: java.io.FileNotFoundException: /storage/emulated/0/Music/Nirvana/[1989] - Bleach/01 - Blew.mp3: open failed: EACCES (Permission denied)
at com.google.android.exoplayer2.upstream.FileDataSource.open(FileDataSource.java:73)
at com.google.android.exoplayer2.upstream.DefaultDataSource.open(DefaultDataSource.java:257)
at com.google.android.exoplayer2.upstream.StatsDataSource.open(StatsDataSource.java:83)
at com.google.android.exoplayer2.source.ProgressiveMediaPeriod$ExtractingLoadable.load(ProgressiveMediaPeriod.java:939)
at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:394)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)
Caused by: java.io.FileNotFoundException: /storage/emulated/0/Music/Nirvana/[1989] - Bleach/01 - Blew.mp3: open failed: EACCES (Permission denied)
at libcore.io.IoBridge.open(IoBridge.java:496)
at java.io.RandomAccessFile.<init>(RandomAccessFile.java:289)
at java.io.RandomAccessFile.<init>(RandomAccessFile.java:152)
at com.google.android.exoplayer2.upstream.FileDataSource.open(FileDataSource.java:65)
at com.google.android.exoplayer2.upstream.DefaultDataSource.open(DefaultDataSource.java:257)
at com.google.android.exoplayer2.upstream.StatsDataSource.open(StatsDataSource.java:83)
at com.google.android.exoplayer2.source.ProgressiveMediaPeriod$ExtractingLoadable.load(ProgressiveMediaPeriod.java:939)
at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:394)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)
Caused by: android.system.ErrnoException: open failed: EACCES (Permission denied)
at libcore.io.Linux.open(Native Method)
at libcore.io.ForwardingOs.open(ForwardingOs.java:167)
at libcore.io.BlockGuardOs.open(BlockGuardOs.java:252)
at libcore.io.ForwardingOs.open(ForwardingOs.java:167)
at android.app.ActivityThread$AndroidOs.open(ActivityThread.java:7255)
at libcore.io.IoBridge.open(IoBridge.java:482)
at java.io.RandomAccessFile.<init>(RandomAccessFile.java:289)
at java.io.RandomAccessFile.<init>(RandomAccessFile.java:152)
at com.google.android.exoplayer2.upstream.FileDataSource.open(FileDataSource.java:65)
at com.google.android.exoplayer2.upstream.DefaultDataSource.open(DefaultDataSource.java:257)
at com.google.android.exoplayer2.upstream.StatsDataSource.open(StatsDataSource.java:83)
at com.google.android.exoplayer2.source.ProgressiveMediaPeriod$ExtractingLoadable.load(ProgressiveMediaPeriod.java:939)
at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:394)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)
One way that I found on the Internet to solve that problem is to add the following attribute on the Manifest's <application> tag:
android:requestLegacyExternalStorage="true"
The problem with that solution is that it seems to be temporary and might get deprecated soon.
What is the correct way to deal with those changes under those specifications?
After further trials, I was able to play a song using ExoPlayer using the Media's Uri.
// id col = `MediaStore.Audio.Media._ID`
val id = cursor.getLong(idColIndex)
val uri = ContentUris.withAppendedId(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
id
)
...
val songSource = ExtractorMediaSource.Factory(dataSourceFactory)
.createMediaSource(uri)
It successfully played the song without any exceptions being thrown.
See https://stackoverflow.com/a/59037794/2373819
But looking at the Exoplayer Source Code.
https://github.com/google/ExoPlayer/blob/release-v2/library/core/src/main/java/com/google/android/exoplayer2/upstream/FileDataSource.java
Says
file = new RandomAccessFile(dataSpec.uri.getPath(), "r");
And in API 29 and above file paths are not accessible in public files.
You should raise a bug in ExoPlayer to use Java a fileDescriptor from a contentresolver instead
I am using Nearby api on two android tablets to send files between them. They can connect to each other successfully but after doing a factory reset on both devices (that is how our customers receive the device), WiFi direct cannot be established and it throws java.io.FileNotFoundException: /data/misc/wifi/networkHistory.txt (No such file or directory). Then After connecting devices to a WiFi it eventually works. Any idea what to do with this issue?
logcat:
E/WifiNetworkHistory: readNetworkHistory: No config file, revert to default, java.io.FileNotFoundException: /data/misc/wifi/networkHistory.txt (No such file or directory)
java.io.FileNotFoundException: /data/misc/wifi/networkHistory.txt (No such file or directory)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.(FileInputStream.java:146)
at java.io.FileInputStream.(FileInputStream.java:99)
at com.android.server.wifi.WifiNetworkHistory.readNetworkHistory(WifiNetworkHistory.java:331)
at com.android.server.wifi.WifiConfigManager.readNetworkHistory(WifiConfigManager.java:1920)
at com.android.server.wifi.WifiConfigManager.loadConfiguredNetworks(WifiConfigManager.java:1750)
at com.android.server.wifi.WifiConfigManager.loadAndEnableAllNetworks(WifiConfigManager.java:458)
at com.android.server.wifi.WifiStateMachine$SupplicantStartingState.processMessage(WifiStateMachine.java:4860)
at com.android.internal.util.StateMachine$SmHandler.processMsg(StateMachine.java:980)
at com.android.internal.util.StateMachine$SmHandler.handleMessage(StateMachine.java:799)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:203)
at android.os.HandlerThread.run(HandlerThread.java:61)
01-01 13:06:18.868 700-747/? E/IpConfigStore: Error parsing configuration: java.io.FileNotFoundException: /data/misc/wifi/ipconfig.txt (No such file or directory)
In my app, I am getting info about device storage (total and free space) using StatFs class.
It is initialized this way:
StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getAbsolutePath());
This app has a bug reporting tool that reports the follwoing error in the previous piece of code:
android.system.ErrnoException
Posix.java line -2 in Posix.statvfs()
statvfs failed: ENOENT (No such file or directory)
I've found little info about this error, like here and here
The documentation about ErrnoException says: A checked exception thrown when Os methods fail.
Someone else has faced this issue?
This question already has answers here:
Exception 'open failed: EACCES (Permission denied)' on Android
(34 answers)
Closed 8 years ago.
For some strange reason, am constantly facing an issue with different types of Android devices, for saving the captured images on the device storage.
Here, is the detailed error log, of what, actually am getting.
java.io.IOException: open failed: EACCES (Permission denied)
at java.io.File.createNewFile(File.java:940)
at com.parkhya.pick_for_shareAflash.HomeActivity.resizeImage(HomeActivity.java:456)
at com.parkhya.pick_for_shareAflash.HomeActivity.onActivityResult(HomeActivity.java:393)
Caused by: libcore.io.ErrnoException: open failed: EACCES (Permission denied)
at java.io.File.createNewFile(File.java:933)
Although, all the other Android apps, like, Instagram and others, are able to save the camera clicked images on the devices.
Anybody, can you please suggest, what should I do, in order for my app, to save the camera pictures in sdcard.
This may help you. I face the same issue when writing the file on sdcard. I have set all required permission to write the file but I used the file object like below:
Wrong:
File myFile = new File(Environment.getExternalStorageDirectory().getAbsoluteFile()+fileName);
Correct:
File myFile = new File(Environment.getExternalStorageDirectory().getAbsoluteFile(), fileName);
That means the path was wrong.
Solution what i find is
edit the Emulator
1. go to android virtual device manager and then edit the emulator
2. set say 100 MB for Sd card for the respected emulator and say Ok
3. save and close emulator and start
4. path saved is click DDMS mnt/sdcard/yourfilename
it worked for me the app is not giving Error and is working