首先!我们一个通知栏是不是需要一个外观呢?!!
第二行代码上说了一种方法设置
好像就是直接设置 图片 标题 副标题(就是默认格式吧?)
不需要写XML代码~
(我写的都是我自己的理解..可能不太正确)
但是我们的就不同了!我们的不能像默认格式那样对不对!
因为我们后面还需要添加按钮啥的!所以!
先写一个外观0 0.
<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>
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去
为什么呢
因为当服务启动的时候就会启动通知栏呀(也就是说只要我们歌曲在播放)
而如果写在我们的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;
}
}
}
}
更改界面信息。
//绑定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) {
}
};