Get mp3 files in Android using LFS [SOLVED]

Hello everyone! I tried to get mp3 files from Android storage. Using LFS extension I can get folders and subfolders, but I can’t get any files.
I need to get files and play it using miniaudio.h. It works corrent in Windows – I use IFileOpenDialog to get folder and LFS to get mp3 files. After that I use the paths to files to play them with miniaudio.h.
For android I wanted to use Java file dialog with Intent.ACTION_OPEN_DOCUMENT_TREE. I tried to create c++ native extension, i used jni to run java code (it was in a example android extension from manual). But I had a problem with startActivityForResult – I couldn’t start new Intent(context, GetFileActivity.class). (But if use only java class, not Activity, java code works. I could start startActivity but can`t get files uri or their real paths.) After that I thought that it is not allowed to start Activity in the Defold and tried to create my own open file dialog using LFS extension. It works, but i can get only directories, not files. How can I get files? Maybe I have to do something else?
My current code which uses LFS, without c++ extension and java:

local start_dir="/storage/emulated/0"

local funs={}

funs.current_dir="/storage/emulated/0"

function funs.change_dir(is_in, name)
	if is_in then
		funs.current_dir=funs.current_dir .. "/" .. name
	else
		if funs.current_dir~=start_dir then
			funs.current_dir=funs.current_dir:match("(.*)/")
		end
	end
end

function funs.print_dir()
	iter, dir_obj = lfs.dir(funs.current_dir)
	local dir_array={}
	if dir_obj then
		local filename = dir_obj:next()
		while filename do
			local name=tostring(filename)
			local attr = lfs.attributes(funs.current_dir .. "/" .. name)
			if attr then
				if attr.mode == "directory" and name~= "." and name~=".." then
					table.insert(dir_array, name)
				end
			end
			filename = dir_obj:next()
		end
	end
	return dir_array
end

return {
	funs = funs
}

This code works, I can get directories. But here I can’t see files, not mp3, png and others, even if I remove attr.mode == "directory"
After that I use:

        local dir=funs.current_dir
        local iter, dir_obj = lfs.dir(dir)
		self.for_music.funs.set_music_files(dir_obj)

But self.for_music.funs.set_music_files(dir_obj) has a problem. It has to create a table which contains all audio files in directory, but it is empty.self.for_music.funs.set_music_files(dir_obj) code:

function funs.set_music_files(dir_obj)
	if dir_obj then
		musics_info={}
		funs.current_track=1
		local filename = dir_obj:next()
		while filename do
			local name=tostring(filename)
			local extension = string.match(name, "%.([^%.]+)$") or ""
			if extension=="mp3" then
				table.insert(musics_info, filename)
			end
			filename = dir_obj:next()
		end
	end
end

I found out that the problem is local filename = dir_obj:next(). It returns nil, even if files exists in this directory. In windows it returns files correctly, so I thought that this is because of permission. But In one of my extensions I have following AndroidManifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="{{android.package}}">    
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"  />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
</manifest>

So I think I have permissions? Maybe there is no way to get files? Thanks in advance for your help!!!

I am away from my computer and cant do a thorough check, but it feels to me like a permission thing. Are you able to list files using lfs in a location you get from sys.get_save_path()?

I found out that I can get files from sys.get_save_path() – the directory is data/data/com.example.todo/files. And I can see files in it. But the files from /storage/emulated/0 are not showing. In Android Studio device explorer I get files permissions – I can access files, which have -rw-rw-rw- permission (in sys.get_save_path()), but files in /storage/emulated/0 have -rwxrwx— permissions, maybe this is the problem?

I solved the problem!!! It was really silly, but I just didn’t get user permissions correctly… They were in my Android manifest, but the app didn’t have these permissions!

Summary: you just have to have the following in the app settings on your phone:

To get this, you have to explicitly request the user’s permission for file access/storage. Even though the permissions are declared in the Android manifest, the app still needs to request them at runtime or the user must grant them in the app settings

1 Like