简体   繁体   中英

Android Auto: How to return a large number of children on loadChildren() of MediaBrowserService?

I am currently trying to implement a MediaBrowserService to build a media app for Android Auto. I followed the official Android Auto documentation ( https://developer.android.com/training/cars/media#onLoadChildren ) to implement the onLoadChildren function.

Following is a code snippet that I tried to show the content on the Android Auto screen:

override fun onLoadChildren(parentId: String, result: Result<MutableList<MediaBrowserCompat.MediaItem>>) {
  ...
  if (parentId == NODE_LIBRARY_ALBUMS) {
    val items = mutableListOf<MediaBrowserCompat.MediaItem>()

    val albumList = LibraryManager.getAlbumList()
    for (it in albumList) {
      val descriptionBuilder = MediaDescriptionCompat.Builder()
        .setTitle(it.albumName)
      items.add(MediaBrowserCompat.MediaItem(descriptionBuilder.build(), MediaBrowserCompat.MediaItem.FLAG_BROWSABLE))
    }

    result.sendResult(items)
  }
  ...
}

This works pretty well, when the number of items is small enough. However, when the number of items is large (eg, about 5,000 items), the following error appears:

E/JavaBinder: !!! FAILED BINDER TRANSACTION !!!  (parcel size = 1339384)

I found that several other media apps (eg, Samsung Music) that support Android Auto can show a large number of items. Is there any way to return a large number of items on the onLoadChildren function, or is there any other way to solve this issue?

Thanks!

Probably you have to split the large data into a small pieces. For example, you have a list of 5000 items. So inside you MediaBrowserService in onLoadChildren do something like this

 public fun onLoadChildren(parentId: String, result: Result<List<MediaBrowserCompat.MediaItem>>) {
       
    if (MEDIA_ID_ROOT == parentId || itemsList.size > 100) {
        fillMediaBrowsableResult(parentId, result);
    }
    else {
        fillMediaPlayableResult(parentId, result);
    }
}


//Split the large number of content to a parts
private fun fillMediaBrowsableResult(parentId: String, result: Result<List<MediaBrowserCompat.MediaItem>>) {

    // Detect count of parts
    val partsCount = itemsList.size / 100
    if(itemsList.size % 100 > 0){
        partsCount ++
    }
    val mediaItems = mutableListOf<MediaBrowserCompat.MediaItem>()
    //Create parts in a loop
    for(i in 0 until partsCount){
        
         val mediaDescription = MediaDescriptionCompat.Builder()
                .setMediaId(i) // This is your next parent in onLoadChildren when you click on it in AA
                .setTitle("Part ${i + 1}")
                .build();

        val mediaItem =. MediaBrowserCompat.MediaItem(mediaDescription, MediaBrowserCompat.MediaItem.FLAG_BROWSABLE)
        mediaItems.add(mediaItem)
    }
    result.sendResult(mediaItems)
}

private fun fillMediaPlayableResult(parentId: String, result: Result<List<MediaBrowserCompat.MediaItem>>){

    val intParent = parentId.toInt()
    val startPosition = intParent * 100 // where to start for this part
    val stopPosition = (intParent + 1) * 100 // where to finish for this part
    if(stopPosition > itemsList.size){
        stopPosition = itemsList.size 
    }
    
    val mediaItems = mutableListOf<MediaBrowserCompat.MediaItem>()
    for(i in startPosition..stopPosition){
        //Generate playable content for this part
        val item = itemsList[i]
        val mediaDescription = MediaDescriptionCompat.Builder()
                    .setMediaId(item.id)
                    .setTitle(item.albumTitle)
                    .build();
        val mediaItem =. MediaBrowserCompat.MediaItem(mediaDescription, MediaBrowserCompat.MediaItem.FLAG_PLAYABLE)
        mediaItems.add(mediaItem)
    }
    result.sendResult(mediaItems)
}
 

I didn't check this code, but I think the idea is clear.

If you look into Android SDK document :

Note: Android Auto and Android Automotive OS have strict limits on how many media items they can display in each level of the menu. These limits minimize distractions for drivers and help them operate your app with voice commands. ...

So, I think the best approach is to limit # of media items in UX design. For what you saw from the other apps working with lots of media items, they might used Jetpack Media 2 for pagination .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM