通知頻道
什麼是通知渠道?
通知渠道使我們的應用開發者能夠將我們的通知分組到頻道 - 使用者可以立即修改整個頻道的通知設定。例如,對於每個頻道,使用者可以完全阻止所有通知,覆蓋重要性級別或允許顯示通知標記。此新功能有助於大大改善應用的使用者體驗。
建立通知渠道
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.content.ContextWrapper;
import android.graphics.Color;
public class NotificationUtils extends ContextWrapper {
private NotificationManager mManager;
public static final String ANDROID_CHANNEL_ID = "com.sai.ANDROID";
public static final String IOS_CHANNEL_ID = "com.sai.IOS";
public static final String ANDROID_CHANNEL_NAME = "ANDROID CHANNEL";
public static final String IOS_CHANNEL_NAME = "IOS CHANNEL";
public NotificationUtils(Context base) {
super(base);
createChannels();
}
public void createChannels() {
// create android channel
NotificationChannel androidChannel = new NotificationChannel(ANDROID_CHANNEL_ID,
ANDROID_CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT);
// Sets whether notifications posted to this channel should display notification lights
androidChannel.enableLights(true);
// Sets whether notification posted to this channel should vibrate.
androidChannel.enableVibration(true);
// Sets the notification light color for notifications posted to this channel
androidChannel.setLightColor(Color.BLUE);
// Sets whether notifications posted to this channel appear on the lockscreen or not
androidChannel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
getManager().createNotificationChannel(androidChannel);
// create ios channel
NotificationChannel iosChannel = new NotificationChannel(IOS_CHANNEL_ID,
IOS_CHANNEL_NAME, NotificationManager.IMPORTANCE_HIGH);
iosChannel.enableLights(true);
iosChannel.enableVibration(true);
iosChannel.setLightColor(Color.GRAY);
iosChannel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
getManager().createNotificationChannel(iosChannel);
}
private NotificationManager getManager() {
if (mManager == null) {
mManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
}
return mManager;
}}
在上面的程式碼中,我們建立了 NotificationChannel 的兩個例項,傳遞了唯一的通道名稱,以及其建構函式中的重要性級別。對於每個通知渠道,我們應用了以下特徵。
- 聲音
- 燈火
- 振動
- 在鎖定螢幕上顯示的通知。
最後,我們從系統中獲取 NotificationManager,然後通過呼叫 createNotificationChannel()
方法註冊通道,傳遞我們建立的通道。
我們可以使用 createNotificationChannels()
一次建立多個通知通道,並傳遞 NotificationChannel 例項的 Java 列表。你可以使用 getNotificationChannels()
獲取應用的所有通知通道,並使用 getNotificationChannel()
獲取特定通道,僅將通道 ID 作為引數傳遞。
通知渠道中的重要性級別
方法 | 描述 |
---|---|
IMPORTANCE_MAX | 沒用過 |
IMPORTANCE_HIGH | 到處顯示,發出喧鬧聲 |
IMPORTANCE_DEFAULT | 到處顯示,發出噪音,但不會在視覺上侵入 |
IMPORTANCE_LOW | 到處顯示,但不是侵入性,價值是 0 |
IMPORTANCE_MIN | 僅顯示在陰影下方,摺疊下方 |
IMPORTANCE_NONE | 不重要的通知; 不顯示在陰涼處 |
建立通知併發布到頻道
我們使用 NotificationBuilder 建立了兩個使用 NotificationUtils 的通知。
public Notification.Builder getAndroidChannelNotification(String title, String body) {
return new Notification.Builder(getApplicationContext(), ANDROID_CHANNEL_ID)
.setContentTitle(title)
.setContentText(body)
.setSmallIcon(android.R.drawable.stat_notify_more)
.setAutoCancel(true);
}
public Notification.Builder getIosChannelNotification(String title, String body) {
return new Notification.Builder(getApplicationContext(), IOS_CHANNEL_ID)
.setContentTitle(title)
.setContentText(body)
.setSmallIcon(android.R.drawable.stat_notify_more)
.setAutoCancel(true);
}
我們也可以使用 Notification.Builder()
設定 NotificationChannel。為此,我們可以使用 setChannel(String channelId) 。
更新通知頻道設定
建立通知渠道後,使用者將負責其設定和行為。你可以再次呼叫 createNotificationChannel()
來重新命名現有通知通道,或更新其描述。以下示例程式碼描述瞭如何通過建立啟動活動的意圖將使用者重定向到通知通道的設定。在這種情況下,意圖需要擴充套件資料,包括通知通道的 ID 和應用程式的包名稱。
@Override
protected void onCreate(Bundle savedInstanceState) {
//...
Button buttonAndroidNotifSettings = (Button) findViewById(R.id.btn_android_notif_settings);
buttonAndroidNotifSettings.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent i = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS);
i.putExtra(Settings.EXTRA_APP_PACKAGE, getPackageName());
i.putExtra(Settings.EXTRA_CHANNEL_ID, NotificationUtils.ANDROID_CHANNEL_ID);
startActivity(i);
}
});
}
XML 檔案:
<!--...-->
<Button
android:id="@+id/btn_android_notif_settings"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Notification Settings"/>
<!--...-->
刪除通知渠道
你可以通過呼叫 deleteNotificationChannel()
來刪除通知通道。
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// The id of the channel.
String id = "my_channel_01";
NotificationChannel mChannel = mNotificationManager.getNotificationChannel(id);
mNotificationManager.deleteNotificationChannel(mChannel);
現在建立 MainActivity 和 xml
activity_main.xml 中
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
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:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_margin="16dp"
tools:context="com.chikeandroid.tutsplusalerts.MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Tuts+ Android Channel"
android:layout_gravity="center_horizontal"
android:textAppearance="@style/TextAppearance.AppCompat.Title"/>
<EditText
android:id="@+id/et_android_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Title"/>
<EditText
android:id="@+id/et_android_author"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Author"/>
<Button
android:id="@+id/btn_send_android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Send"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginTop="20dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Tuts+ IOS Channel"
android:layout_gravity="center_horizontal"
android:textAppearance="@style/TextAppearance.AppCompat.Title"/>
<EditText
android:id="@+id/et_ios_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Title"
/>
<EditText
android:id="@+id/et_ios_author"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Author"/>
<Button
android:id="@+id/btn_send_ios"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Send"/>
</LinearLayout>
</LinearLayout>
MainActivity.java
我們將編輯我們的 MainActivity,以便我們可以從 EditText 元件中獲取標題和作者,然後將它們傳送到 Android 頻道。我們為我們在 NotificationUtils 中建立的 Android 頻道獲取 Notification.Builder,然後通知 NotificationManager。
import android.app.Notification; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.text.TextUtils; import android.view.View; import android.widget.Button; import android.widget.EditText;
public class MainActivity extends AppCompatActivity {
private NotificationUtils mNotificationUtils;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mNotificationUtils = new NotificationUtils(this);
final EditText editTextTitleAndroid = (EditText) findViewById(R.id.et_android_title);
final EditText editTextAuthorAndroid = (EditText) findViewById(R.id.et_android_author);
Button buttonAndroid = (Button) findViewById(R.id.btn_send_android);
buttonAndroid.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String title = editTextTitleAndroid.getText().toString();
String author = editTextAuthorAndroid.getText().toString();
if(!TextUtils.isEmpty(title) && !TextUtils.isEmpty(author)) {
Notification.Builder nb = mNotificationUtils.
getAndroidChannelNotification(title, "By " + author);
mNotificationUtils.getManager().notify(107, nb.build());
}
}
});
}
}