Android 超简单音乐播放器(八)通知栏切换显示更新歌曲 服务和活动之间的相互通信~

通知栏切换显示更新歌曲

首先!我们一个通知栏是不是需要一个外观呢?!!
第二行代码上说了一种方法设置
好像就是直接设置 图片 标题 副标题(就是默认格式吧?)
不需要写XML代码~
(我写的都是我自己的理解..可能不太正确)
但是我们的就不同了!我们的不能像默认格式那样对不对!
因为我们后面还需要添加按钮啥的!所以!
先写一个外观0 0.

notification.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="60dp"
    android:orientation="horizontal">

    <ImageView
        android:layout_marginLeft="5dp"
        android:layout_marginTop="5dp"
        android:id="@+id/iv_icon"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:src="@drawable/miao" />
    <LinearLayout
        android:layout_gravity="center"
        android:orientation="vertical"
        android:layout_marginLeft="10dp"
        android:layout_width="180dp"
        android:layout_height="40dp">
        <TextView
            android:id="@+id/tv_notigication_songName"
            android:maxEms="11"
            android:ellipsize="end"
            android:maxLines="1"
            android:text="人海—2015版"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            />
        <TextView
            android:id="@+id/tv_notigication_singer"
            android:maxEms="16"
            android:ellipsize="end"
            android:maxLines="1"
            android:textSize="12sp"
            android:layout_marginTop="5dp"
            android:text="燕池"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            />
    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="30dp"
        android:layout_gravity="center"
        android:orientation="horizontal">
        <ImageView
            android:id="@+id/iv_notigication__pre"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:src="@drawable/pre"
            android:layout_weight="1" />
        <ImageView
            android:id="@+id/iv_notigication__stopOrStart"
            android:src="@drawable/star"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"/>
        <ImageView
            android:id="@+id/iv_notigication__next"
            android:src="@drawable/next"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"/>
    </LinearLayout>

</LinearLayout>

然后创建一个MusicNotification

public class MusicNotification extends Notification {
    private static MusicNotification notifyInstance = null;
    private Notification musicNotifi = null;
    private final int NOTIFICATION_ID =0;
    // 通知id
    // 布局
    private Context context;
    private final int REQUEST_CODE = 30000;
    int flags= 10001;
    private NotificationManager manager = null;
    private Builder builder = null;
    private final String MUSIC_NOTIFICATION_ACTION_PLAY = "musicnotificaion.To.PLAY";
    private final String MUSIC_NOTIFICATION_ACTION_NEXT = "musicnotificaion.To.NEXT";
    private final String MUSIC_NOTIFICATION_ACTION_PRE = "musicnotificaion.To.Pre";
    private final String MUSIC_NOTIFICATION_ACTION_NPLAY = "musicnotificaion.To.NPLAY";
    private final String MUSIC_NOTIFICATION_ACTION_NNEXT = "musicnotificaion.To.NNEXT";
    private final String MUSIC_NOTIFICATION_ACTION_NPRE = "musicnotificaion.To.NPre";
    private RemoteViews remoteViews;
    private Intent play=null,next=null,close = null;
    private Intent nplay=null,nnext=null,nclose = null;
    private PendingIntent musicPendIntent = null;
    public void setContext(Context context){
        this.context=context;
    }
    public void setManager(NotificationManager manager) {
        this.manager = manager;
    }
    private MusicNotification (Context context){
        this.context = context;
        // 初始化操作
        remoteViews = new RemoteViews(context.getPackageName(), R.layout.notification);
        builder = new Builder(context);
        play = new Intent();
        play.setAction(MUSIC_NOTIFICATION_ACTION_PLAY);
        next = new Intent();
        next.setAction(MUSIC_NOTIFICATION_ACTION_NEXT);
        close = new Intent();
        close.setAction(MUSIC_NOTIFICATION_ACTION_PRE);
        nplay = new Intent();
        nplay.setAction(MUSIC_NOTIFICATION_ACTION_NPLAY);
        nnext = new Intent();
        nnext.setAction(MUSIC_NOTIFICATION_ACTION_NNEXT);
        nclose = new Intent();
        nclose.setAction(MUSIC_NOTIFICATION_ACTION_NPRE);
    }//恶汉式实现 通知初始化
    public static MusicNotification getMusicNotification(Context context){
        if (notifyInstance == null) {
            notifyInstance = new MusicNotification(context);
        }
        return notifyInstance;
    }


