Cant write nor read to/from external storage with LibGDX - android

My create method looks like this:
#Override
public void create () {
batch = new SpriteBatch();
FileHandle file = Gdx.files.external("file.txt");
file.writeString("My god, it's full of stars", false);
}
I also included:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
The Exception I get is this:
02-13 14:45:51.858 12439-12466/com.snowdevs.tweetiebirds E/AndroidRuntime: FATAL EXCEPTION: GLThread 1120
Process: com.snowdevs.tweetiebirds, PID: 12439
com.badlogic.gdx.utils.GdxRuntimeException: Error writing file: file.txt (External)
at com.badlogic.gdx.files.FileHandle.writeString(FileHandle.java:353)
at com.badlogic.gdx.files.FileHandle.writeString(FileHandle.java:339)
at com.snowdevs.tweetiebirds.TweetieBirdsGame.create(TweetieBirdsGame.java:22)
at com.badlogic.gdx.backends.android.AndroidGraphics.onSurfaceChanged(AndroidGraphics.java:254)
at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1519)
at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1240)
Caused by: com.badlogic.gdx.utils.GdxRuntimeException: Error writing file: file.txt (External)
at com.badlogic.gdx.files.FileHandle.writer(FileHandle.java:330)
at com.badlogic.gdx.files.FileHandle.writeString(FileHandle.java:350)
at com.badlogic.gdx.files.FileHandle.writeString(FileHandle.java:339) 
at com.snowdevs.tweetiebirds.TweetieBirdsGame.create(TweetieBirdsGame.java:22) 
at com.badlogic.gdx.backends.android.AndroidGraphics.onSurfaceChanged(AndroidGraphics.java:254) 
at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1519) 
at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1240) 
Caused by: java.io.FileNotFoundException: /storage/emulated/0/file.txt: open failed: EACCES (Permission denied)
at libcore.io.IoBridge.open(IoBridge.java:452)
at java.io.FileOutputStream.<init>(FileOutputStream.java:87)
at com.badlogic.gdx.files.FileHandle.writer(FileHandle.java:322)
at com.badlogic.gdx.files.FileHandle.writeString(FileHandle.java:350) 
at com.badlogic.gdx.files.FileHandle.writeString(FileHandle.java:339) 
at com.snowdevs.tweetiebirds.TweetieBirdsGame.create(TweetieBirdsGame.java:22) 
at com.badlogic.gdx.backends.android.AndroidGraphics.onSurfaceChanged(AndroidGraphics.java:254) 
at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1519) 
at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1240) 
Caused by: android.system.ErrnoException: open failed: EACCES (Permission denied)
at libcore.io.Posix.open(Native Method)
at libcore.io.BlockGuardOs.open(BlockGuardOs.java:186)
at libcore.io.IoBridge.open(IoBridge.java:438)
at java.io.FileOutputStream.<init>(FileOutputStream.java:87) 
at com.badlogic.gdx.files.FileHandle.writer(FileHandle.java:322) 
at com.badlogic.gdx.files.FileHandle.writeString(FileHandle.java:350) 
at com.badlogic.gdx.files.FileHandle.writeString(FileHandle.java:339) 
at com.snowdevs.tweetiebirds.TweetieBirdsGame.create(TweetieBirdsGame.java:22) 
at com.badlogic.gdx.backends.android.AndroidGraphics.onSurfaceChanged(AndroidGraphics.java:254) 
at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1519) 
at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1240) 
I use a Nexus 5 with Android 6 Marshmallow for testing.
I searched and found that Android 6 uses Run Time Permissions, but the LibGDX developers say that it works even on Android 6. Is there a fix, either with or without Run Time Permissions?

I solved the problem by checking if the user has granted permission of external storage and request permision if not granted by using:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (this.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
this.requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, WRITE_REQUEST_CODE);
}
All of this is android-specific code and thus resides in the AndroidLauncher class.

I don't believe Nexus 5 has external storage (SD card).
Use this to test to find out -
boolean isExtAvailable = Gdx.files.isExternalStorageAvailable();
You can find more information here.

I had the same situation(Android 6, Nexus 4 No SD Card, libGDX 1.9.3):
I checked the external storage with
Gdx.files.isExternalStorageAvailable() // returns true
then get the fileHandle with
FileHandle file = Gdx.files.external("file.txt"); // no exception
then call
file.writeString("text",false); // throws GdxRuntimeException
So I checked on android side is the external storage really available with this code:
Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()); // returns true
This also returned true. So it's not a libGDX issue, rather than an Android issue.
then I solved it with catching the exception and in that case writing the file to local storage.

Related

Utilizing File Api for File Access in Android 11

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()

I can't read/write on the external memory of my Galaxy A41

With Android studio, I installed this example on my smartphone.
At the first launch I have a message asking me if I allow the application to have access to the external memory. I answered yes.
On the second launch (or subsequent ones), using the debugger, I notice that the permission is granted and continuing the code, but when I reach the line:
FileOutputStream fos = new FileOutputStream(file);
it goes directly to:
} catch (Exception e) {
While I have permission, it doesn't work.
Doing the same manipulation, but using "run" instead of "debug", I get the following error (logcat):
2020-11-28 11:05:25.135 16779-16779/com.example.testrw D/path:
/storage/emulated/0/UniqueFileName.jpg 2020-11-28 11:05:25.135
16779-16779/com.example.testrw W/System.err:
java.io.FileNotFoundException: /storage/emulated/0/UniqueFileName.jpg:
open failed: EACCES (Permission denied) 2020-11-28 11:05:25.135
16779-16779/com.example.testrw W/System.err: at
libcore.io.IoBridge.open(IoBridge.java:496) 2020-11-28 11:05:25.136
16779-16779/com.example.testrw W/System.err: at
java.io.FileOutputStream.(FileOutputStream.java:235) 2020-11-28
11:05:25.136 16779-16779/com.example.testrw W/System.err: at
java.io.FileOutputStream.(FileOutputStream.java:186) 2020-11-28
11:05:25.136 16779-16779/com.example.testrw W/System.err: at
com.example.testrw.MainActivity$1.onClick(MainActivity.java:47)
where line 47 is the one I mentioned:
FileOutputStream fos = new FileOutputStream(file);
This "run" shows a problem, but I don't see which one.
Please help me.
Cordially.
Pierre.
I found the solution in this link. But I only access to the /storage/emulated/0. I have no access to my SD card.
Cordially.
Pierre.

EACCES(permission denied) when tried to access /system/build.prop even after storage permission and SU

i'm new to kotlin and android i'm trying to read build.prop from /system for that i'm accessing root by using
Runtime.getRuntime().exec("su")
and i also gave storage permission(i have done all the stuffs needed to access storage that need to work on Android 10 like fileProvider and such things)
here is the code of accessing build.prop file
private fun filecreator(): String {
val ensy= Environment.getRootDirectory()
val filess =File("$ensy","build.prop")
return filess.readText()
}
after it throws
msg: android.system.ErrnoException: open failed: EACCES (Permission denied)
stacktrace: java.lang.RuntimeException: Unable to start activity
ComponentInfo{com.airbender.c2/com.airbender.c2.MainActivity}: java.io.FileNotFoundException:
/system/build.prop: open failed: EACCES (Permission denied)
what should i do is there any way to access /system or my implementation is totally wrong
thanks

What is the correct way to play songs on ExoPlayer with Android 10 (Q) and targetSdkVersion = 29?

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

Android Exception : java.io.IOException: open failed: EACCES (Permission denied) [duplicate]

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

Categories

Resources