Android intent to open playlist with Media Player

Support for Android version of Total Commander

Moderators: white, Hacker, petermad, Stefan2

Post Reply
vault
Junior Member
Junior Member
Posts: 6
Joined: 2022-12-30, 22:53 UTC

Android intent to open playlist with Media Player

Post by *vault »

Hello everyone,
I'd like to add a button to my app that tells TC's Media Player to immediately open the playlist at

Code: Select all

/sdcard/playlist.m3u8
I'd also ideally like to empty the queue before opening the playlist, but I can't make that work either.
Can you help me with the right Java code to achieve this?

E.g. I searched the forum without much success. I tried to put together this and this:

Code: Select all

var intent = new Intent("com.ghisler.android.TotalCommander.MediaPlayerActivity");
intent.setData(Uri.parse("uri:file://exit"));
but it's not working well.
User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 48028
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Re: Android intent to open playlist with Media Player

Post by *ghisler(Author) »

1. To send the playlist, use the following code:

Code: Select all

var intent = new Intent("com.ghisler.android.TotalCommander.MediaPlayerActivity");
intent.setData(Uri.parse("file:///storage/emulated/0/playlist.m3u8"));
startActivity(intent);
You need to call special functions to prevent a crash when using file URLs. If your app crashes, replace the file: prefix with something else, e.g.
intent.setData(Uri.parse("data:///storage/emulated/0/playlist.m3u8"));

2. You made a little mistake in the URL to exit the player. It should be

Code: Select all

intent.setData(Uri.parse("file://exit"));
or

Code: Select all

intent.setData(Uri.parse("data://exit"));
The url: prefix is only used in the Total Commander button parameter section to tell Total Commander to add an URL via setData. The actual URL comes after this url: prefix.
Author of Total Commander
https://www.ghisler.com
vault
Junior Member
Junior Member
Posts: 6
Joined: 2022-12-30, 22:53 UTC

Re: Android intent to open playlist with Media Player

Post by *vault »

Do you know how to deal with the new file providers?
I'm targeting android 33 and I've replaced READ_EXTERNAL_STORAGE with READ_MEDIA_AUDIO.
Then I declared a provider in the manifest and added res/xml/file_paths.xml:

Code: Select all

<paths><external-path name="external_storage" path="."/></paths>
In the activity, I'm calculating the URI with:

Code: Select all

Uri playlistUri() {
  var playlist = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC), "list.m3u8");
  return FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID + ".fileprovider", playlist);
}
and launching the intent you suggested to me:

Code: Select all

Intent tcIntent() {
  return new Intent("com.ghisler.android.TotalCommander.MediaPlayerActivity")
      // .setData(playlistUri())
      .setDataAndType(playlistUri(), "audio/x-mpegurl")
      .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
I tried all the variations of the code above (data, dataAndType, with and without flag), but I always receive:

Code: Select all

android.content.ActivityNotFoundException: No Activity found to handle Intent { act=com.ghisler.android.TotalCommander.MediaPlayerActivity dat=content://{APPLICATION_ID}.fileprovider/... typ=audio/x-mpegurl flg=0x1 }
User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 48028
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Re: Android intent to open playlist with Media Player

Post by *ghisler(Author) »

That's not how it works. When you send a content: URL, you either need to implement your own content provider (either a file provider or raw content provider) and then return the data to the called app when it asks for it.

Or in case of Total Commander, you know that it has access to the file system, so you can send it the file:/// or data:/// URLs directly. You should specify both the app and class, though:

Code: Select all

var intent = new Intent("com.ghisler.android.TotalCommander", "com.ghisler.android.TotalCommander.MediaPlayerActivity");
Author of Total Commander
https://www.ghisler.com
vault
Junior Member
Junior Member
Posts: 6
Joined: 2022-12-30, 22:53 UTC

Re: Android intent to open playlist with Media Player

Post by *vault »

The constructor

Code: Select all

Intent(String, String)
doesn't exist, and

Code: Select all

Intent(String)
is meant for actions, not packages or classes.

Here's the fixed version that at least opens Total Commander Media Player:

Code: Select all

new Intent(Intent.ACTION_VIEW)
    .setClassName(
        "com.ghisler.android.TotalCommander",
        "com.ghisler.android.TotalCommander.MediaPlayerActivity")
    .setData(Uri.parse("file:///storage/emulated/0/Music/list.m3u8"));
But with recent Android versions, you cannot use setData as you suggested:

Code: Select all

android.os.FileUriExposedException: file:///storage/emulated/0/Music/list.m3u8 exposed beyond app through Intent.getData()
That's why I started implementing the FileProvider as suggested here (avoiding the hacky solutions that disable the exception), but then the media player has problems opening the files in the m3u:

Code: Select all

java.lang.SecurityException: Permission Denial: reading androidx.core.content.FileProvider uri content://{APPLICATION_ID}.fileprovider/external_storage/Music/01.opus from pid=24667, uid=10362 requires the provider be exported, or grantUriPermission()
A few additional findings:
  • "file://exit" also triggers FileUriExposedException
  • "data://exit" triggers ActivityNotFoundException: Unable to find explicit activity class {c.g.a.TotalCommander/c.g.a.TotalCommander.MediaPlayerActivity}
  • All actions other than Intent.ACTION_VIEW (e.g. ACTION_SEND which seems to be appropriate in this case) trigger ActivityNotFoundException
User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 48028
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Re: Android intent to open playlist with Media Player

Post by *ghisler(Author) »

Actually you can send file URLs, you just need to tell Android to not cause an exception:

Code: Select all

	public static void disableStrictMode() {
		StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P)
			builder.detectNonSdkApiUsage();
		StrictMode.setVmPolicy(builder.penaltyLog().build());
	}
Author of Total Commander
https://www.ghisler.com
vault
Junior Member
Junior Member
Posts: 6
Joined: 2022-12-30, 22:53 UTC

Re: Android intent to open playlist with Media Player

Post by *vault »

Yes, that's the hack that I linked and that I don't want to use (BTW I think the one I linked would be safer to use than yours).
It's not safe to rely on hacks, first because well, they are hacks, and second because they might suddenly disappear in future versions.
So I guess sooner or later TC must work with File Providers. Do you know how to make them work?
User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 48028
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Re: Android intent to open playlist with Media Player

Post by *ghisler(Author) »

Have you tried to replace the file: prefix with something else like data: as I suggested? Don't use content: because that's reserved for content URLs.
Author of Total Commander
https://www.ghisler.com
vault
Junior Member
Junior Member
Posts: 6
Joined: 2022-12-30, 22:53 UTC

Re: Android intent to open playlist with Media Player

Post by *vault »

As I wrote here, "data:" triggers ActivityNotFoundException.
User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 48028
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Re: Android intent to open playlist with Media Player

Post by *ghisler(Author) »

You can send the content with my plugin provider prefix, e.g.:
content://com.ghisler.files/storage/emulated/0/file.m3u
Author of Total Commander
https://www.ghisler.com
vault
Junior Member
Junior Member
Posts: 6
Joined: 2022-12-30, 22:53 UTC

Re: Android intent to open playlist with Media Player

Post by *vault »

Oh nice, this is perfect!
User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 48028
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Re: Android intent to open playlist with Media Player

Post by *ghisler(Author) »

Just make sure to properly encode characters not allowed in URLs, like % # etc.
Author of Total Commander
https://www.ghisler.com
Post Reply