1.在线播放音乐
private fun playMusic(url:String){
player = MediaPlayer()
player.setDataSource(url)
player.prepareAsync()
}
创建MediaPlayer类,音频地址url当参数传入,
setDataSource(url) 获取地址对应资源
prepare() 同步为播放器的回放做准备
prepareAsync()异步地为播放器的回放做准备。
设置数据源和显示表面之后,需要调用prepare()或prepareAsync()。对于流,应该调用prepareAsync(),它会立即返回,而不是阻塞,直到缓冲了足够的数据。
start() 开启音乐
stop()暂停音乐
音乐资源一加载好自动播放的接口
1.1完全写法 ->重写OnPrepared方法
MediaPlayer.setOnPreparedListener {object : OnPreparedListener {
override fun onPrepared(mp: MediaPlayer?) {
if (mp != null) {
mp.start()
}
}
}
}
1.2 lamda表达式化简
MediaPlayer.setOnPreparedListener { it.start() }
2.支持后台播放音乐
2.1 创建 继承Service类,
可以在四个生命周期中添加操作
2.2在Android.Manifest文件的 Application内,Activity外 注册如下
<service android:name=".Service实例化名称"/>
如图
2.3目的:Service可以进行后台播放
在Service类里面进行MediaPlayer的播放操作
3.Notification 通知栏设置
3.1 申请权限
3.1.1 声明权限 Manifest 中 ,application外添加
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
3.1.2 前提
版本<33的不需要申请权限 只需要声明权限即可,>=33的就必须自己申请权限
3.1.3 判断权限存在
第一个判断 本项目 SDK是不小于33,第二个判断有没有申请到指定的权限
fun notification(){
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU){
val result = checkSelfPermission(Manifest.permission.POST_NOTIFICATIONS)
if (result != PackageManager.PERMISSION_GRANTED)
3.1.4开始申请权限
获取launcher进行动态申请权限,并且在获取laucher中可以添加有权限或无该权限的相应操作
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
val result = checkSelfPermission(Manifest.permission.POST_NOTIFICATIONS)
if (result != PackageManager.PERMISSION_GRANTED){ //没有权限
val launcher = registerForActivityResult(ActivityResultContracts.RequestPermission()){
if (it){
//申请到权限了
}else{
//用户拒绝授权
}
}
launcher.launch(Manifest.permission.POST_NOTIFICATIONS)
}
}
3.2 创建通知的通道
3.2.1 准备id,name,notificationManager
val channel_id = "channel_music_id"
val channel_name = "channel_name_playmusic"
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
3.2.2 动态申请权限并创建通道
只有SDK 26以上才能创建通道
传id,name,重要程度,最后createNotificationChannel()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel =
NotificationChannel(channel_id, channel_name, NotificationManager.IMPORTANCE_HIGH)
notificationManager.createNotificationChannel(channel)
}
3.3 创建通知栏本体
notify告诉程序 有这个通知栏,第一个可以不传的tag,第二三个分别是必须传的 新id ,与配置好资源的NotificationCompat
val mNotification = NotificationCompat.Builder(this,channel_id)
.setSmallIcon(com.google.android.material.R.drawable.design_ic_visibility)
.setContentTitle("网易云音乐")
.setContentText("向云端")
.build()
notificationManager.notify(1,mNotification)
4.Broadcast ——传消息和事件的工具
4.1 注册一个广播
创建一个继承 BroadcastReceiver的类,重写onReceive()
class PlayMusicReceiver(private val callback:(Boolean)->Unit):BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
val isPlay = intent!!.getBooleanExtra("EXTRA",true)
callback(isPlay)
}
}
在Service中获取刚创建的 BroadcastReceiver和传入了与之前Intent内部action相同的IntentFilter,进行判断可以注册后,调用registerReceiver()注册Broadcast
fun createReceiver(){
val intentFilter = IntentFilter("com.example.zj_action")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU){
registerReceiver(mReceiver,intentFilter,Context.RECEIVER_EXPORTED)
}else{
registerReceiver(mReceiver,intentFilter)
}
}
4.2 发送广播
自带sendBroacast(),传入一个Intent(action)即可 ,悄悄说,action是自己取名字当标识符
Intent.putExtra()可以传递额外值给目标
fun playBroadcast(){
val intent = Intent("com.example.zj_action")
intent.putExtra("EXTRA",true)
sendBroadcast(intent)
}
4.3 接收广播
Receiver类中通过高阶函数callback回调了Blooean值,再传递给PlayMusicReceiver的实例化类中
mReceiver = PlayMusicReceiver{
if (it){
playMusic("音频的url地址")
}else{
player.stop()
}
}
createReceiver()
5. EventBus
实现一发对多收,且可以选择不收
5.1 导入依赖库
implementation("org.greenrobot:eventbus:3.3.1")
5.2 定义一个事件对应的类
class ChangeColorEvent(val color:Int) {}
5.3 发送事件
EventBus.getDefault().post(ChangeColorEvent(Color.MAGENTA))
5.4 注册,订阅事件,取消注册
一开始创建时就register,整个部分结束时再unregister
记得加Subscribe注解,最后将event以参数形式传入
init {
//注册EventBus
EventBus.getDefault().register(this)
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
//取消EventBus事件订阅
EventBus.getDefault().unregister(this)
}
@Subscribe(threadMode = ThreadMode.MAIN)
fun changeColor(event:ChangeColorEvent){
setTextColor(event.color)
}