How to set EXTRA_PAGE and EXTRA_PAGE_SIZE in a MediaBrowserServiceCompat by getting reference to the Android Auto MediaBrowser?

半腔热情 提交于 2019-12-21 03:50:45

问题


I have an Android Auto app. I would like to take advantage of pagination for browsing within the app. It seems that you can set EXTRA_PAGE and EXTRA_PAGE_SIZE by getting a reference to the MediaBrowserCompat and passing those constants in .subscribe(). However, I can't figure out how to get a reference to the MediaBrowserCompat that Android Auto Audio uses in order to call .subscribe().

This seems way too complicated for something that should be simple, am I just overthinking things?


回答1:


How to get the reference to the Android Auto MediaBrowser? For it, you suppose to know the package name and the class name (if you are trying to bind it outside the app). If you don't know the these details, you can just get it all from the package manager.

final Intent providerIntent = 
new Intent(MediaBrowserService.SERVICE_INTERFACE);
List<ResolveInfo> mediaApps = 
    mPackageManager.queryIntentServices(providerIntent, 0);
for (ResolveInfo info : mediaApps) {
    new MediaBrowserCompat(context, 
        new ComponentName(info.serviceInfo.packageName, 
        info.serviceInfo.name), mConnectionCallbacks, null);
}

How to set EXTRA_PAGE and EXTRA_PAGE_SIZE?

Bundle bundle = new Bundle();
bundle.putInt(MediaBrowserCompat.EXTRA_PAGE, 1);
bundle.putInt(MediaBrowserCompat.EXTRA_PAGE_SIZE, 1);
mBrowser.subscribe("__SOME_ID__", bundle, callback);

If you are overriding the onLoadChildren() with the bundle on your service side than you have to handle the paging logic too. You can bypass it by just overriding onLoadChildren without bundle.




回答2:


Please note: Usually in Android when you see compat suffix at the end, it is new (enhanced) version of one without compat.

MediaActivity is not special Activity, it's a kind of Activity, which is designed to play the musics. And, as you asked MediaBrowserCompat and MediaBrowserServiceCompat, I changed my default architecture (Architecture 2 presented below), to Architecture 1 (Architecture 1 presented below which is new introduced in version 22), just to give the exact answer that you asked.

Two Architectures are:

Architecture1)

1) MediaActivity <--uses----> MediaBrowserCompat <---uses--> MediaServiceBrowserCompat <----> MediaSessionCompat <---> MediaSession <--pass session token --> MediaControllerCompat <-- it also passes token to create --> MediaController /* latest API introduced in 22 */

2)

 <service android:name=".MyMediaBrowserServiceCompat"
              android:label="@string/service_name" >
         <intent-filter>
             <action android:name="android.media.browse.MediaBrowserService" />
         </intent-filter>
     </service>

3) Uses MediaSessionCompat to control music playing.

4) Once a session is created the owner of the session may pass its session token to other processes to allow them to create a MediaControllerCompat to interact with the session.

5) A MediaController can be created if you have a MediaSessionCompat.Token from the session owner.

Now, You created MediaController

From here, both Architecture do the same thing.

Architecture2)

1)MediaActivity <--uses----> MediaBrowser <---uses--> MediaServiceBrowser /* old one introduced in 21. This is default */

2)

 <service android:name=".MyMediaBrowserService"
          android:label="@string/service_name" >
     <intent-filter>
         <action android:name="android.media.browse.MediaBrowserService" />
     </intent-filter>
 </service>

3) Uses MediaSession to control music playing

4) Once a session is created the owner of the session may pass its session token to other processes to allow them to create a MediaController to interact with the session.

5) A MediaController can be created through MediaSessionManager if you hold the "android.permission.MEDIA_CONTENT_CONTROL" permission or are an enabled notification listener or by getting a MediaSession.Token directly from the session owner.

Now, You created MediaController

From here, both Architecture do the same thing.

Note: By default, when you create Android Auto project, it still uses Architecture 2, But, I'm using Architecture 1 because you asked to do via MediaBrowserCompat. So, you can be a little confused here.

