关于音乐播放器与系统功能联动功能梳理

2024-06-08 22:20

本文主要是介绍关于音乐播放器与系统功能联动功能梳理,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

主要实现功能:

一、通知栏播放显示和控制

二、系统下拉栏中播放模块显示同步

三、与其他播放器状态同步:本应用播放时暂停其他应用播放,进入其他应用播放时,暂停本应用的后台播放

通知栏播放的显示和控制:

通过Notification + RemoteViews + 广播实现,主要代码如下:
    /*** 初始化自定义通知栏 的按钮点击事件*/private void initRemoteViews() {remoteViews = new RemoteViews(this.getPackageName(), R.layout.notification);//通知栏控制器上一首按钮广播操作Intent intentPrev = new Intent(ACTION_PRE_SONG);PendingIntent prevPendingIntent = PendingIntent.getBroadcast(this, 5100, intentPrev, PendingIntent.FLAG_CANCEL_CURRENT);//为prev控件注册事件remoteViews.setOnClickPendingIntent(R.id.btn_notification_previous, prevPendingIntent);//通知栏控制器播放暂停按钮广播操作  //用于接收广播时过滤意图信息Intent intentPlay = new Intent(ACTION_PAUSE);PendingIntent playPendingIntent = PendingIntent.getBroadcast(this, 5101, intentPlay, PendingIntent.FLAG_CANCEL_CURRENT);//为play控件注册事件remoteViews.setOnClickPendingIntent(R.id.btn_notification_play, playPendingIntent);//通知栏控制器下一首按钮广播操作Intent intentNext = new Intent(ACTION_NEXT_SONG);PendingIntent nextPendingIntent = PendingIntent.getBroadcast(this, 5102, intentNext, PendingIntent.FLAG_CANCEL_CURRENT);//为next控件注册事件remoteViews.setOnClickPendingIntent(R.id.btn_notification_next, nextPendingIntent);//通知栏控制器关闭按钮广播操作Intent intentClose = new Intent(ACTION_PLAY_CLOSE);PendingIntent closePendingIntent = PendingIntent.getBroadcast(this, 5103, intentClose, 0);//为close控件注册事件remoteViews.setOnClickPendingIntent(R.id.btn_notification_close, closePendingIntent);}/*** 初始化通知*/@SuppressLint("NotificationTrampoline")private void initNotification() {String channelId = "play_control";String channelName = "播放控制";int importance = NotificationManager.IMPORTANCE_HIGH;createNotificationChannel(channelId, channelName, importance);//点击整个通知时发送广播Intent intent = new Intent(getApplicationContext(), NotificationClickReceiver.class);PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0,intent, FLAG_UPDATE_CURRENT);//初始化通知notification = new NotificationCompat.Builder(this, "play_control").setContentIntent(pendingIntent).setWhen(System.currentTimeMillis()).setSmallIcon(R.mipmap.ic_launcher).setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))//   .setCustomContentView(remoteViews).setCustomBigContentView(remoteViews).setVisibility(NotificationCompat.VISIBILITY_PUBLIC)// .setStyle(new NotificationCompat.BigTextStyle())//  .setStyle(new NotificationCompat.InboxStyle()).setDefaults(NotificationCompat.DEFAULT_ALL).setAutoCancel(false).setOnlyAlertOnce(true).setOngoing(true).build();}/*** 创建通知渠道** @param channelId   渠道id* @param channelName 渠道名称* @param importance  渠道重要性*/@TargetApi(Build.VERSION_CODES.O)private void createNotificationChannel(String channelId, String channelName, int importance) {NotificationChannel channel = new NotificationChannel(channelId, channelName, importance);channel.enableLights(false);channel.enableVibration(false);channel.setVibrationPattern(new long[]{0});channel.setSound(null, null);manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);manager.createNotificationChannel(channel);}

通知栏整体点击跳转到播放界面:注册全局监听广播

public class NotificationClickReceiver extends BroadcastReceiver {public static final String TAG = "NotificationClickReceiver";@Overridepublic void onReceive(Context context, Intent intent) {LogUtil.showLog(TAG,"通知栏点击");//获取栈顶的Activity// Activity currentActivity = ActivityManager.getCurrentActivity();intent = new Intent(Intent.ACTION_MAIN);intent.addCategory(Intent.CATEGORY_LAUNCHER);intent.setClass(context, MusicPlayerActivity.class);intent.putExtra("from","notify");// intent.putExtra("file",MyApplication.currentPlayMusic);intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);context.startActivity(intent);}
}

系统下拉栏媒体播放信息和状态同步:

通过MediaSession + MediaMetadata + PlaybackState实现

public void initMediaSession(){mediaSession = new MediaSession(this, "music_player_session");mediaSession.setCallback(new MediaSession.Callback() {// 覆盖必要的回调方法,如onPlay, onPause等@Overridepublic void onPause() {super.onPause();mediaSession.setPlaybackState(stateBuilder.setState(PlaybackState.STATE_PAUSED,mPlayer.getCurrentPosition(), 0.0f).build());sendBroadcast(new Intent(ACTION_PAUSE));}@Overridepublic void onPlay() {super.onPlay();mediaSession.setPlaybackState(stateBuilder.setState(PlaybackState.STATE_PLAYING, mPlayer.getCurrentPosition(), 0.0f).build());sendBroadcast(new Intent(ACTION_PLAY_SONG));}@Overridepublic void onSkipToNext() {super.onSkipToNext();sendBroadcast(new Intent(ACTION_NEXT_SONG));}@Overridepublic void onSkipToPrevious() {super.onSkipToPrevious();sendBroadcast(new Intent(ACTION_PRE_SONG));}});mediaSession.setActive(true);metaDataBuilder = new MediaMetadata.Builder();//播放状态stateBuilder = new PlaybackState.Builder();stateBuilder.setActions(PlaybackState.ACTION_PLAY | PlaybackState.ACTION_PAUSE| PlaybackState.ACTION_SKIP_TO_NEXT | PlaybackState.ACTION_SKIP_TO_PREVIOUS);}

状态和信息同步:

    /*** 更改通知的信息和UI*/private Intent intentPlay;private PendingIntent playPendingIntent;public void updateNotificationShow() {//通知栏控制器播放暂停按钮广播操作  //用于接收广播时过滤意图信息intentPlay = new Intent(mPlayer.isPlaying()?ACTION_PAUSE:ACTION_PLAY_SONG);playPendingIntent = PendingIntent.getBroadcast(this, 5101, intentPlay, PendingIntent.FLAG_CANCEL_CURRENT);//为play控件注册事件remoteViews.setOnClickPendingIntent(R.id.btn_notification_play, playPendingIntent);//播放状态判断if (mPlayer.isPlaying()) {remoteViews.setImageViewResource(R.id.btn_notification_play, R.mipmap.notify_pause);} else {remoteViews.setImageViewResource(R.id.btn_notification_play, R.mipmap.notify_play);}//封面专辑remoteViews.setImageViewResource(R.id.iv_album_cover,R.mipmap.ic_launcher);//歌曲名remoteViews.setTextViewText(R.id.tv_notification_song_name,defaultSongName.substring(0,defaultSongName.lastIndexOf(".")));//歌手名remoteViews.setTextViewText(R.id.tv_notification_singer,"");remoteViews.setTextViewText(R.id.tv_duration,StringUtil.formatDuration(mPlayer.getDuration()));remoteViews.setTextViewText(R.id.tv_current_time,StringUtil.formatDuration(mPlayer.getCurrentPosition()));if(mPlayer.getDuration() > 0)remoteViews.setProgressBar(R.id.seekbar,100,mPlayer.getCurrentPosition()*100/mPlayer.getDuration(),false);//发送通知manager.notify(NOTIFICATION_ID,notification);WindowUtils.isNotifyShow = true;//同步下拉栏播放控制区信息metaDataBuilder.putString(MediaMetadata.METADATA_KEY_TITLE,defaultSongName.substring(0,defaultSongName.lastIndexOf(".")));mediaSession.setMetadata(metaDataBuilder.build());}

与其他应用播放器状态同步

通过AudioManager监听onAudioFocusChange音频焦点变化实现

 /** 监测其他应用播放音视频 */mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);mListener = new AudioManager.OnAudioFocusChangeListener() {@Overridepublic void onAudioFocusChange(int focusChange) {LogUtil.showLog(TAG,"==onAudioFocusChange=="+focusChange);abandonAudioFocus(); //禁用音频sendBroadcast(new Intent(ACTION_PAUSE));switch (focusChange) {case AudioManager.AUDIOFOCUS_GAIN:// TBD 继续播放break;case AudioManager.AUDIOFOCUS_LOSS:// TBD 停止播放break;case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:// TBD 暂停播放break;case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:// TBD 混音播放break;default:break;}}};//android 版本 5.0if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {mAttribute = new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_MEDIA).setContentType(AudioAttributes.CONTENT_TYPE_MUSIC).build();}//android 版本 8.0if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {mFocusRequest = new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN_TRANSIENT).setWillPauseWhenDucked(true).setAcceptsDelayedFocusGain(true).setOnAudioFocusChangeListener(mListener, mHandler).setAudioAttributes(mAttribute).build();}requestAudioFocus();//启动获取音频

效果图:

这篇关于关于音乐播放器与系统功能联动功能梳理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1043469

相关文章

通信系统网络架构_2.广域网网络架构

1.概述          通俗来讲,广域网是将分布于相比局域网络更广区域的计算机设备联接起来的网络。广域网由通信子网于资源子网组成。通信子网可以利用公用分组交换网、卫星通信网和无线分组交换网构建,将分布在不同地区的局域网或计算机系统互连起来,实现资源子网的共享。 2.网络组成          广域网属于多级网络,通常由骨干网、分布网、接入网组成。在网络规模较小时,可仅由骨干网和接入网组成

硬件基础知识——自学习梳理

计算机存储分为闪存和永久性存储。 硬盘(永久存储)主要分为机械磁盘和固态硬盘。 机械磁盘主要靠磁颗粒的正负极方向来存储0或1,且机械磁盘没有使用寿命。 固态硬盘就有使用寿命了,大概支持30w次的读写操作。 闪存使用的是电容进行存储,断电数据就没了。 器件之间传输bit数据在总线上是一个一个传输的,因为通过电压传输(电流不稳定),但是电压属于电势能,所以可以叠加互相干扰,这也就是硬盘,U盘

android 免费短信验证功能

没有太复杂的使用的话,功能实现比较简单粗暴。 在www.mob.com网站中可以申请使用免费短信验证功能。 步骤: 1.注册登录。 2.选择“短信验证码SDK” 3.下载对应的sdk包,我这是选studio的。 4.从头像那进入后台并创建短信验证应用,获取到key跟secret 5.根据技术文档操作(initSDK方法写在setContentView上面) 6.关键:在有用到的Mo

android一键分享功能部分实现

为什么叫做部分实现呢,其实是我只实现一部分的分享。如新浪微博,那还有没去实现的是微信分享。还有一部分奇怪的问题:我QQ分享跟QQ空间的分享功能,我都没配置key那些都是原本集成就有的key也可以实现分享,谁清楚的麻烦详解下。 实现分享功能我们可以去www.mob.com这个网站集成。免费的,而且还有短信验证功能。等这分享研究完后就研究下短信验证功能。 开始实现步骤(新浪分享,以下是本人自己实现

Android我的二维码扫描功能发展史(完整)

最近在研究下二维码扫描功能,跟据从网上查阅的资料到自己勉强已实现扫描功能来一一介绍我的二维码扫描功能实现的发展历程: 首页通过网络搜索发现做android二维码扫描功能看去都是基于google的ZXing项目开发。 2、搜索怎么使用ZXing实现自己的二维码扫描:从网上下载ZXing-2.2.zip以及core-2.2-source.jar文件,分别解压两个文件。然后把.jar解压出来的整个c

vue+elementUI下拉框联动显示

<el-row><el-col :span="12"><el-form-item label="主账号:" prop="partyAccountId" :rules="[ { required: true, message: '主账号不能为空'}]"><el-select v-model="detailForm.partyAccountId" filterable placeholder="

Linux系统稳定性的奥秘:探究其背后的机制与哲学

在计算机操作系统的世界里,Linux以其卓越的稳定性和可靠性著称,成为服务器、嵌入式系统乃至个人电脑用户的首选。那么,是什么造就了Linux如此之高的稳定性呢?本文将深入解析Linux系统稳定性的几个关键因素,揭示其背后的技术哲学与实践。 1. 开源协作的力量Linux是一个开源项目,意味着任何人都可以查看、修改和贡献其源代码。这种开放性吸引了全球成千上万的开发者参与到内核的维护与优化中,形成了

人工智能做音乐

0 别人做的音乐demo https://yun.baidu.com/share/link?shareid=1799925478&uk=840708891 1 为什么人工智能能做音乐? 最下面蓝色的部分是你输入的音乐。 从上图可以看出,input是一个个的点,然后通过input来相互结合生成灰色的点,经过几层的连接之后,最后的Output就是新生成的音乐,也就是黄色的点。 把黄色的点

开启青龙 Ninja 扫码功能失效后修改成手动填写CK功能【修正Ninja拉库地址】

国内:进入容器docker exec -it qinglong bash #获取ninjagit clone -b main https://ghproxy.com/https://github.com/wjx0428/ninja.git /ql/ninja#安装cd /ql/ninja/backend && pnpm install cp .env.example .env

【机器学习】半监督学习可以实现什么功能?

目录 一、什么是机器学习二、半监督学习算法介绍三、半监督学习算法的应用场景四、半监督学习可以实现什么功能? 一、什么是机器学习 机器学习是一种人工智能技术,它使计算机系统能够从数据中学习并做出预测或决策,而无需明确编程。它涉及到使用算法和统计模型来分析大量数据,识别其中的模式和关系,并利用这些信息来预测未来事件或做出决策。机器学习可以应用于各种领域,包括图像识别、自然语言