Notification——形形色色的通知(二)

  上一章写到如何发出一个通知。但是,通知既然作为一个View,它应该能与我们的业务逻辑有一系列交互。比如,我们可以通过Notification的remoteview中的Button控制一下业务逻辑(如播放/暂停音乐),或者用进度条显示后台操作的进度。在此我写了一个简单的音乐播放器。我们能够在Notification的remoteview中的Button,控制音乐的播放,通过其中的进度条,得知播放音乐的进度。

  Notification的初始化为

    private void initNotification(){

        Intent intentService = new Intent(this , MusicPlayService.class);
        // 开启音乐Service
        this.startService(intentService);

        String notifyTitle = "这是消息的标题";
        String notifyContent = "这是消息的内容";
        // 建立点击Intent
        Intent intent = new Intent(this , NotifyDesActivity.class);
        intent.putExtra("title" , notifyTitle);
        intent.putExtra("content", notifyContent);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, NOTIFY_DES, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        // 将notification的布局引入
        remoteViews = new RemoteViews(getPackageName() , R.layout.notify_layout);
        // 发送播放音乐的广播
        Intent intentStart = new Intent();
        intentStart.setAction(MusicPlayService.MUSIC_COMMAN_INTENTFILTER);
        intentStart.putExtra(MusicPlayService.MUSIC_COMMAND_KEY, MusicPlayService.START_MUSIC_COMMAND);
        PendingIntent pendingIntentStart = PendingIntent.getBroadcast(this, MusicPlayService.START_MUSIC_COMMAND, intentStart, PendingIntent.FLAG_UPDATE_CURRENT);
        remoteViews.setOnClickPendingIntent(R.id.start_btn , pendingIntentStart);
        // 发送停止音乐的广播
        Intent intentStop = new Intent();
        intentStop.setAction(MusicPlayService.MUSIC_COMMAN_INTENTFILTER);
        intentStop.putExtra(MusicPlayService.MUSIC_COMMAND_KEY, MusicPlayService.STOP_MUSIC_COMMAND);
        PendingIntent pendingIntentStop = PendingIntent.getBroadcast(this , MusicPlayService.STOP_MUSIC_COMMAND , intentStop , PendingIntent.FLAG_UPDATE_CURRENT);
        remoteViews.setOnClickPendingIntent(R.id.cancel_btn , pendingIntentStop);

        // 创建notificationpu 实例
        notifyBuilder = new NotificationCompat.Builder(this)
                // 通知时的图标
                .setSmallIcon(R.drawable.add_group_btn_img)
                // 下拉窗中的通知布局
                .setContent(remoteViews)
                // 通知时的提示
                .setTicker("收到一条消息")
                // 通知被点击时的事件
                .setContentIntent(pendingIntent)
                // 通知被点击后是否自动关闭
                .setAutoCancel(true);

    }

这样当我们单击R.id.start_btn和R.id.cancel_btn时,即会分别会发现intentStart和intentStop两个广播,通知后台处理音乐播放的逻辑。

当需要发送通知时

    private synchronized void sendNotification(){
        Intent intentService = new Intent(this , MusicPlayService.class);
        // 开启音乐Service
        this.startService(intentService);
        // 获取默认通知铃声,此处可以自己设置
        Uri soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        // 为通知设置铃声
        notifyBuilder.setSound(soundUri);
        // 为通知设置振动 停1000ms 震200ms 停1000ms 震200ms
        notifyBuilder.setVibrate(new long[]{1000, 200, 1000, 200});
        // 设置通知ID,并发出通知
        Notification notification = notifyBuilder.build();
        notification.flags = Notification.FLAG_NO_CLEAR;
        notificationManager.notify(UPLOAD_IMAGE, notification);
        notifyBuilder.setSound(null);
        notifyBuilder.setVibrate(null);
    }

MusicPlayService的任务有两个:

1) 根据接收到的广播控制音乐的播放停止逻辑

2) 根据当前的音乐播放状态,将进度条、是否正在播放等信息以广播的形式发出,改变Notification的外观。

public class MusicPlayService extends Service {

    static final String MUSIC_COMMAND_KEY = "music_command";
    static final String MUSIC_PROCCESS = "music_proccess";
    static final String MUSIC_COMMAN_INTENTFILTER = "music_command_intent_filter";
    static final int START_MUSIC_COMMAND = 1001;
    static final int STOP_MUSIC_COMMAND = 1002;
    static final int PAUSE_MUSIC_COMMAND = 1003;

    final int MUSIC_STATE_STOP = 0;
    final int MUSIC_STATE_START = 1;
    final int MUSIC_STATE_PAUSE = 2;

    int musicState = MUSIC_STATE_STOP;

    MusicServiceReceiver musciReceiver;

    MediaPlayer mMusicPlayer;

    TimerTask timerTask;
    Timer timer;
    boolean timeIsAlive = false;
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        // 初始化音乐播放器
        mMusicPlayer = new MediaPlayer();
        mMusicPlayer.setLooping(false);
        // 音乐广播接收器
        musciReceiver = new MusicServiceReceiver();
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(MUSIC_COMMAN_INTENTFILTER);
        registerReceiver(musciReceiver, intentFilter);
        readyAssetsMusic(mMusicPlayer);