Since exact implementation is kind of long, so I'm providing exact link where you kind find the implementation via MediaBrowserCompat way (Architecture 1) https://github.com/googlesamples/android-MediaBrowserService

I am posting basic code here based on the Architecture -- because it's a new one introduced in version 22 -- just to enough to show how you can get MediaBrowserCompat reference.

mConnectionCallbacks is the main thing that connectes MediaServiceBrowserCompat with MediaBrowserCompat. MediaBrowserCompat controls the media provided by the MediaServiceBrowserCompat. Activity, which is suitablely designed to control the media is called MediaActivity. MediaActivity uses MediaBrowserCompat to control media (eg, volume, play change etc). MediaBrowserCompat setups mConnectionCallbacks which further has onConnected() etc methods where you can put your own logic there.

public class MyMediaActivity /* can be any activity */ extends AppCompatActivity {

private MediaBrowserCompat mMediaBrowserCompat; /* your reference here */

MediaControllerCompat mediaController = MediaControllerCompat.getMediaController(MyMediaActivity.this);
MediaControllerCompat.Callback controllerCallback =
        new MediaControllerCompat.Callback() {
            @Override
            public void onMetadataChanged(MediaMetadataCompat metadata) {
            }

            @Override
            public void onPlaybackStateChanged(PlaybackStateCompat state) {
            }
        };


private MediaBrowserCompat.ConnectionCallback mConnectionCallbacks =
        new MediaBrowserCompat.ConnectionCallback() {
            @Override
            public void onConnected() {

                // Get the token for the MediaSession
                MediaSessionCompat.Token token = mMediaBrowserCompat.getSessionToken();

                // Create a MediaControllerCompat
                MediaControllerCompat mediaController =
                        null;
                try {
                    mediaController = new MediaControllerCompat(MyMediaActivity.this, // Context
                            token);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }

                // Save the controller
                MediaControllerCompat.setMediaController(MyMediaActivity.this, mediaController);

                // Finish building the UI
                buildTransportControls();
            }

            @Override
            public void onConnectionSuspended() {
                // The Service has crashed. Disable transport controls until it automatically reconnects
            }

            @Override
            public void onConnectionFailed() {
                // The Service has refused our connection
            }
        };

void buildTransportControls() {
    /* you can define your view to control music here */
    /* your stuffs here */
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // Display the initial state
    MediaMetadataCompat metadata = mediaController.getMetadata();
    PlaybackStateCompat pbState = mediaController.getPlaybackState();

    // Register a Callback to stay in sync
    mediaController.registerCallback(controllerCallback);


    mConnectionCallbacks = new MediaBrowserCompat.ConnectionCallback();

    /* your MediaBrowserCompat instance reference here*/
    mMediaBrowserCompat = new MediaBrowserCompat(this,
            new ComponentName(this, MyMediaBrowserServiceCompat.class),
            mConnectionCallbacks,
            null); // optional Bundle



/* now you can call subscribe() callbacks via mMediaBrowserCompat.subscribe(.....) anywhere inside this Activity's 
            lifecycle callbacks
             */


}

@Override
public void onStart() {
    super.onStart();
    mMediaBrowserCompat.connect();
}

@Override
public void onStop() {
    super.onStop();
    // (see "stay in sync with the MediaSession")
    if (MediaControllerCompat.getMediaController(MyMediaActivity.this) != null) {
        MediaControllerCompat.getMediaController(MyMediaActivity.this).unregisterCallback(controllerCallback);
    }


      mMediaBrowserCompat.disconnect();

    }
}

And, now, you can create MediaBrowserServiceCompat /* note MediaBrowserServiceCompat is service */ as below.

public class MyMediaBrowserServiceCompat extends MediaBrowserServiceCompat {
/* various calbacks here */
}

For more research, you can read this link, which exactly explains the logic I presented above. https://developer.android.com/guide/topics/media-apps/audio-app/building-a-mediabrowser-client.html#connect-ui-and-mediacontroller



来源:https://stackoverflow.com/questions/45027916/how-to-set-extra-page-and-extra-page-size-in-a-mediabrowserservicecompat-by-gett

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!