各位小伙伴,此demo主要介绍Notification的自定义布局和事件绑定。(注意了,Android 8及以上系统的通知需要使用notificationchannel,不然不能发出通知)
我为什么要写这篇文章呢?我当时在使用notification的时候,正好手机开了酷狗音乐,酷狗音乐在通知栏里面占用了第一条。我的notification通知在第二条,本来应该有115dp高度的通知被挤成64dp(notification默认的高度),发现当布局很大的时候,我的bigContentView显示不全。而酷狗音乐的通知栏,如果显示在第二条,会自动切换布局为较小布局,所以我寻思着也要做到酷狗通知的效果。于是使用notification自带的contentView和bigContentView属性实现了这个效果。
而notification的事件绑定使用的是PendingIntent意图,结合广播BroadcastReceiver实现。话不多说,代码贴上。
package com.demo.notification;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import android.provider.Settings;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.RemoteViews;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private boolean displayFlag = true;
private Toast toast;
private RemoteViews bigRemoteViews,smallRemoteViews;
private NotificationManager mNotificationManager;
private Notification notification;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//添加广播的action,以处理Notification通知中的各个控件的事件
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("lastSong");
intentFilter.addAction("nextSong");
intentFilter.addAction("closeNotification");
intentFilter.addAction("display_big");
intentFilter.addAction("display_small");
registerReceiver(broadcastReceiver, intentFilter);
mNotificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
Notification.Builder mBuilder = new Notification.Builder(this.getApplicationContext())
.setSound(Settings.System.DEFAULT_NOTIFICATION_URI)
.setSmallIcon(R.mipmap.ic_launcher)
.setTicker("有这个消息呢")
.setSound(null) //我不想有声音提示,设置为null//资源文件的使用: Uri.parse("android.resource://com.demo.notification/" + R.raw.hah)
.setPriority(Notification.PRIORITY_DEFAULT) //设置该通知的优先级
.setOngoing(true)
.setWhen(System.currentTimeMillis()); //设置通知时间,默认为系统发出通知的时间,通常不设置
//处理点击Notification的逻辑 返回正在运行的activity
Intent resultIntent = new Intent(this,this.getClass());
resultIntent.setAction(Intent.ACTION_MAIN);
resultIntent.addCategory(Intent.CATEGORY_LAUNCHER);
PendingIntent resultPendingIntent = PendingIntent.getActivity(this, 0x004, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(resultPendingIntent);
notification = mBuilder.build();
bigRemoteViews = getBigRemoteViews(); //想要使用的大布局
smallRemoteViews = getSmallRemoteViews(); //默认的小布局
if (Build.VERSION.SDK_INT >= 16){ //bigContentView支持Android4.1及以上
notification.bigContentView = bigRemoteViews;
}
notification.contentView = smallRemoteViews;
notification.flags |= Notification.FLAG_NO_CLEAR; // |=叠加运算,设置 FLAG_NO_CLEAR 表示设置通知不能被状态栏的清除按钮给清除掉,也不能被手动清除,但能通过 cancel() 方法清除
//发送
mNotificationManager.notify(1, notification);
}
private RemoteViews getBigRemoteViews() {
RemoteViews remoteViews = new RemoteViews(this.getPackageName(), R.layout.music_big_content_view); //大布局
remoteViews.setOnClickPendingIntent(R.id.lastSong_big, getActivityPendingIntent("lastSong")); //给控制设置点击事件
remoteViews.setOnClickPendingIntent(R.id.display_big, getActivityPendingIntent("display_big"));
remoteViews.setOnClickPendingIntent(R.id.nextSong_big, getActivityPendingIntent("nextSong"));
remoteViews.setOnClickPendingIntent(R.id.closeNotification_big,getActivityPendingIntent("closeNotification"));
return remoteViews;
}
private RemoteViews getSmallRemoteViews() {
RemoteViews remoteViews = new RemoteViews(this.getPackageName(), R.layout.music_small_content_view); //小布局
remoteViews.setOnClickPendingIntent(R.id.lastSong_small, getActivityPendingIntent("lastSong"));
remoteViews.setOnClickPendingIntent(R.id.display_small, getActivityPendingIntent("display_small"));
remoteViews.setOnClickPendingIntent(R.id.nextSong_small, getActivityPendingIntent("nextSong"));
remoteViews.setOnClickPendingIntent(R.id.closeNotification_small,getActivityPendingIntent("closeNotification"));
return remoteViews;
}
//覆盖toast对话
public void toastLast(String string) {
if (toast != null) {
toast.cancel();
}
toast = Toast.makeText(MainActivity.this, string, Toast.LENGTH_SHORT);
toast.show();
}
/**
* 获取一个Activity类型的PendingIntent对象
*/
private PendingIntent getActivityPendingIntent(String event) {
Intent pIntent = new Intent(event);
return PendingIntent.getBroadcast(this, R.string.app_name, pIntent, PendingIntent.FLAG_UPDATE_CURRENT);
}
public void lastSong() {
toastLast("上一首");
}
public void displayBig() {
if (displayFlag) {
toastLast("暂停 ---大");
bigRemoteViews.setImageViewResource(R.id.display_big,R.drawable.button_pausesong_selected);
mNotificationManager.notify(1,notification);
displayFlag = false;
} else {
toastLast("播放 ---大");
bigRemoteViews.setImageViewResource(R.id.display_big,R.drawable.button_pause_002);
mNotificationManager.notify(1,notification);
displayFlag = true;
}
}
public void displaySmall() {
if (displayFlag) {
toastLast("暂停 ---小");
smallRemoteViews.setImageViewResource(R.id.display_small,R.drawable.button_pausesong_selected);
mNotificationManager.notify(1,notification); //布局内容变化之后,一定要notify更新,不然不会变化
displayFlag = false;
} else {
toastLast("播放 ---小");
smallRemoteViews.setImageViewResource(R.id.display_small,R.drawable.button_pause_002);
mNotificationManager.notify(1,notification);
displayFlag = true;
}
}
public void nextSong() {
toastLast("下一首");
}
public BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
switch (intent.getAction()) {
case "lastSong":
lastSong();
break;
case "display_big":
displayBig();
break;
case "display_small":
displaySmall();
break;
case "nextSong":
nextSong();
break;
case "closeNotification":
mNotificationManager.cancel(1);
finish();
break;
default:
break;
}
}
};
@Override
protected void onDestroy() {
unregisterReceiver(broadcastReceiver);
super.onDestroy();
}
}
下面是布局文件:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:layout_marginRight="5dp"
android:src="@drawable/icon_close"
android:layout_alignParentRight="true"
android:id="@+id/closeNotification_big"
android:layout_width="30dp"
android:layout_height="30dp" />
<ImageView
android:src="@drawable/defaultsongpic"
android:layout_marginRight="10dp"
android:id="@+id/songPic_big"
android:layout_width="115dp"
android:layout_height="115dp" />
<TextView
android:layout_toRightOf="@id/songPic_big"
android:id="@+id/songName_big"
android:textColor="#fff"
android:textSize="18sp"
android:text="歌曲名称"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:textColor="#ccc"
android:layout_toRightOf="@id/songPic_big"
android:layout_below="@id/songName_big"
android:id="@+id/authorName_big"
android:layout_marginTop="5dp"
android:textSize="16sp"
android:text="作者"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<LinearLayout
android:layout_toRightOf="@id/songPic_big"
android:layout_below="@id/authorName_big"
android:layout_marginTop="15dp"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/lastSong_big"
android:layout_width="35dp"
android:layout_height="35dp"
android:src="@drawable/button_last_002" />
<ImageView
android:id="@+id/display_big"
android:layout_width="35dp"
android:layout_height="35dp"
android:layout_marginLeft="25dp"
android:src="@drawable/button_pause_002" />
<ImageView
android:id="@+id/nextSong_big"
android:layout_width="35dp"
android:layout_height="35dp"
android:layout_marginLeft="25dp"
android:src="@drawable/button_next_002" />
</LinearLayout>
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="64dp"
android:orientation="vertical">
<ImageView
android:id="@+id/songPic_small"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_marginRight="10dp"
android:src="@drawable/defaultsongpic" />
<LinearLayout
android:id="@+id/musicInfo_small"
android:layout_centerVertical="true"
android:orientation="vertical"
android:layout_toRightOf="@id/songPic_small"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="@+id/songName_small"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="歌曲名称"
android:textColor="#fff"
android:textSize="16sp" />
<TextView
android:textColor="#ccc"
android:id="@+id/authorName_small"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="作者"
android:textSize="14sp" />
</LinearLayout>
<LinearLayout
android:layout_marginRight="20dp"
android:layout_alignParentRight="true"
android:gravity="center_vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_centerVertical="true">
<ImageView
android:id="@+id/lastSong_small"
android:layout_width="30dp"
android:layout_height="30dp"
android:src="@drawable/button_last_002" />
<ImageView
android:id="@+id/display_small"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginLeft="10dp"
android:src="@drawable/button_pause_002" />
<ImageView
android:id="@+id/nextSong_small"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginLeft="10dp"
android:src="@drawable/button_next_002" />
<ImageView
android:src="@drawable/icon_close"
android:id="@+id/closeNotification_small"
android:layout_marginLeft="10dp"
android:layout_width="30dp"
android:layout_height="30dp" />
</LinearLayout>
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.demo.ndkdemo.MainActivity">
<EditText
android:layout_width="200dp"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="在文本框中输入文字以判断activity是否变化"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
下面是图片资源: