14 KiB
14 KiB
Android 高优先级通知渠道配置指南
概述
在 Android 应用中配置高优先级通知渠道,可以实现强提醒效果,包括:
- ✓ 灭屏状态下的声音和振动提醒
- ✓ 锁屏界面显示通知
- ✓ 通知栏显示消息
- ✓ 绕过免打扰模式(部分情况下)
实现步骤
1. 创建高优先级通知渠道
在应用启动时(Application 或 MainActivity 的 onCreate 中)创建通知渠道:
import android.app.Application;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.media.AudioAttributes;
import android.net.Uri;
import android.os.Build;
public class MyApplication extends Application {
public static final String CHANNEL_ID_IMPORTANT = "important_messages";
public static final String CHANNEL_NAME_IMPORTANT = "重要消息";
@Override
public void onCreate() {
super.onCreate();
createNotificationChannels();
}
private void createNotificationChannels() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// 创建高优先级通知渠道
NotificationChannel importantChannel = new NotificationChannel(
CHANNEL_ID_IMPORTANT,
CHANNEL_NAME_IMPORTANT,
NotificationManager.IMPORTANCE_HIGH // 高优先级
);
// 设置渠道描述
importantChannel.setDescription("重要消息通知,包括即时聊天、语音通话等");
// 启用指示灯
importantChannel.enableLights(true);
importantChannel.setLightColor(android.graphics.Color.BLUE);
// 启用振动
importantChannel.enableVibration(true);
// 设置振动模式:等待0ms,振动1000ms,暂停500ms,再振动1000ms
importantChannel.setVibrationPattern(new long[]{0, 1000, 500, 1000});
// 设置通知声音(使用系统默认通知声音)
importantChannel.setSound(
android.provider.Settings.System.DEFAULT_NOTIFICATION_URI,
new AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.setUsage(AudioAttributes.USAGE_NOTIFICATION)
.build()
);
// 设置绕过免打扰模式(需要用户授权)
// importantChannel.setBypassDnd(true);
// 在锁屏上显示
importantChannel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
// 创建渠道
notificationManager.createNotificationChannel(importantChannel);
}
}
}
2. 在 AndroidManifest.xml 中注册 Application
<application
android:name=".MyApplication"
...>
...
</application>
3. 处理 OPPO 推送消息时使用该渠道
当收到 OPPO 推送消息时,在显示通知时指定使用该渠道:
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.os.Build;
public class PushMessageHandler {
private Context context;
private NotificationManager notificationManager;
public PushMessageHandler(Context context) {
this.context = context;
this.notificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
}
/**
* 显示推送通知
* @param title 通知标题
* @param content 通知内容
* @param data 推送数据(可选)
*/
public void showNotification(String title, String content, Map<String, String> data) {
// 创建点击意图
Intent intent = new Intent(context, MainActivity.class);
if (data != null) {
for (Map.Entry<String, String> entry : data.entrySet()) {
intent.putExtra(entry.getKey(), entry.getValue());
}
}
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(
context,
0,
intent,
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE
);
// 构建通知
Notification.Builder builder;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// Android 8.0 及以上使用渠道
builder = new Notification.Builder(context, MyApplication.CHANNEL_ID_IMPORTANT);
} else {
// Android 8.0 以下
builder = new Notification.Builder(context);
}
builder.setContentTitle(title)
.setContentText(content)
.setSmallIcon(R.drawable.ic_notification) // 小图标
.setLargeIcon(BitmapFactory.decodeResource(
context.getResources(),
R.drawable.ic_launcher
)) // 大图标
.setContentIntent(pendingIntent)
.setAutoCancel(true) // 点击后自动取消
.setPriority(Notification.PRIORITY_HIGH) // 高优先级(Android 7.1及以下)
.setDefaults(Notification.DEFAULT_ALL) // 使用默认声音、振动、灯光
.setWhen(System.currentTimeMillis())
.setShowWhen(true);
// 设置通知样式(可选)
Notification.BigTextStyle bigTextStyle = new Notification.BigTextStyle();
bigTextStyle.bigText(content);
builder.setStyle(bigTextStyle);
// 显示通知
int notificationId = (int) System.currentTimeMillis();
notificationManager.notify(notificationId, builder.build());
}
}
4. 在 OPPO 推送接收处理中使用
import com.heytap.msp.push.mode.DataMessage;
import com.heytap.msp.push.service.DataMessageCallbackService;
public class OppoPushMessageService extends DataMessageCallbackService {
@Override
public void processMessage(Context context, DataMessage dataMessage) {
super.processMessage(context, dataMessage);
// 获取推送消息内容
String title = dataMessage.getTitle();
String content = dataMessage.getContent();
Map<String, String> extra = dataMessage.getExtra();
// 使用高优先级通知渠道显示通知
PushMessageHandler handler = new PushMessageHandler(context);
handler.showNotification(title, content, extra);
}
}
5. 在 AndroidManifest.xml 中注册推送服务
<application>
...
<!-- OPPO 推送服务 -->
<service
android:name=".OppoPushMessageService"
android:permission="com.heytap.mcs.permission.SEND_PUSH_MESSAGE"
android:exported="true">
<intent-filter>
<action android:name="com.heytap.mcs.action.RECEIVE_MCS_MESSAGE" />
</intent-filter>
</service>
...
</application>
完整示例代码
Application.java
package com.xunpaisoft.social;
import android.app.Application;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.media.AudioAttributes;
import android.os.Build;
public class MyApplication extends Application {
public static final String CHANNEL_ID_IMPORTANT = "important_messages";
public static final String CHANNEL_NAME_IMPORTANT = "重要消息";
@Override
public void onCreate() {
super.onCreate();
createNotificationChannels();
}
private void createNotificationChannels() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// 检查渠道是否已存在
if (notificationManager.getNotificationChannel(CHANNEL_ID_IMPORTANT) == null) {
NotificationChannel importantChannel = new NotificationChannel(
CHANNEL_ID_IMPORTANT,
CHANNEL_NAME_IMPORTANT,
NotificationManager.IMPORTANCE_HIGH
);
importantChannel.setDescription("重要消息通知");
importantChannel.enableLights(true);
importantChannel.enableVibration(true);
importantChannel.setVibrationPattern(new long[]{0, 1000, 500, 1000});
importantChannel.setSound(
android.provider.Settings.System.DEFAULT_NOTIFICATION_URI,
new AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.setUsage(AudioAttributes.USAGE_NOTIFICATION)
.build()
);
notificationManager.createNotificationChannel(importantChannel);
}
}
}
}
PushNotificationHelper.java
package com.xunpaisoft.social;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
public class PushNotificationHelper {
private static final String CHANNEL_ID = MyApplication.CHANNEL_ID_IMPORTANT;
public static void showNotification(Context context, String title, String content) {
NotificationManager notificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Intent intent = new Intent(context, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(
context,
0,
intent,
PendingIntent.FLAG_UPDATE_CURRENT |
(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ? PendingIntent.FLAG_IMMUTABLE : 0)
);
Notification.Builder builder;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
builder = new Notification.Builder(context, CHANNEL_ID);
} else {
builder = new Notification.Builder(context);
builder.setPriority(Notification.PRIORITY_HIGH);
}
builder.setContentTitle(title)
.setContentText(content)
.setSmallIcon(R.drawable.ic_notification)
.setContentIntent(pendingIntent)
.setAutoCancel(true)
.setDefaults(Notification.DEFAULT_ALL);
int notificationId = (int) System.currentTimeMillis();
notificationManager.notify(notificationId, builder.build());
}
}
权限配置
在 AndroidManifest.xml 中添加必要权限:
<manifest>
<!-- 通知权限 -->
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<!-- 振动权限 -->
<uses-permission android:name="android.permission.VIBRATE" />
<!-- 唤醒锁(可选,用于确保通知及时送达) -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<application>
...
</application>
</manifest>
Android 13+ (API 33+) 权限处理
Android 13 及以上版本需要动态申请通知权限:
import android.Manifest;
import android.content.pm.PackageManager;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
public class MainActivity extends AppCompatActivity {
private static final int REQUEST_NOTIFICATION_PERMISSION = 1001;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Android 13+ 需要动态申请通知权限
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(
this,
new String[]{Manifest.permission.POST_NOTIFICATIONS},
REQUEST_NOTIFICATION_PERMISSION
);
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_NOTIFICATION_PERMISSION) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// 权限已授予
}
}
}
}
测试验证
- 安装应用:在 OPPO 手机上安装配置好的应用
- 发送推送:使用之前的测试脚本发送推送消息
- 验证效果:
- ✓ 灭屏状态下应该有声音和振动
- ✓ 锁屏界面应该显示通知
- ✓ 通知栏应该显示消息
- ✓ 通知应该使用"重要消息"渠道
注意事项
- 渠道创建时机:通知渠道应该在应用启动时创建,且只需创建一次
- 渠道优先级:
IMPORTANCE_HIGH表示高优先级,会显示在通知栏顶部并发出声音 - 用户设置:用户可以在系统设置中修改渠道的提醒方式,但高优先级渠道默认会启用声音和振动
- 兼容性:Android 8.0 (API 26) 及以上版本才支持通知渠道,低版本会自动使用传统通知方式
与 OPPO 推送集成
当收到 OPPO 推送消息时,在消息处理回调中使用配置好的通知渠道显示通知即可。这样即使不使用通讯与服务类消息权限,也能实现强提醒效果。