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

主要实现功能:

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

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

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

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

通过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";

    @Override
    public 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等

            @Override
            public void onPause() {
                super.onPause();
                mediaSession.setPlaybackState(stateBuilder.setState(PlaybackState.STATE_PAUSED,mPlayer.getCurrentPosition(), 0.0f).build());
                sendBroadcast(new Intent(ACTION_PAUSE));
            }

            @Override
            public void onPlay() {
                super.onPlay();
                mediaSession.setPlaybackState(stateBuilder.setState(PlaybackState.STATE_PLAYING, mPlayer.getCurrentPosition(), 0.0f).build());
                sendBroadcast(new Intent(ACTION_PLAY_SONG));
            }

            @Override
            public void onSkipToNext() {
                super.onSkipToNext();
                sendBroadcast(new Intent(ACTION_NEXT_SONG));
            }

            @Override
            public 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() {
            @Override
            public 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.0
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            mAttribute = new AudioAttributes.Builder()
                    .setUsage(AudioAttributes.USAGE_MEDIA)
                    .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
                    .build();
        }
        //android 版本 8.0
        if (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();//启动获取音频

效果图:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值