ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

android车载应用--蓝牙音乐开发

android车载应用--蓝牙音乐开发 车机蓝牙音乐核心是通过绑定蓝牙媒体服务来实现车机与手机的交互核心代码//当前播放的音乐信息varplayMusicInfoMutableStateFlowMediaMetadata?(null)//播放状态varplaybackStateMutableStateFlowPlaybackState?(null)//媒体浏览服务privatevarmMediaBrowser:MediaBrowser?null//媒体控制器privatevarmediaController:MediaController?null//记录播放状态用于下次连接时候做是否播放的处理varisNeedPlaytrue//是否是连接之后第一次获取信息varfirstInfoAfterConnectfalsefuninitMediaBrowser(){val packageNamecom.android.bluetoothval classNamecom.android.bluetooth.avrcpcontroller.BluetoothMediaBrowserService//1.待连接的服务val componentNameComponentName(packageName,className)//2.创建MediaBrowsermMediaBrowserMediaBrowser(App.context,componentName,mConnectionCallbacks,null)//3.建立连接mMediaBrowser!!.connect()mMediaBrowser!!.subscribe(music,object:MediaBrowser.SubscriptionCallback(){override funonChildrenLoaded(parentId:String,children:ListMediaBrowser.MediaItem?){super.onChildrenLoaded(parentId,children)}override funonChildrenLoaded(parentId:String,children:ListMediaBrowser.MediaItem?,options:Bundle){super.onChildrenLoaded(parentId,children,options)}override funonError(parentId:String){super.onError(parentId)}override funonError(parentId:String,options:Bundle){super.onError(parentId,options)}})}fundisconnect(){mMediaBrowser?.disconnect()mMediaBrowsernull}privateval mConnectionCallbacks:MediaBrowser.ConnectionCallbackobject:MediaBrowser.ConnectionCallback(){override funonConnected(){Log.d(TAG,onConnected)//连接成功回调// Get the token for the MediaSessionval token:MediaSession.TokenmMediaBrowser!!.sessionToken// Create a MediaControllerCompatmediaControllerMediaController(App.context,// Contexttoken)// Register a Callback to stay in syncmediaController!!.registerCallback(controllerCallback)if(isNeedPlay){mediaController?.transportControls?.play()}}override funonConnectionSuspended(){//连接中断回调Log.d(TAG,onConnectionSuspended)}override funonConnectionFailed(){//连接失败回调Log.d(TAG,onConnectionFailed)}}varcontrollerCallback:MediaController.Callbackobject:MediaController.Callback(){override funonSessionDestroyed(){//Session销毁}override funonMetadataChanged(metadata:MediaMetadata?){Log.i(TAG,metadata $metadata)playMusicInfo.valuemetadata}override funonPlaybackStateChanged(state:PlaybackState?){playbackState.valuestateif(state!nullplayMusicInfo.value!null){if(state.statePlaybackState.STATE_PLAYING){isNeedPlaytrue}elseif(state.statePlaybackState.STATE_PAUSED){isNeedPlayfalse}}}override funonAudioInfoChanged(info:MediaController.PlaybackInfo?){super.onAudioInfoChanged(info)}}/** * 播放 */funplay(){Log.i(TAG,play)mediaController?.transportControls?.play()}/** * 暂停 */funpause(){Log.i(TAG,pause)mediaController?.transportControls?.pause()}/** * 下一曲 */funnext(){Log.i(TAG,next)mediaController?.transportControls?.skipToNext()}/** * 上一曲 */funprev(){Log.i(TAG,prev)mediaController?.transportControls?.skipToPrevious()}/** * 拖到到指定进度 */funseekTo(pos:Long){Log.i(TAG,seekTo:pos $pos)mediaController?.transportControls?.seekTo(pos)}媒体数据解析 常用//标题 部分音乐软件也是通过这个展示歌词MediaMetadata.METADATA_KEY_TITLE//专辑名MediaMetadata.METADATA_KEY_ALBUM//歌手MediaMetadata.METADATA_KEY_ARTIST)//总时长MediaMetadata.METADATA_KEY_DURATION//封面MediaMetadata.METADATA_KEY_ALBUM_ART_URI
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进