Jump to content

How to get the ABSOLUTE path with Poweramp.Track.PATH ?


Rachel Tang

Recommended Posts

Hi there, I'm working on a app which could fetch .lrc files in the folder where songs are located, but in my development I've found some issues. I don't know what PATH does Poweramp return, or how can I get the ABSOLUTE path to make my app able to access files in the same directory. It seems that Poweramp installed on some devices returns "primary/XXX/XXX.mp3", and on some others returns "/mnt/internal_sd/XXX/XXX.mp3", varying from device to device(maybe? I don't have enough devices to prove). What's worse, deeply-customized Android OSs and various Android devices add to the difficulty of fetching the correct path.

TL;DR: Sorry for my nonsense, in short words what I want to know is that:

  1. How to get the correct absolute path of each file?
  2. (If possible) how does Poweramp process the Poweramp.Track.PATH before it is put into an Intent?

Thanks!

Link to comment
Share on other sites

@Rachel TangI can explain how Poweramp stores the data

The main "central" table is callled folder_files and has the following columns:

image.png.c0c2ac94d47dcefa6e4be522fd2ab904.png

There is also a table called folders which has the following structure

image.png.81e1fd4a36511dc7802814fa59a4c669.png

where you can find the path

image.png.c5f25f9a0899cd53bfb1d40d541f3d1f.png

The sql statement should contain "WHERE folder_files.folder_id = folders.folder_id

SELECT
    folder_files.name,
    folder_files.folder_id, folders.path
FROM
    folder_files folder_files,
    folders folders
WHERE
    folder_files.folder_id = folders._id

which then gives:

image.png.5cfd0efa06924ac18bf8d24880c5b499.png

I hope this helps

Link to comment
Share on other sites

Here is some more

public final Uri powerampuri = Uri.parse("content://com.maxmpz.audioplayer.data/files");
public String pamppath = "folders.path as pamppath";
public String pamppathColumn = "pamppath";

This gets all tracks

ContentResolver cr = context.getContentResolver();
String[] proj = {pamptrack_id,  pamppath};
return cr.query(powerampuri, proj, null, null, null);

and once you have the cursor

String path = poweramp_cursor.getString(poweramp_cursor.getColumnIndex(pamppathColumn));
Link to comment
Share on other sites

@flyingdutchman After looking into it, I found that on some devices with only one storage, the path inside the database is still something like "primary/XXX", the same as what the Poweramp puts into the bundle with Poweramp.Track.PATH. So… does it mean that if there is not a "primary" prefix, the Poweramp.Track.PATH will return the real absolute path, and if there is, a simple getExternalStorageDirectory should do that? Not widely confirmed, but true on my other device… I'm getting confused now.

Snipaste_2020-03-07_23-29-37.png

Link to comment
Share on other sites

If you are working with Poweramp tracks, you should be using the path as held in the Poweramp database. It is confusing as different versions of android have different naming conventions. Internal memory is sometimes also known as sdcard or storage/emulated/0. External sdcards show up as storage/some weird stuff/some folder. But in the android picker it shows as Sdcard. I am convinced google is trying to get rid of devices which have an external sdcard slot. With each release they seem to make life more difficult

 

Link to comment
Share on other sites

1 hour ago, flyingdutchman said:

With each release they seem to make life more difficult

Ain't that the truth. :(  It started with Grant Access, then these ridiculous 8 random digit SD Card names, and now the horrible mess of Android 10. 

Andre

Link to comment
Share on other sites

@andrewilley Fully agree. APIs change from generation to generation which is a great trouble to get apps compatible with all versions of Android. Also in China too many deeply-customized Androids(like MIUI, EMUI, Color OS, etc) make the difficult situation just harder.

Link to comment
Share on other sites

@Rachel Tang It's not about API change, it's Android 10 that banned direct access to the files (though, they reverted it for older sdk build targets, etc. but Poweramp is built vs highest target build available and it's already moved to the new APIs), and thus, there are no absolute paths anymore.

Paths are relative to the DocumentContract permission URI, which is given by user in Music Folders (that Enable button). Depending on what user selected there, path differs.

Please note that same approach is used also for other storages on older Androids (5+, for USB storages).

There is still a solution, but it requires you to use DocumentsContract/SAF API too. You can generate URIs based on Poweramp "paths" via your permission URI.

 

Link to comment
Share on other sites

@maxmp Got that. Currently I declares requestLegacyExternalStorage to be true so that I could replace "primary" with the storage directory to gain access to the files…which I believe is the worst practice.

So, on Android 10 and above I need to ask user to select(with DocumentsContract and SAF API) the same path as they do in Poweramp, and on Pie and below the "path" can be directly used, is that true?

And another question, can URIs be used to access a specific file, for example, if there is "primary/XXX/YYY.mp3" and I want to access "primary/XXX/YYY.lrc", can I achieve that by DocumentsContract / SAF? I've googled a lot but not much seems to have something to do with this, or maybe I should just try it out myself?

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...