How to write to user:// directory in android

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By yonni
:warning: Old Version Published before Godot 3 was released.

Whenever I try to open a file in user:// for writing on android, I get the error number 12 back (that’s Error::ERR_FILE_CANT_OPEN). This works fine on linux.

What am I missing, or is the engine bugged for file io in android?

(I’ve tested this with a fresh compile of, as well as with my previous 2.0-based expanded builds).

Here’s a minimal working (well, not working on android) example:

extends Node

func _ready():

    var dir =
    var dir_name = "test-dir"
    var filename = "test_file.txt"
    var user_dir = "user://" + dir_name

    print( "User directory: " + user_dir )

    if( !dir.dir_exists( OS.get_data_dir() + "/" + dir_name ) ):
        print( user_dir + " doesn't exist." )
        dir.make_dir_recursive( OS.get_data_dir() + "/" + dir_name )
        print( user_dir + " exists." )

    var fp_user =
    # Neither of the following lines work
    # var err = OS.get_data_dir() + "/" + dir_name + "/" + filename, File.WRITE )
    var err = user_dir + "/" + filename, File.WRITE )
    print( user_dir + "/" + filename + " opened." )
    print( "fp_user error code: " + str(err) )

    fp_user.store_line( "This is a test file." )
    print( filename + " written." )


What about using "user://" instead of OS.get_data_dir()?
What android version did you test on?

volzhs | 2016-07-22 12:17

You’ll note in the example for I try both versions.
For checking whether the directory exists and making it if not I believe I’ve checked both versions, but I’ll double check when back from work.
The error occurs on the line for

yonni | 2016-07-22 12:19

hm… I will try.

volzhs | 2016-07-22 12:24

what android version are you using?
there was related commit in recent.
Fixed bug using DirAccess in Android Marshmallow due to data dir bein… · godotengine/godot@10eedf6 · GitHub

volzhs | 2016-07-22 12:31

Android 5.0 kernel 3.4.0. LG G3.
I’m not sure exactly what I’m supposed to be looking at in that link?

yonni | 2016-07-22 12:34

I was just saying something changed in recent, giving you a small information.
And I am making android game and using save and load play data at user://
I don’t have problem so far.
But not tried to make a sub directory and save it under the sub directory.

volzhs | 2016-07-22 12:43

Thank you. Would you mind sending me the relevant snippet of your code (with your godot and android version)?

yonni | 2016-07-22 12:46

:bust_in_silhouette: Reply From: volzhs

I tested your code on Android 6.0 with current head on github.

This codes works as expected.

func _ready():
	var dir =
	var dir_name = "test-dir"
	var filename = "test_file.txt"
	var user_dir = "user://"
	print( "User directory: " + user_dir )

	if( !dir.dir_exists( dir_name ) ):
		print( dir_name + " doesn't exist." )
		dir.make_dir_recursive( dir_name )
		print( dir_name + " exists." )

	var fp_user =
	var f_name = user_dir + dir_name + "/" + filename;
	var err = f_name, File.WRITE )
	print( f_name + " opened." )
	print( "fp_user error code: " + str(err) )

	fp_user.store_line( "This is a test file." )
	print( f_name + " written." )


And result

User directory: user://
test-dir doesn't exist.
user://test-dir/test_file.txt opened.
fp_user error code: 0
user://test-dir/test_file.txt written.

…and this works! I guess the problem was not opening the directory directly and instead trying to make the directory from the OS directory path. I’m surprised I hadn’t checked this. Thanks so much for your help.

yonni | 2016-07-22 23:45

On a side note, I’m not able to build the current master branch from github. It’s complaining it can’t find my xrandr (which is most definitely there). I don’t suppose you know anything about that do you?

yonni | 2016-07-22 23:46

try apt-get install xutils-dev or apt-get install libxrandr-dev - according to my apt logs one of that helped me, probably the last one

gorgo | 2016-07-23 13:26

Fantastic, that worked too. Thanks for all of your help.

yonni | 2016-07-24 16:13

:bust_in_silhouette: Reply From: punto

I’m not sure if it’s the same, but there was an issue a while ago where on some versions of Android, the user:// directory is a symlink, that triggers some code in the DirAccess class that causes it to fail creating directories in user:// (basically it fails if the new path is outside the base path for user data, to avoid users creating data outside of their assigned directory). Try a newer version, if that’s the issue we can probably make the case to cherry pick the fix to the stable build.

hello! I’ve got this crash log from google play, could it be related to that bug? Used master branch with last commits dated 14 June

 Build fingerprint: 'motorola/athene_f/athene_f:6.0.1/MPJ24.139-23.1/1:user/release-keys'
Revision: 'p2a0'
ABI: 'arm'

