Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/222.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android Auto:如何在MediaBrowserService的loadChildren()上返回大量子项?_Android_Android Auto_Mediabrowserservice - Fatal编程技术网

Android Auto:如何在MediaBrowserService的loadChildren()上返回大量子项?

Android Auto:如何在MediaBrowserService的loadChildren()上返回大量子项?,android,android-auto,mediabrowserservice,Android,Android Auto,Mediabrowserservice,我目前正在尝试实现一个MediaBrowserService,为Android Auto构建一个媒体应用程序。 我遵循官方的Android Auto文档()实现了onLoadChildren函数 以下是我试图在Android自动屏幕上显示内容的代码片段: 重写有趣的onLoadChildren(parentId:String,result:result){ ... if(parentId==节点\库\相册){ val items=mutableListOf() val albumList=Lib

我目前正在尝试实现一个
MediaBrowserService
,为Android Auto构建一个媒体应用程序。 我遵循官方的Android Auto文档()实现了
onLoadChildren
函数

以下是我试图在Android自动屏幕上显示内容的代码片段:

重写有趣的onLoadChildren(parentId:String,result:result){
...
if(parentId==节点\库\相册){
val items=mutableListOf()
val albumList=LibraryManager.getAlbumList()
for(在相册列表中){
val descriptionBuilder=MediaDescriptionCompat.Builder()
.setTitle(it.albumName)
添加(MediaBrowserCompat.MediaItem(descriptionBuilder.build(),MediaBrowserCompat.MediaItem.FLAG_BROWSABLE))
}
result.sendResult(项目)
}
...
}
当项目的数量足够小时,这种方法非常有效。 但是,当项目数量较大(例如,约5000个项目)时,会出现以下错误:

E/JavaBinder: !!! FAILED BINDER TRANSACTION !!!  (parcel size = 1339384)
我发现其他几个支持Android Auto的媒体应用程序(如三星音乐)可以显示大量项目。 在
onload children
函数中是否有方法返回大量项目,或者是否有其他方法解决此问题


谢谢

可能您必须将大数据拆分为小块。例如,您有一个包含5000项的列表。因此,在您的
mediabrowservice
中,在
onLoadChildren
中执行类似的操作

 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)
}
 
public-fun-onLoadChildren(parentId:String,result:result){
if(MEDIA_ID_ROOT==parentId | | itemsList.size>100){
FillMediaBrowsablerResult(parentId,result);
}
否则{
fillMediaPlayableResult(parentId,result);
}
}
//将大量内容拆分为多个部分
private fun FillMediaBrowsablerResult(parentId:String,result:result){
//检测零件数量
val PARTSCONT=itemsList.size/100
如果(itemsList.size%100>0){
partscont++
}
val mediatems=mutableListOf()
//在循环中创建零件
for(在0中输入i,直到partsCount){
val mediasdescription=mediasdescriptioncompat.Builder()
.setMediaId(i)//当您在AA中单击它时,这是onLoadChildren中的下一个父项
.setTitle(“第${i+1}部分”)
.build();
val mediaItem=.MediaBrowserCompat.mediaItem(mediaDescription,MediaBrowserCompat.mediaItem.FLAG_BROWSABLE)
添加(mediaItem)
}
result.sendResult(mediaItems)
}
private fun fillMediaPlayableResult(parentId:String,result:result){
val intParent=parentId.toInt()
val startPosition=intParent*100//此零件的起始位置
val stopPosition=(intParent+1)*100//
如果(停止位置>项目列表大小){
stopPosition=itemsList.size
}
val mediatems=mutableListOf()
用于(i处于起始位置..停止位置){
//为此部件生成可播放的内容
val项目=项目列表[i]
val mediasdescription=mediasdescriptioncompat.Builder()
.setMediaId(项.id)
.setTitle(项.albumTitle)
.build();
val mediaItem=.MediaBrowserCompat.mediaItem(mediaDescription,MediaBrowserCompat.mediaItem.FLAG_可播放)
添加(mediaItem)
}
result.sendResult(mediaItems)
}

我没有检查这段代码,但我认为想法很清楚。

如果您查看Android SDK:

注意:Android Auto和Android Automotive操作系统对操作方式有严格限制 它们可以在菜单的每一级显示许多媒体项。这些 限制将驾驶员的注意力分散到最低程度,并帮助他们操作车辆 带有语音命令的应用程序


因此,我认为最好的方法是在用户体验设计中限制媒体项目的数量。从其他处理大量媒体项目的应用程序中,您可以看到,它们可能使用Jetpack进行处理。

您好。我也面临同样的问题。你找到解决办法了吗?@DmitriyMiyai哦,你在同一条船上。。。我找不到任何解决方案,所以我开始悬赏这个问题。我发现了为什么会发生这种情况——因为Android在发送意图数据方面的限制(1MB左右)。当您调用
result.sendResult(items)
时,它会发送在AA中显示数据的意图。我找到的解决方案是将内容分成几个小部分。例如,如果您有5000个项目,请将其划分为50个部分,并将其称为第1部分-第50部分。每个部分将包含100个项目。这并不理想,但对我来说是最好的把戏。@DmitriyMiyai是的,这是因为Android捆绑包的大小限制。但是你是如何在Android自动屏幕上将这些拆分合并成一个列表的呢?还是在屏幕上分别显示每个部分?请参见我的示例。希望您会发现它对您的案例有用这可能是一个解决方法,但它显示了“第1部分”、“第2部分”。。。第一页,用户必须查看“所有部件”菜单才能找到用户想要播放的媒体项。正如我在问题中提到的,有一些Android Auto应用程序支持显示1000多个项目而没有任何错误。因此我认为应该有一种方法来解决这个问题,而不必将数据分割成若干块。。。