    public void onCreateMusicNotifi() {
        // 设置点击事件

        // 1.注册控制点击事件

        PendingIntent pplay = PendingIntent.getBroadcast(context, REQUEST_CODE,
                play,0);
        remoteViews.setOnClickPendingIntent(R.id.iv_notigication__stopOrStart,
                pplay);

        // 2.注册下一首点击事件

        PendingIntent pnext = PendingIntent.getBroadcast(context, REQUEST_CODE,
                next, 0);
        remoteViews.setOnClickPendingIntent(R.id.iv_notigication__next,
                pnext);

        // 3.注册关闭点击事件

        PendingIntent pclose = PendingIntent.getBroadcast(context, REQUEST_CODE,
                close, 0);
        remoteViews.setOnClickPendingIntent(R.id.iv_notigication__pre,
                pclose);
                //4.设置点击事件(挑战到播放界面)
        Intent intent = new Intent(context, MusicActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(context,0,intent,0);
        builder.setContent(remoteViews).setWhen(System.currentTimeMillis())
                // 通知产生的时间,会在通知信息里显示
//              .setPriority(Notification.PRIORITY_DEFAULT)
                // 设置该通知优先级
                .setContentIntent(pendingIntent)
                .setOngoing(true).setTicker("播放新的一首歌")
                .setSmallIcon(R.drawable.miao);

        // 兼容性实现

        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
            musicNotifi = builder.getNotification();
        } else {
            musicNotifi = builder.build();
        }
        musicNotifi.flags = Notification.FLAG_ONGOING_EVENT;
        manager.notify(0, musicNotifi);
//        manager.cancel(0);
    }

    public void onUpdataMusicNotifi(Song song, boolean isplay) {
        // 设置添加内容
        if (song==null){
            remoteViews.setTextViewText(R.id.tv_notigication_songName,"什么东东");
            remoteViews.setTextViewText(R.id.tv_notigication_singer,"未知");
        }
        else {
            remoteViews.setTextViewText(R.id.tv_notigication_songName,
                    (song.getSong()!=null?song.getSong():"什么东东") + "");

            remoteViews.setTextViewText(R.id.tv_notigication_singer,
                    (song.getSinger()!=null?song.getSinger():"未知") + "");

            //判断是否播放
            Log.i(TAG, "onUpdataMusicNotifi: ]"+isplay);
            if (isplay) {
                remoteViews.setImageViewResource(R.id.iv_notigication__stopOrStart,
                        R.drawable.star);
            } else {
                remoteViews.setImageViewResource(R.id.iv_notigication__stopOrStart,
                        R.drawable.stop);
            }
        }

        onCreateMusicNotifi(); //每一次改变都要重新创建,所以直接写这里
    }


    /**
     * 取消通知栏
     */
    public void onCancelMusicNotifi(){
        manager.cancel(0);
    }



}

修改MusicSerive。

这样我们就创建好啦~
接下来我们就要把通知栏写到我们的MusicSerive去
为什么呢
因为当服务启动的时候就会启动通知栏呀(也就是说只要我们歌曲在播放)
而如果写在我们的MusicActivity中
而且我们是动态注册广播接收器的
当活动finish之后 是不是就无法控制控制切换歌曲了呢
而且当我们的通知栏切换歌曲后 恰好我们之前是留在MusicActivity 我们是不是需要提醒活动更新界面
而当我们在活动中切换后是不是也需要提醒我们的通知栏更新界面·
简言而之 就是说
服务和活动相互沟通要怎么实现呢~
首先说说从活动到服务~
记不记得我们服务的生命周期中还有一个onBind()
就是用来绑定活动的
我们可以在活动中通过get获得服务的实例
然后进行对服务的操作嘛
(这里要因人而异 我的写法只需要绑定活动就可以 这样活动创建通知栏就会创建 )
(反正我是这么理解的)
然后从服务到活动 这就可以用广播嘛
服务发送广播~活动接受广播~