pid: 12847, tid: 12873, name: GLThread 4482  >>> <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0
    r0 af80019c  r1 00000000  r2 00000000  r3 00000001
    r4 af80019c  r5 b7858ba0  r6 af8001a4  r7 af8001a0
    r8 a223d888  r9 af80019c  sl a21de508  fp af800328
    ip ebad607c  sp af800158  lr a2020948  pc a20206f0  cpsr 680f0010

    #00 pc 00cba6f0  /data/app/ (_ZN6String9copy_fromEPKc+8)
    #01 pc 00cba944  /data/app/ (_ZN6StringC2EPKc+16)
    #02 pc 0006ab98  /data/app/ (_ZL13_get_data_dirv+68)
    #03 pc 00062e9c  /data/app/ (_ZNK10OS_Android12get_data_dirEv+20)
    #04 pc 00ce7cfc  /data/app/ (_ZNK10FileAccess8fix_pathERK6String+216)
    #05 pc 0010c060  /data/app/ (_ZN14FileAccessUnix5_openERK6Stringi+64)
    #06 pc 00ce7848  /data/app/ (_ZN10FileAccess4openERK6StringiP5Error+220)
    #07 pc 00d8a28c  /data/app/ (_ZN5_File4openERK6Stringi+36)
    #08 pc 00d8a37c  /data/app/ (_ZN5_File19open_encrypted_passERK6StringiS2_+16)
    #09 pc 00d8c510  /data/app/ (_ZN12MethodBind3RI5ErrorRK6StringiS3_E4callEP6ObjectPPK7VariantiRNS7_9CallErrorE+468)
    #10 pc 00c865d0  /data/app/ (_ZN6Object4callERK10StringNamePPK7VariantiRNS3_9CallErrorE+308)
    #11 pc 00c6e54c  /data/app/ (_ZN7Variant4callERK10StringNamePPKS_iRNS_9CallErrorE+556)
    #12 pc 000c2788  /data/app/ (_ZN10GDFunction4callEP10GDInstancePPK7VariantiRNS2_9CallErrorEPNS_9CallStateE+30752)
    #13 pc 000cfe90  /data/app/ (_ZN10GDInstance4callERK10StringNamePPK7VariantiRNS3_9CallErrorE+180)
    #14 pc 00c8666c  /data/app/ (_ZN6Object4callERK10StringNamePPK7VariantiRNS3_9CallErrorE+464)
    #15 pc 00c6e54c  /data/app/ (_ZN7Variant4callERK10StringNamePPKS_iRNS_9CallErrorE+556)
    #16 pc 000c3194  /data/app/ (_ZN10GDFunction4callEP10GDInstancePPK7VariantiRNS2_9CallErrorEPNS_9CallStateE+33324)
    #17 pc 000cfe90  /data/app/ (_ZN10GDInstance4callERK10StringNamePPK7VariantiRNS3_9CallErrorE+180)
    #18 pc 00c8666c  /data/app/ (_ZN6Object4callERK10StringNamePPK7VariantiRNS3_9CallErrorE+464)
    #19 pc 00c93cb0  /data/app/ (_ZN6Object11emit_signalERK10StringNamePPK7Varianti+1176)
    #20 pc 00c9441c  /data/app/ (_ZN6Object11emit_signalERK10StringNameRK7VariantS5_S5_S5_S5_+100)
    #21 pc 0054efe8  /data/app/ (_ZN10BaseButton12_input_eventE10InputEvent+636)
    #22 pc 00456d94  /data/app/ (_ZN11MethodBind1I10InputEventE4callEP6ObjectPPK7VariantiRNS4_9CallErrorE+156)
    #23 pc 00c8641c  /data/app/ (_ZN6Object15call_multilevelERK10StringNamePPK7Varianti+212)
    #24 pc 00c86b30  /data/app/ (_ZN6Object15call_multilevelERK10StringNameRK7VariantS5_S5_S5_S5_+108)
    #25 pc 00446b5c  /data/app/ (_ZN8Viewport15_gui_call_inputEP7ControlRK10InputEvent+184)
    #26 pc 004554fc  /data/app/ (_ZN8Viewport16_gui_input_eventE10InputEvent+4748)
    #27 pc 00455910  /data/app/ (_ZN8Viewport5inputERK10InputEvent+144)
    #28 pc 00455a18  /data/app/ (_ZN8Viewport9_vp_inputERK10InputEvent+128)
    #29 pc 00443d8c  /data/app/ (_ZN11MethodBind1IRK10InputEventE4callEP6ObjectPPK7VariantiRNS6_9CallErrorE+120)
    #30 pc 00c865d0  /data/app/ (_ZN6Object4callERK10StringNamePPK7VariantiRNS3_9CallErrorE+308)
    #31 pc 00c86a9c  /data/app/ (_ZN6Object4callERK10StringNameRK7VariantS5_S5_S5_S5_+140)
    #32 pc 004198a0  /data/app/ (_ZN9SceneTree10call_groupEjRK10StringNameS2_RK7VariantS5_S5_S5_S5_+956)
    #33 pc 0041c630  /data/app/ (_ZN9SceneTree11input_eventERK10InputEvent.part.185+268)
    #34 pc 00090c34  /data/app/ (_ZN12InputDefault17parse_input_eventERK10InputEvent+380)
    #35 pc 00065458  /data/app/ (_ZN10OS_Android13process_touchEiiRK6VectorINS_8TouchPosEE+4596)
    #36 pc 00072298  /data/app/ (Java_org_godotengine_godot_GodotLib_step+328)
    #37 pc 0064635d  /data/app/ (offset 0x4d1000)

gorgo | 2016-07-23 13:43