Как установить EXTRA_PAGE и EXTRA_PAGE_SIZE в MediaBrowserServiceCompat, получив ссылку на Android Auto MediaBrowser?

У меня есть приложение Android Auto. Я хотел бы воспользоваться возможностью разбивки на страницы для просмотра в приложении. Кажется, что вы можете установить EXTRA_PAGE и EXTRA_PAGE_SIZE, получив ссылку на MediaBrowserCompat и передав эти константы в .subscribe(). Однако я не могу понять, как получить ссылку на MediaBrowserCompat, которую использует Android Auto Audio для вызова .subscribe().

Это кажется слишком сложным для чего-то, что должно быть простым, я просто переоцениваю вещи?

Ответ 1

Обратите внимание: Обычно в Android, когда вы видите суффикс-совместимость в конце, это новая (улучшенная) версия без совместимости.

MediaActivity - это не специальная деятельность, это своего рода деятельность, предназначенная для воспроизведения музыки. И когда вы спросили MediaBrowserCompat и MediaBrowserServiceCompat, я поменял архитектуру по умолчанию (Архитектура 2, представленная ниже), на Архитектуру 1 (ниже представленная ниже архитектура, представленная ниже в версии 22), чтобы дать точный ответ, который вы задали.

Две архитектуры:

Архитектура1)

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.

Теперь вы создали MediaController

Отсюда и обе архитектуры делают то же самое.

Архитектура2)

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.

Теперь вы создали MediaController

Отсюда и обе архитектуры делают то же самое.

Примечание. По умолчанию при создании проекта Android Auto по-прежнему используется архитектура 2, но я использую архитектуру 1, потому что вы просили сделать это через MediaBrowserCompat. Итак, вы можете быть немного смущены.

Поскольку точная реализация длинна, поэтому я предоставляю точную ссылку, где вы добьетесь реализации через MediaBrowserCompat (Архитектура 1) https://github.com/googlesamples/android-MediaBrowserService

Я размещаю базовый код здесь на основе архитектуры - потому что это новый, введенный в версии 22 - достаточно, чтобы показать, как вы можете получить ссылку MediaBrowserCompat.

mConnectionCallbacks - это главное, что связывает MediaServiceBrowserCompat с MediaBrowserCompat. MediaBrowserCompat управляет медиа, предоставленным MediaServiceBrowserCompat. Активность, подходящая для управления носителями, называется MediaActivity. MediaActivity использует MediaBrowserCompat для управления медиа (например, громкость, изменение игры и т.д.). MediaBrowserCompat настраивает mConnectionCallbacks, который также имеет методы onConnected() и т.д., где вы можете поместить свою собственную логику.

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 
            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();

    }
}

И теперь вы можете создать MediaBrowserServiceCompat/* note MediaBrowserServiceCompat - это служба */, как показано ниже.

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

Для получения дополнительной информации вы можете прочитать эту ссылку, которая точно объясняет логику, представленную выше. https://developer.android.com/guide/topics/media-apps/audio-app/building-a-mediabrowser-client.html#connect-ui-and-mediacontroller