1

I've got an android app that listens to music broadcasts. It receives track change notifications using the following ApplicationManifest.xml (snippet):

    <receiver android:name=".music.AndroidMusicBroadcastReceiver">
        <intent-filter>
            <action android:name="com.android.music.metachanged"/>
            <action android:name="com.android.music.playbackcomplete"/>
            <action android:name="com.android.music.playstatechanged"/>
            <action android:name="com.htc.music.metachanged"/>
            <action android:name="com.htc.music.playbackcomplete"/>
            <action android:name="com.htc.music.playstatechanged"/>
        </intent-filter>
    </receiver>

When I get this broadcast intent from my nexus 4 running the default (builtin) Google Play Music app, the bundle has useful information about the currently playing track, including "artist" and "title". It doesn't have a file path, which I would like. But it does have an "id" field (a long), which makes me think I can perhaps look up the additional information using that ID as a key. But I can't figure out: What database / content provider is this ID a key into?


Things I've tried so far:

1) I would have expected this to correspond to the _ID field of the content resolver for one of:

  • MediaStore.Audio.Media.INTERNAL_CONTENT_URI
  • MediaStore.Audio.Media.EXTERNAL_CONTENT_URI

But I've tried querying both of those, and the IDs are nowhere in the same ballpark. My current example is that I'm getting an "id" (in the broadcast) of 3399. But querying all the tracks in the EXTERNAL_CONTENT_URI gives me IDs in the range of 20865-23051, plus a couple of small IDs (20 and 24, corresponding to a notification and ringtone installed by the google+ app).

For this source, the ID for the currently playing track would be 21373 (I looked up the ID based on the path, which I can figure out by manual inspection).

INTERNAL_CONTENT_URI just gives me builtin stuff (like ringtones, etc) - all the IDs are < 100, so that's not useful either.

2) I did the same query against all media objects - using MediaStore.Files.getContentUri("external"). I got back plenty of results, but ID 3399 is a random file cached by newsrob (an RSS reader), so that's clearly not relevant.

Matthieu Brucher
  • 21,634
  • 7
  • 38
  • 62
gfxmonk
  • 8,614
  • 5
  • 42
  • 53
  • Using gmusic-playlist (which is a Tampermonkey script that exports Google Play Music (the web service) playlist information as CSV. Get it here: https://github.com/soulfx/gmusic-playlist.js). I see that the ID repeats across different songs. Very strange. There also appear to be seven different "idtype"s and these correspond in some cases to different ID formats. Could these correspond possibly to those used in the Android app for Google Play Music? – Jon May 07 '16 at 16:51
  • Correction: they are unique to each track. My sorting had an error. – Jon May 07 '16 at 17:01

1 Answers1

1

Take a look at the source code in MediaPlaybackService.java:

private void notifyChange(String what) {

    Intent i = new Intent(what);
    i.putExtra("id", Long.valueOf(getAudioId()));
    i.putExtra("artist", getArtistName());
    i.putExtra("album",getAlbumName());
    i.putExtra("track", getTrackName());
    i.putExtra("playing", isPlaying());
    ...
}

/**
 * Returns the rowid of the currently playing file, or -1 if
 * no file is currently playing.
 */
public long getAudioId() {
    synchronized (this) {
        if (mPlayPos >= 0 && mPlayer.isInitialized()) {
            return mPlayList[mPlayPos];
        }
    }
    return -1;
}

Some code about the ContentProvider:

Cursor crsr = MusicUtils.query(this,
                    MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
                    new String [] {"_id"}, "_id=" + mPlayList[mPlayPos] , null, null);

I think I don't need to say something else. :) Hope this can help you.

StarPinkER
  • 14,081
  • 7
  • 55
  • 81
  • Thanks for the pointer, I had forgotten that the source might be available. I'm using "Google Play music", which I forgot might be relevant. I suspect this isn't based on the open source code, as there are a discrepancies in the keys that my broadcast intent receives and what is supposedly sent (not the last of which is that the ID doesn't match like it should!). So while it's a good answer, I've updated my question to refer specifically to Google Play Music. – gfxmonk Feb 28 '13 at 10:19
  • Did you use id instead of _id to select from the EXTERNAL_CONTENT_URI? – StarPinkER Feb 28 '13 at 10:35
  • I used MediaStore.Audio.Media._ID, but also tried a literal "_id" out of superstition - same results. – gfxmonk Feb 28 '13 at 11:56
  • Well, I tested it on emulator, it works, so I think it might be an HTC-specific problem. And http://stackoverflow.com/a/5613055/1365960 also showed a similar problem on Images. – StarPinkER Mar 01 '13 at 00:56
  • I fired up an emulator, and it has the regular Music app, not "Google Play Music", so yes I think it must be specific to that (not HTC related though, this is a Google Nexus 4 - I'd expect less weirdness from Google). – gfxmonk Mar 01 '13 at 10:48