最近在做一个Flutter的音乐播放器,遇到了需要蓝牙耳机控制的需求,查了一下网上的相关资料,并没有针对没有安卓开发经验的开发者的文档,大部分文章都未一针见血的提出解决方案。其实在从 Android 4.0(API 级别 14)开始,系统可以访问媒体会话的播放状态和元数据。此功能可让锁定屏幕显示媒体控件和海报图片。原生安卓中使用MediaSeesion实现类似耳机控制的功能。 那么话不多说,我们直接上代码。 本次使用到了audio_service这个插件。不选择使用just_audio_background是因为适用度不够高,虽然其相对简单。audio_service支持与其他的音乐播放插件兼容,因此不用对代码进行大量的删改,比较简单。
插件链接:https://pub.dev/packages/audio_service
安装:flutter pub add audio_service
首先先初始化,并且实现相应的回调方法
class MyAudioHandler extends BaseAudioHandler
with QueueHandler, // mix in default queue callback implementations
SeekHandler { // 混合使用默认的查找回调实现
// The most common callbacks:
Future<void> play() async {
// 所有“播放”都来源于此. 记得实现此方法
// 此回调方法会开始播放您的音频
}
Future<void> pause() async {}
Future<void> stop() async {}
Future<void> seek(Duration position) async {}
Future<void> skipToQueueItem(int i) async {}
}
//注:代码来源于https://pub.dev/packages/audio_service
第二步,在Main函数中注册
Future<void> main() async {
// 将其存储在单例中
_audioHandler = await AudioService.init(
builder: () => MyAudioHandler(),
config: AudioServiceConfig(
androidNotificationChannelId: 'com.mycompany.myapp.channel.audio',
androidNotificationChannelName: 'Music playback',
),
);
runApp(new MyApp());
}
然后设置音源
var item = MediaItem(
id: 'https://example.com/audio.mp3',
album: 'Album name',
title: 'Track title',
artist: 'Artist name',
duration: const Duration(milliseconds: 123456),
artUri: Uri.parse('https://example.com/album.jpg'),
);
_audioHandler.playMediaItem(item);
_audioHandler.playFromSearch(queryString);
_audioHandler.playFromUri(uri);//从URI中播放
_audioHandler.playFromMediaId(id);//根据ID播放音乐
基础的控制
_audioHandler.play();
_audioHandler.seek(Duration(seconds: 10));
_audioHandler.setSpeed(1.5);
_audioHandler.pause();
_audioHandler.stop();
最后修改配置文件
<manifest xmlns:tools="http://schemas.android.com/tools" ...>
<!-- 添加这两个权限 -->
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<application ...>
...
<!-- 编辑现有“Activity”元素中的android:name属性 -->
<activity android:name="com.ryanheise.audioservice.AudioServiceActivity" ...>
...
</activity>
<!-- 添加这个service -->
<service android:name="com.ryanheise.audioservice.AudioService"
android:foregroundServiceType="mediaPlayback"
android:exported="true" tools:ignore="Instantiatable">
<intent-filter>
<action android:name="android.media.browse.MediaBrowserService" />
</intent-filter>
</service>
<!-- 添加这个receiver -->
<receiver android:name="com.ryanheise.audioservice.MediaButtonReceiver"
android:exported="true" tools:ignore="Instantiatable">
<intent-filter>
<action android:name="android.intent.action.MEDIA_BUTTON" />
</intent-filter>
</receiver>
</application>
</manifest>