在安卓8.0以前是这样创建一个通知栏的:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button sendNotice = findViewById(R.id.send_notice);
sendNotice.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
NotificationManager manager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
Notification notification = new NotificationCompat.Builder(MainActivity.this)
.setContentTitle("This is Content Title")
.setContentText("This is Content text")
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher_foreground))
.build();
manager.notify(1,notification);
}
});
}
}
可当我运行程序的时候发现,什么效果都没有,查阅资料后发现,原来在安卓8.0之后Google引入了渠道这个概念,我的模拟器是8.0版本的按照原来的方式创建通知自然是不行的。
那么问题来了,什么是渠道呢?其实就是说App内的每条通知都属于一个渠道,我们可以自主的为App创建渠道, 但是渠道的控制权全都在用户手上,用户可以对渠道的重要程度设置震动,响铃,或者是否关闭这个渠道。
那么渠道有什么好处呢?
打个比方,对于淘宝来说,我只关心淘宝中的物流信息,我希望商家一发货我就立马可以收到通知,但是我又不想收到那些打折促使的广告通知。像这种情况淘宝就可以创建两个渠道,一个是物流,一个是广告。这样一来我就可以直接将广告通知的渠道关闭,这样既不影响我关心的通知,也不会让那些我不关心的通知来打扰我了。
创建渠道
创建一个notificationTest项目
创建好后打开app/build.gradle文件检查一下,要保证自己项目中的targetSdkVersion是26及以上,如下所示 :
如果targetSdkVersion低于26可以更新一下,或者手动把他改成26。
接着在MainActivity.java中增加如下代码
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ){
String channelId = "chat";
String channelName = "聊天消息";
int importance = NotificationManager.IMPORTANCE_HIGH;
createNotificationChannel(channelId,channelName,importance);
channelId = "subscribe";
channelName = "订阅消息";
importance = NotificationManager.IMPORTANCE_DEFAULT;
createNotificationChannel(channelId,channelName,importance);
}
}
@RequiresApi(api = Build.VERSION_CODES.O)
private void createNotificationChannel(String channelId, String channelName , int importance){
NotificationChannel notificationChannel = new NotificationChannel(channelId, channelName, importance);
NotificationManager Manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationChannel.setShowBadge(true);
Manager.createNotificationChannel(notificationChannel);
}
}
在Oncreate中创建了两个渠道,首先要确保手机的系统是不是8.0或更高,因为低版本的手机没有渠道这个功能,会造成程序崩溃.然后把创建渠道的代码封装到了createNotificationChannel方法中,创建一个渠道需要三个参数,分别是渠道的id,渠道的名称以及渠道的重要等级,渠道的id可以随便起,只要保证全局唯一性就可以,渠道名称是给用户看的,要表达清楚这个渠道的用途,渠道的重要等级则决定这个通知的不同行为,用户也可以自主修改等级,App是无法干预的。
这个程序模拟了微信App,其中有两类通知,一类是别人给我发的消息通知,这类通知非常重要,因此我把这类通知的重要等级设置为了NotificationManager.IMPORTANCE_HIGH,还有一类是订阅消息,这类消息不是那么重要我把这类通知设置为 NotificationManager.IMPORTANCE_DEFAULT,当然还有其他的等级可以设置如:IMPORTANCE_LOW、IMPORTANCE_MIN,分别对应了更低的通知重要程度。
现在运行程序,然后关闭App,进入到设置 -> 应用 -> 通知当中,查看notification这个App的通知界面
就可以看到刚才创建的渠道已经被显示出来了。
让通知显示出来
显示通知的代码和之前没有什么区别,只是在创建通知的时候要传入一个渠道的id,表示这条通知是属于哪个渠道的。
代码如下:
MainActivity.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="发送聊天消息"
android:onClick="sendChatMsg"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="发送订阅消息"
android:onClick="sendSubscribeMsg"
/>
</LinearLayout>
在布局界面中,添加了两个按钮,一个用来触发聊天消息渠道的,一个用来触发订阅消息渠道的。
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
String channelId = "chat";
String channelName = "聊天消息";
int importance = NotificationManager.IMPORTANCE_HIGH;
createNotificationChannel(channelId, channelName, importance);
channelId = "subscribe";
channelName = "订阅消息";
importance = NotificationManager.IMPORTANCE_DEFAULT;
createNotificationChannel(channelId, channelName, importance);
}
}
@RequiresApi(api = Build.VERSION_CODES.O)
private void createNotificationChannel(String channelId, String channelName, int importance) {
NotificationChannel channel = new NotificationChannel(channelId, channelName, importance);
NotificationManager notificationManager = (NotificationManager) getSystemService(
NOTIFICATION_SERVICE);
notificationManager.createNotificationChannel(channel);
}
/*
以下是新增加的代码
*/
public void sendChatMsg(View view) {
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.O){
NotificationChannel chat = manager.getNotificationChannel("chat");
if (chat.getImportance() == manager.IMPORTANCE_NONE){
Intent intent = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS);
intent.putExtra(Settings.EXTRA_APP_PACKAGE,getPackageName());
intent.putExtra(Settings.EXTRA_CHANNEL_ID,chat.getId());
Toast.makeText(this, "请手动将通知打开", Toast.LENGTH_SHORT).show();
startActivity(intent);
}
}
Notification notification = new NotificationCompat.Builder(this, "chat")
.setContentTitle("收到一条聊天消息")
.setContentText("今天中午吃什么?")
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher_foreground))
.setAutoCancel(true)
.build();
manager.notify(1, notification);
}
public void sendSubscribeMsg(View view) {
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
Notification notification = new NotificationCompat.Builder(this, "subscribe")
.setContentTitle("收到一条订阅消息")
.setContentText("震惊!家里有这物的赶紧扔掉!")
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher_foreground))
.setAutoCancel(true)
.build();
manager.notify(2, notification);
}
}
上面创建通知的方法跟原来的没什么区别,只是在sendChatMsg方法中,判断了一下用户是否将聊天消息通知渠道关闭,因为这类消息比较重要,所有如果一旦用户将这类通知关闭了,那我们就提醒他打开。
程序运行后的效果