第一句子网 - 唯美句子、句子迷、好句子大全
第一句子网 > Android 通知栏 锁屏播放音乐 类似音乐播放器

Android 通知栏 锁屏播放音乐 类似音乐播放器

时间:2021-08-03 01:26:49

相关推荐

Android 通知栏 锁屏播放音乐 类似音乐播放器

项目中需要用到播放音频的功能,想做一个类似酷狗、酷我这样的音频播放功能,在通知栏和锁屏时都可以操控音乐,开发中发现oppo reno手机在锁屏时不显示通知栏,研究了整整一天终于解决,特作记录,给遇到同样问题的童鞋做个参考。

整体功能实现思路如下:

1.播放音乐时启动前台服务,在服务中创建播放器和通知并且创建广播,音频的播控通过广播来操控,实现跨模块;

2.在切换音频源、播放、暂停的时候通过重新创建通知来实现通知的界面更新;

3.在关闭音频功能时关掉通知,释放播放器。

细节,以下只做简单说明,具体实现方式请百度,本文只是为了解决锁屏不显示通知的问题,已测试正常使用的机型有华为、荣耀、oppo:

1.通知的自定义view为remoteView;

2.通知创建时需要判断8.0渠道配置:

private fun createChannel(context: Context, channel_id: String, channel_name: CharSequence, description: String) {//8.0以上版本通知适配if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {val notificationChannel = NotificationChannel(channel_id, channel_name, NotificationManager.IMPORTANCE_HIGH)notificationChannel.setSound(null, null)notificationChannel.enableLights(false) //通知灯notificationChannel.lightColor = Color.RED // 通知灯颜色notificationChannel.setShowBadge(false) //角标notificationChannel.lockscreenVisibility = Notification.VISIBILITY_PUBLIC // 所有情况下显示,包括锁屏notificationChannel.description = descriptionval notificationManager = context.getSystemService(NotificationManager::class.java)notificationManager.createNotificationChannel(notificationChannel)}}/*** 返回一个前台通知** @param channel_id 通知渠道id,注意8.0创建通知的时候渠道id与此要匹配* @param remoteViews 自定义通知view* @return*/fun createForeNotification(context: Context, channel_id: String, channel_name: CharSequence, description: String, remoteViews: RemoteViews): Notification {CreateChannel(context, channel_id, channel_name, description)val builder = NotificationCompat.Builder(context, channel_id).setSmallIcon(R.mipmap.ic_launcher) //最顶部的小图标.setContent(remoteViews).setAutoCancel(true) // 允许自动清除.setPriority(NotificationCompat.PRIORITY_MAX).setSound(Uri.EMPTY) //声音.setDefaults(NotificationCompat.DEFAULT_ALL) //统一消除声音和震动.setVisibility(Notification.VISIBILITY_PUBLIC) // 所有情况下显示,包括锁屏return builder.build()}

3.对通知设置点击事件,切换、暂停、播放的原理一样,如果别的模块需要调用播控的话直接发送广播即可:

// 暂停val pauseIntent = Intent(AudioBroadCastReceiver.PAUSE)val pausePendingIntent = PendingIntent.getBroadcast(this, 0, pauseIntent, 0)notifyLayout.setOnClickPendingIntent(R.id.iv_music_pause, pausePendingIntent)// 播放val playIntent = Intent(AudioBroadCastReceiver.PLAY)val playPendingIntent = PendingIntent.getBroadcast(this, 0, playIntent, 0)notifyLayout.setOnClickPendingIntent(R.id.iv_music_play, playPendingIntent)

object AudioBroadCastReceiver : BroadcastReceiver() {private val TAG = javaClass.simpleNameconst val PLAY_PRE = "com.audio.PLAY_PRE"const val PLAY_NEXT = "com.audio.PLAY_NEXT"const val PLAY = "com.audio..PLAY"const val PAUSE = "com.audio.PAUSE"// 停止播放器、关闭通知、关闭服务、关掉播放界面const val CLOSE = "com.audio.CLOSE"var receiveListener: ((Context, Intent?) -> Unit)? = nulloverride fun onReceive(context: Context, intent: Intent?) {Logger.d(TAG, "onReceive: ${intent?.action}")val audioPlayerHelper = App.get().audioPlayerHelperintent?.let {when (it.action) {PLAY_PRE -> {Logger.d(TAG, "onReceive: 上一节")audioPlayerHelper.playPre()}PLAY_NEXT -> {Logger.d(TAG, "onReceive: 下一节")audioPlayerHelper.playNext()}PLAY -> {Logger.d(TAG, "onReceive: 播放")audioPlayerHelper.play()}PAUSE -> {Logger.d(TAG, "onReceive: 暂停")audioPlayerHelper.pause()}CLOSE -> {Logger.d(TAG, "onReceive: 停止")audioPlayerHelper.stop()}else -> {}}receiveListener?.invoke(context,intent)}}}

4.服务中启动通知:

startForeground(AudioNotifyHelper.NOTIFY_ID, notification)

5.监听锁屏,我遇到的问题就是在oppo手机上锁屏不显示通知,其实解决办法就是监听锁屏,在锁屏后再次发送一次通知即可:

public class HomeWatcherReceiver extends BroadcastReceiver {private final String TAG = getClass().getSimpleName();private static final String SYSTEM_DIALOG_REASON_KEY = "reason";private static final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps";private static final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey";private static final String SYSTEM_DIALOG_REASON_LOCK = "lock";private static final String SYSTEM_DIALOG_REASON_ASSIST = "assist";private PhysicalKeyListener listener;@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();Logger.i(TAG, "onReceive: action: " + action);if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {// android.intent.action.CLOSE_SYSTEM_DIALOGSString reason = intent.getStringExtra(SYSTEM_DIALOG_REASON_KEY);Logger.i(TAG, "reason: " + reason);if (SYSTEM_DIALOG_REASON_HOME_KEY.equals(reason)) {// 短按Home键Logger.i(TAG, "homekey");if(listener != null){listener.onHome();}} else if (SYSTEM_DIALOG_REASON_RECENT_APPS.equals(reason)) {// 长按Home键 或者 activity切换键Logger.i(TAG, "long press home key or activity switch");if(listener != null){listener.onRecentApp();}} else if (SYSTEM_DIALOG_REASON_LOCK.equals(reason)) {// 锁屏Logger.i(TAG, "lock");if(listener != null){listener.onLock();}} else if (SYSTEM_DIALOG_REASON_ASSIST.equals(reason)) {// samsung 长按Home键Logger.i(TAG, "assist");if(listener != null){listener.onAssist();}}} else if (Intent.ACTION_SCREEN_ON.equals(action)) { // 开屏Logger.i(TAG, "onReceive: 开屏");if(listener != null){listener.onScreenOn();}} else if (Intent.ACTION_SCREEN_OFF.equals(action)) { // 锁屏Logger.i(TAG, "onReceive: 锁屏");if(listener != null){listener.onScreenOff();}} else if (Intent.ACTION_USER_PRESENT.equals(action)) { // 解锁Logger.i(TAG, "onReceive: 解锁");if(listener != null){listener.onUserPresent();}}}public void setListener(PhysicalKeyListener listener) {this.listener = listener;}}

6.在服务中注册锁屏广播监听,监听到锁屏再发一次通知即可。

至此,仿音乐播放器的通知栏和锁屏操控音乐就OK了,如果有特殊机型或者其他情况不管用的,评论区咱们互相讨论、学习。

共勉!

效果如下:

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。