博主聲明:
轉載請在開頭附加本文鏈接及作者信息,並標記爲轉載。本文由博主 威威喵 原創,請多支持與指教。
由於博主之前寫過的通知代碼,在 Android 8.0 以上跑的時候,卻怎麼也通知不出來。本來之前在其它模擬器(android 5.x)上進行測試的時候,還是好好的。突然在 8.0 上跑的時候,就不行了,這很明顯就是版本適配出現了問題。
於是呢,博主就去看了一些相關的資料,原來在 8.0 版本,谷歌就爲每一個通知設定了一個 NotificationChannel,如果在通知代碼裏沒有加這個 Channel 的話,在 8.0 及以上都無法顯示通知出來的。
好了,接下來通過一個簡單的 Demo 去適配 Android 8.0 及以上的通知,案例中包含了普通樣式的通知、自定義View樣式的通知、帶進度條的通知、以及懸浮式通知。
首先,我們要解決的一個問題,如何進行適配,既適配 8.0 及以上,和 8.0 以下。
先獲取 NotificationManager 的實例,用於管理通知:
private NotificationManager mNotificationManager;
mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
接着是創建 Notification 代碼,這裏就要對 Android 版本進行適配工作
private Notification.Builder getNotificationBuilder() {
checkOpenNotification(this);
Notification.Builder builder;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // if android version >= 8.0
builder = new Notification.Builder(this, "channel_id");
@SuppressLint("WrongConstant")
NotificationChannel channel = new NotificationChannel("channel_id", "channel_name",
NotificationManager.IMPORTANCE_DEFAULT);
channel.setLockscreenVisibility(NotificationCompat.VISIBILITY_PUBLIC);
mNotificationManager.createNotificationChannel(channel);
} else {
builder = new Notification.Builder(this);
}
builder.setContentTitle("content-title");
builder.setContentText("content-text");
builder.setSubText("sub-text");
builder.setShowWhen(true);
builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher));
builder.setSmallIcon(R.mipmap.ic_launcher_round);
return builder;
}
如果在 sdk 大於 8.0 及以上的時候,就要創建一個 NotificationChannel 的實例,小於 8.0 那就不需要了,並且可以在 Channel 中設置鈴聲、震動、呼吸燈、優先級等等。
接下來也是非常重要的一步,就是去系統設置裏面,將本應用的通知功能給打開,由於一些手機自己定製的系統,會默認將這項通知功能給關閉,如果不打開的話,也照樣顯示不了通知信息的。
由於用戶可以並不知道如何進行設置,我們可以用代碼來先檢測該功能是否被打開了,代碼如下:
private void checkOpenNotification(Context context) {
boolean notify = NotificationManagerCompat.from(context).areNotificationsEnabled();
if (!notify) {
Intent intent = new Intent();
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && Build.VERSION.SDK_INT < Build.VERSION_CODES.P) { // android 5.x - 9.x
intent.setAction("android.settings.APP_NOTIFICATION_SETTINGS");
intent.putExtra("app_package", context.getPackageName());
intent.putExtra("app_uid", context.getApplicationInfo().uid);
} else if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { // android 4.x
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.setData(Uri.parse("package:" + context.getPackageName()));
} else {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
intent.setData(Uri.fromParts("package", context.getPackageName(), null));
}
context.startActivity(intent);
}
}
這裏設計到了不同版本系統的區別,以及跳轉到通知設置的方法,如果用戶沒有打開該權限,就會引導跳轉到設置頁面,將下面的通知功能打開即可。
一、創建普通樣式的通知
普通樣式的通知,就設置了通知內容、標題、副標題等信息,代碼很簡單,如下:
private void showNormalNotification() {
mNotificationManager.notify(1, getNotificationBuilder().build());
}
效果圖如下:
二、創建自定義View樣式的通知
自定義View樣式的通知,需要根據自己的需求來決定,比如像音樂播放器那種樣式的,就是一個自定義樣式,下面是一個簡單的佈局文件:
<?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="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/tv_notify_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:textColor="#000000"
android:textSize="16sp" />
<TextView
android:id="@+id/tv_notify_sub_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/tv_notify_text"
android:layout_marginLeft="16dp"
android:layout_marginTop="8dp"
android:textSize="14sp" />
<ImageView
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_below="@+id/tv_notify_sub_text"
android:layout_marginLeft="8dp"
android:layout_marginTop="8dp"
android:src="@mipmap/ic_launcher" />
<Button
android:id="@+id/btn_pending_intent"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="8dp"
android:text="點擊跳轉" />
</RelativeLayout>
通知代碼如下:
private void showCustomNotification() {
Notification.Builder builder = getNotificationBuilder();
RemoteViews contentView = new RemoteViews(getPackageName(), R.layout.notify_content_view);
contentView.setTextViewText(R.id.tv_notify_text, "Text");
contentView.setTextViewText(R.id.tv_notify_sub_text, "SubText");
Intent intent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
contentView.setOnClickPendingIntent(R.id.btn_pending_intent, pendingIntent);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
builder.setCustomContentView(contentView);
}
mNotificationManager.notify(2, builder.build());
}
效果圖:
三、創建帶進度樣式的通知
帶進度樣式的通知,可以用於系統更新、下載服務上,給用戶通知一下下載進度,代碼如下:
private void showProgressNotification() {
final Notification.Builder builder = getNotificationBuilder();
builder.setOnlyAlertOnce(true);//設置震動、鈴聲等只提醒一次
mNotificationManager.notify(3, builder.build());
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i <= 100; i++) {
try {
Thread.sleep(100);
builder.setProgress(100, i, false);
mNotificationManager.notify(3, builder.build());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
這裏僅做了一個線程模擬下載的例子,效果如下:
四、創建懸浮式樣式的通知
懸浮式樣式的通知場景也很多,比如現在的 App 一般都是用這種方式,但是博主發現,在我現在這個模擬器,Android 9.0 上始終無法懸浮出來,目前也沒有成功。但是,在 5.x 的系統上,是可以實現懸浮效果的。就如下面顯示的這樣:
其代碼如下:
private void showSuspendNotification() {
Notification.Builder builder = getNotificationBuilder();
Intent intent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
builder.setContentText("SuspendNotification")
.setFullScreenIntent(pendingIntent, true);
mNotificationManager.notify(4, builder.build());
}
最後,這就是關於 Android 的通知方面的適配以及通知樣式相關的案例,到此也基本滿足我們日常開發中所需求的通知方式。