public class MusicService extends Service {
    private final String MUSIC_NOTIFICATION_ACTION_PLAY = "musicnotificaion.To.PLAY";
    private final String MUSIC_NOTIFICATION_ACTION_NEXT = "musicnotificaion.To.NEXT";
    private final String MUSIC_NOTIFICATION_ACTION_PRE = "musicnotificaion.To.Pre";
    private MusicBroadCast musicBroadCast = null;
    private MusicNotification musicNotifi = null;
    private Intent intent1 = new Intent("com.example.communication.CHANGE");//发送广播给活动提醒活动更新界面
    @Override
    public void onCreate() {
        // 初始化通知栏 根据服务的生命周期 所以我们写在这里啦~
        musicNotifi = MusicNotification.getMusicNotification(getApplicationContext());
        musicNotifi.setContext(getBaseContext());
        musicNotifi
                .setManager((NotificationManager) getSystemService(NOTIFICATION_SERVICE));
        musicBroadCast = new MusicBroadCast();
        IntentFilter filter = new IntentFilter();
        filter.addAction(MUSIC_NOTIFICATION_ACTION_PLAY);
        filter.addAction(MUSIC_NOTIFICATION_ACTION_NEXT);
        filter.addAction(MUSIC_NOTIFICATION_ACTION_PRE);
        registerReceiver(musicBroadCast, filter);

        super.onCreate();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        releseWakeLock();
        MusicUtil.getInstance().clean();
        unregisterReceiver(musicBroadCast);//动态注册广播记得要取消
        musicNotifi.onCancelMusicNotifi();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        acquireWakeLock();
        switch (intent.getStringExtra("action")) {
            case COMPLETE:
                MusicUtil.getInstance().prePlayOrNextPlay();
//提醒通知栏更新 写在这里 无论是通过活动还是通知栏控制 都会更新 
                musicNotifi.onUpdataMusicNotifi(MusicUtil.getInstance().getNewSongInfo(),MusicUtil.getInstance().isPlaying());
                break;
            case PLAYORPAUSE:
                MusicUtil.getInstance().playOrPause();
                musicNotifi.onUpdataMusicNotifi(MusicUtil.getInstance().getNewSongInfo(),MusicUtil.getInstance().isPlaying());
                break;
            case PREVIOUSMUSIC:
                MusicUtil.getInstance().prePlayOrNextPlay();
                musicNotifi.onUpdataMusicNotifi(MusicUtil.getInstance().getNewSongInfo(),MusicUtil.getInstance().isPlaying());
                break;
            case NEXTMUSIC:
                MusicUtil.getInstance().prePlayOrNextPlay();
                musicNotifi.onUpdataMusicNotifi(MusicUtil.getInstance().getNewSongInfo(),MusicUtil.getInstance().isPlaying());
                break;
        }


        return super.onStartCommand(intent, flags, startId);
    }
    public class MusicBinder extends Binder {
        public MusicService getService() {
            return MusicService.this;
        }
    }//绑定活动 获得服务实例


    @Nullable
    @Override

    public IBinder onBind(Intent intent) {
        musicNotifi.onUpdataMusicNotifi(MusicUtil.getInstance().getNewSongInfo(),MusicUtil.getInstance().isPlaying());
             return new MusicBinder();

    }
//通知栏发送广播的接收器 实现通知栏按钮的实现
    public class MusicBroadCast extends BroadcastReceiver {
    private final String MUSIC_NOTIFICATION_ACTION_PLAY = "musicnotificaion.To.PLAY";
    private final String MUSIC_NOTIFICATION_ACTION_NEXT = "musicnotificaion.To.NEXT";
    private final String MUSIC_NOTIFICATION_ACTION_PRE = "musicnotificaion.To.PRE";
    @Override
    public void onReceive(Context context, Intent intent) {
        switch (intent.getAction()){
            case MUSIC_NOTIFICATION_ACTION_PLAY :
                Intent startIntent1 = new Intent(getApplicationContext(), MusicService.class);
                startIntent1.putExtra("action",MusicService.PLAYORPAUSE);
                startService(startIntent1);
                sendBroadcast(intent1);
                break;
            case MUSIC_NOTIFICATION_ACTION_NEXT:
                MusicUtil.getInstance().next();
                Intent startIntent3 = new Intent(getApplicationContext(), MusicService.class);
                startIntent3.putExtra("action",MusicService.NEXTMUSIC);
                startService(startIntent3);
                sendBroadcast(intent1);
                break;
            case MUSIC_NOTIFICATION_ACTION_PRE:
                MusicUtil.getInstance().pre();
                Intent startIntent2 = new Intent(getApplicationContext(), MusicService.class);
                startIntent2.putExtra("action",MusicService.PREVIOUSMUSIC);
                startService(startIntent2);
                sendBroadcast(intent1);
                break;
        }

    }
}
}

MusicActivity 中接收广播。

更改界面信息。

//绑定Activity与服务。
 Intent startIntent = new Intent(this, MusicService.class);
    bindService(startIntent, connection, BIND_AUTO_CREATE);

    //动态注册广播接收器。
    msgReceiver = new MsgReceiver();
    IntentFilter intentFilter = new IntentFilter();
    intentFilter.addAction("com.example.communication.CHANGE");
    registerReceiver(msgReceiver, intentFilter);
    public class MsgReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        changInfo();//接收到了就更新界面嘛~
    }
}

@Override
protected void onDestroy() {
    unbindService(connection);
unregisterReceiver(msgReceiver);//同理注销还有取消绑定~
    super.onDestroy();}
//当绑定后,服务需要进行的操作。
private ServiceConnection connection = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName componentName, IBinder service1) {
    musicService = ((MusicService.MusicBinder ) service1).getService();
        musicService.changNotifi();
    }

    @Override
    public void onServiceDisconnected(ComponentName componentName) {

    }
};
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值