        // 当时发送音乐播放进度,改变进度条
        timerTask = new TimerTask() {
            @Override
            public void run() {
                if (mMusicPlayer != null && mMusicPlayer.isPlaying()&&timeIsAlive) {
                    float duration = mMusicPlayer.getDuration();
                    Log.d("tag", "当前播放到======" + mMusicPlayer.getCurrentPosition() / duration * 100 + "%");
                    Intent intent = new Intent();
                    intent.setAction(MainActivity.MUSIC_ACTIVITY_ACTION);
                    intent.putExtra(MUSIC_PROCCESS, (int) (mMusicPlayer.getCurrentPosition() / duration * 100));
                    sendBroadcast(intent);
                }
            }
        };
        timer = new Timer();
        timer.schedule(timerTask, 2000, 1000);
    }

    // 广播接收器
    public class MusicServiceReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            Log.d("tag", "收到了广播消息");
            int command = intent.getIntExtra(MUSIC_COMMAND_KEY, -1);
            switch (command) {
                //开始音乐
                case START_MUSIC_COMMAND:
                    if (musicState == MUSIC_STATE_START) {
                        //发送状态信息
                        Intent pauseIntent = new Intent();
                        pauseIntent.setAction(MainActivity.MUSIC_ACTIVITY_ACTION);
                        pauseIntent.putExtra(MUSIC_COMMAND_KEY, PAUSE_MUSIC_COMMAND);
                        sendBroadcast(pauseIntent);
                        // 控制音乐播放
                        mMusicPlayer.pause();
                        // 处理音乐逻辑
                        timeIsAlive = false;
                        musicState = MUSIC_STATE_PAUSE;
                    } else if (musicState == MUSIC_STATE_PAUSE || musicState == MUSIC_STATE_STOP) {
                        //发送状态信息
                        Intent startIntent = new Intent();
                        startIntent.setAction(MainActivity.MUSIC_ACTIVITY_ACTION);
                        startIntent.putExtra(MUSIC_COMMAND_KEY, START_MUSIC_COMMAND);
                        sendBroadcast(startIntent);
                        // 控制音乐播放
                        mMusicPlayer.start();
                        // 处理音乐逻辑
                        timeIsAlive = true;
                        musicState = MUSIC_STATE_START;
                    }
                    break;
                // 停止音乐
                case STOP_MUSIC_COMMAND:
                    if (musicState == MUSIC_STATE_START || musicState == MUSIC_STATE_PAUSE) {
                        //发送状态信息
                        Intent stopIntent = new Intent();
                        stopIntent.setAction(MainActivity.MUSIC_ACTIVITY_ACTION);
                        stopIntent.putExtra(MUSIC_COMMAND_KEY, STOP_MUSIC_COMMAND);
                        stopIntent.putExtra(MUSIC_PROCCESS , 0);
                        sendBroadcast(stopIntent);
                        // 控制音乐播放
                        mMusicPlayer.pause();
                        mMusicPlayer.seekTo(0);
                        // 处理音乐逻辑
                        timeIsAlive = false;
                        musicState = MUSIC_STATE_STOP;
                    }
                    break;
            }
        }
    }

    /**
     * 读取assets中的文件
     * @param mediaPlayer 播放器实例
     */
    private void readyAssetsMusic(MediaPlayer mediaPlayer) {
        if (mediaPlayer == null) {
            return;
        }
        try {
            AssetFileDescriptor afd = getAssets().openFd("music1.mp3");
            mediaPlayer.reset();
            mediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
            mediaPlayer.prepare();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

MusicPlayService将音乐播放状态传给MainActivity。根据传来的信息,MainActivity将remoteview中的外观进行修改,并更新。

    public class MusicActivityReceiver extends BroadcastReceiver{

        @Override
        public void onReceive(Context context, Intent intent) {
            int proccess = intent.getIntExtra(MusicPlayService.MUSIC_PROCCESS , -1);
            int command = intent.getIntExtra(MusicPlayService.MUSIC_COMMAND_KEY , 0);
            if (proccess >= 0){
                remoteViews.setProgressBar(R.id.notify_progress , 100 , proccess ,false);
            }

            switch (command){
                case MusicPlayService.START_MUSIC_COMMAND:
                    remoteViews.setTextViewText(R.id.start_btn, "暂停");
                    break;
                case MusicPlayService.STOP_MUSIC_COMMAND:
                    remoteViews.setTextViewText(R.id.start_btn, "播放");
                    break;
                case MusicPlayService.PAUSE_MUSIC_COMMAND:
                    remoteViews.setTextViewText(R.id.start_btn, "播放");

                    break;
            }
            updateNotification();
        }
    }

    /**
     * 注册广播,接收来自MusicService的广播命令
     */
    private void initReceiver(){
        musicReceiver = new MusicActivityReceiver();
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(MUSIC_ACTIVITY_ACTION);
        registerReceiver(musicReceiver , intentFilter);
    }

    // 更新通知信息
    private synchronized void updateNotification() {
        notificationManager.notify(UPLOAD_IMAGE, notifyBuilder.build());
    }

  Done!

原文地址:https://www.cnblogs.com/fishbone-lsy/p/4735410.html