Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2fcb185861 |
@@ -1,262 +0,0 @@
|
|||||||
/**
|
|
||||||
* Android 高优先级通知渠道配置 - 完整示例代码
|
|
||||||
* 包名: com.xunpaisoft.social
|
|
||||||
*/
|
|
||||||
|
|
||||||
// ============================================
|
|
||||||
// 1. 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.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.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
|
|
||||||
|
|
||||||
// 创建渠道
|
|
||||||
notificationManager.createNotificationChannel(importantChannel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ============================================
|
|
||||||
// 2. 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.graphics.BitmapFactory;
|
|
||||||
import android.os.Build;
|
|
||||||
|
|
||||||
public class PushNotificationHelper {
|
|
||||||
|
|
||||||
private static final String CHANNEL_ID = MyApplication.CHANNEL_ID_IMPORTANT;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 显示推送通知
|
|
||||||
* @param context 上下文
|
|
||||||
* @param title 通知标题
|
|
||||||
* @param content 通知内容
|
|
||||||
*/
|
|
||||||
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) {
|
|
||||||
// Android 8.0 及以上使用渠道
|
|
||||||
builder = new Notification.Builder(context, CHANNEL_ID);
|
|
||||||
} else {
|
|
||||||
// Android 8.0 以下
|
|
||||||
builder = new Notification.Builder(context);
|
|
||||||
builder.setPriority(Notification.PRIORITY_HIGH); // 高优先级
|
|
||||||
}
|
|
||||||
|
|
||||||
builder.setContentTitle(title)
|
|
||||||
.setContentText(content)
|
|
||||||
.setSmallIcon(R.drawable.ic_notification) // 小图标(必须)
|
|
||||||
.setLargeIcon(BitmapFactory.decodeResource(
|
|
||||||
context.getResources(),
|
|
||||||
R.drawable.ic_launcher
|
|
||||||
)) // 大图标(可选)
|
|
||||||
.setContentIntent(pendingIntent)
|
|
||||||
.setAutoCancel(true) // 点击后自动取消
|
|
||||||
.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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ============================================
|
|
||||||
// 3. OppoPushMessageService.java - OPPO推送处理
|
|
||||||
// ============================================
|
|
||||||
package com.xunpaisoft.social;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
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();
|
|
||||||
|
|
||||||
// 使用高优先级通知渠道显示通知
|
|
||||||
PushNotificationHelper.showNotification(context, title, content);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ============================================
|
|
||||||
// 4. MainActivity.java - 权限申请(Android 13+)
|
|
||||||
// ============================================
|
|
||||||
package com.xunpaisoft.social;
|
|
||||||
|
|
||||||
import android.Manifest;
|
|
||||||
import android.content.pm.PackageManager;
|
|
||||||
import android.os.Build;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
|
||||||
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+ (API 33+) 需要动态申请通知权限
|
|
||||||
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) {
|
|
||||||
// 权限已授予,可以显示通知
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ============================================
|
|
||||||
// 5. AndroidManifest.xml 配置
|
|
||||||
// ============================================
|
|
||||||
/*
|
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
package="com.xunpaisoft.social">
|
|
||||||
|
|
||||||
<!-- 通知权限 -->
|
|
||||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
|
||||||
|
|
||||||
<!-- 振动权限 -->
|
|
||||||
<uses-permission android:name="android.permission.VIBRATE" />
|
|
||||||
|
|
||||||
<!-- 唤醒锁(可选) -->
|
|
||||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
|
||||||
|
|
||||||
<application
|
|
||||||
android:name=".MyApplication"
|
|
||||||
android:allowBackup="true"
|
|
||||||
android:icon="@mipmap/ic_launcher"
|
|
||||||
android:label="@string/app_name"
|
|
||||||
android:theme="@style/AppTheme">
|
|
||||||
|
|
||||||
<activity
|
|
||||||
android:name=".MainActivity"
|
|
||||||
android:exported="true">
|
|
||||||
<intent-filter>
|
|
||||||
<action android:name="android.intent.action.MAIN" />
|
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
|
||||||
</intent-filter>
|
|
||||||
</activity>
|
|
||||||
|
|
||||||
<!-- 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>
|
|
||||||
</manifest>
|
|
||||||
*/
|
|
||||||
|
|
||||||
@@ -1,414 +0,0 @@
|
|||||||
# Android 高优先级通知渠道配置指南
|
|
||||||
|
|
||||||
## 概述
|
|
||||||
|
|
||||||
在 Android 应用中配置高优先级通知渠道,可以实现强提醒效果,包括:
|
|
||||||
- ✓ 灭屏状态下的声音和振动提醒
|
|
||||||
- ✓ 锁屏界面显示通知
|
|
||||||
- ✓ 通知栏显示消息
|
|
||||||
- ✓ 绕过免打扰模式(部分情况下)
|
|
||||||
|
|
||||||
## 实现步骤
|
|
||||||
|
|
||||||
### 1. 创建高优先级通知渠道
|
|
||||||
|
|
||||||
在应用启动时(Application 或 MainActivity 的 onCreate 中)创建通知渠道:
|
|
||||||
|
|
||||||
```java
|
|
||||||
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
|
|
||||||
|
|
||||||
```xml
|
|
||||||
<application
|
|
||||||
android:name=".MyApplication"
|
|
||||||
...>
|
|
||||||
...
|
|
||||||
</application>
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. 处理 OPPO 推送消息时使用该渠道
|
|
||||||
|
|
||||||
当收到 OPPO 推送消息时,在显示通知时指定使用该渠道:
|
|
||||||
|
|
||||||
```java
|
|
||||||
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 推送接收处理中使用
|
|
||||||
|
|
||||||
```java
|
|
||||||
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 中注册推送服务
|
|
||||||
|
|
||||||
```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
|
|
||||||
|
|
||||||
```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
|
|
||||||
|
|
||||||
```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` 中添加必要权限:
|
|
||||||
|
|
||||||
```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 及以上版本需要动态申请通知权限:
|
|
||||||
|
|
||||||
```java
|
|
||||||
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) {
|
|
||||||
// 权限已授予
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## 测试验证
|
|
||||||
|
|
||||||
1. **安装应用**:在 OPPO 手机上安装配置好的应用
|
|
||||||
2. **发送推送**:使用之前的测试脚本发送推送消息
|
|
||||||
3. **验证效果**:
|
|
||||||
- ✓ 灭屏状态下应该有声音和振动
|
|
||||||
- ✓ 锁屏界面应该显示通知
|
|
||||||
- ✓ 通知栏应该显示消息
|
|
||||||
- ✓ 通知应该使用"重要消息"渠道
|
|
||||||
|
|
||||||
## 注意事项
|
|
||||||
|
|
||||||
1. **渠道创建时机**:通知渠道应该在应用启动时创建,且只需创建一次
|
|
||||||
2. **渠道优先级**:`IMPORTANCE_HIGH` 表示高优先级,会显示在通知栏顶部并发出声音
|
|
||||||
3. **用户设置**:用户可以在系统设置中修改渠道的提醒方式,但高优先级渠道默认会启用声音和振动
|
|
||||||
4. **兼容性**:Android 8.0 (API 26) 及以上版本才支持通知渠道,低版本会自动使用传统通知方式
|
|
||||||
|
|
||||||
## 与 OPPO 推送集成
|
|
||||||
|
|
||||||
当收到 OPPO 推送消息时,在消息处理回调中使用配置好的通知渠道显示通知即可。这样即使不使用通讯与服务类消息权限,也能实现强提醒效果。
|
|
||||||
|
|
||||||
@@ -1,90 +0,0 @@
|
|||||||
# OPPO推送 - 强提醒替代方案
|
|
||||||
|
|
||||||
## 问题
|
|
||||||
|
|
||||||
无法找到"通讯与服务类消息"权限申请入口,但需要实现强提醒功能。
|
|
||||||
|
|
||||||
## 替代方案
|
|
||||||
|
|
||||||
### 方案1: 使用 notify_level 参数(如果支持)
|
|
||||||
|
|
||||||
即使不使用 `previte_message` 频道,也可以尝试设置 `notify_level` 参数:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"notification": {
|
|
||||||
"notify_level": 2, // 2: 通知栏、锁屏、铃声、振动
|
|
||||||
"offLine": true,
|
|
||||||
"offLineTtl": 86400
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 方案2: 在应用端配置通知渠道
|
|
||||||
|
|
||||||
在 Android 应用中创建高优先级通知渠道:
|
|
||||||
|
|
||||||
```java
|
|
||||||
// Android 代码示例
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
||||||
NotificationChannel channel = new NotificationChannel(
|
|
||||||
"high_priority_channel",
|
|
||||||
"重要消息",
|
|
||||||
NotificationManager.IMPORTANCE_HIGH
|
|
||||||
);
|
|
||||||
channel.setDescription("重要消息通知");
|
|
||||||
channel.enableLights(true);
|
|
||||||
channel.enableVibration(true);
|
|
||||||
channel.setVibrationPattern(new long[]{0, 1000, 500, 1000});
|
|
||||||
channel.setSound(Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.notification_sound),
|
|
||||||
new AudioAttributes.Builder()
|
|
||||||
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
|
|
||||||
.setUsage(AudioAttributes.USAGE_NOTIFICATION)
|
|
||||||
.build());
|
|
||||||
|
|
||||||
NotificationManager notificationManager = getSystemService(NotificationManager.class);
|
|
||||||
notificationManager.createNotificationChannel(channel);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 方案3: 联系 OPPO 客服
|
|
||||||
|
|
||||||
如果确实需要通讯与服务类消息权限,可以:
|
|
||||||
1. 在 OPPO 开放平台找到"咨询"或"客服"入口
|
|
||||||
2. 说明需要申请通讯与服务类消息权限
|
|
||||||
3. 提供应用信息和使用场景
|
|
||||||
|
|
||||||
### 方案4: 使用 HTTP API 测试其他参数组合
|
|
||||||
|
|
||||||
尝试不使用 `channel_id`,但设置其他强提醒参数:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"notification": {
|
|
||||||
"title": "知你",
|
|
||||||
"content": "我是api",
|
|
||||||
"notify_level": 2,
|
|
||||||
"category": "IM",
|
|
||||||
"offLine": true,
|
|
||||||
"offLineTtl": 86400,
|
|
||||||
"showTimeType": 0,
|
|
||||||
"networkType": 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## 测试脚本
|
|
||||||
|
|
||||||
已创建测试脚本,可以尝试不同的参数组合:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd /home/renjianbo/push/push_server
|
|
||||||
./test_communication_service_push.sh OPPO_CN_95ac9afc103d70bb26441ec0cbb06b97
|
|
||||||
```
|
|
||||||
|
|
||||||
## 建议
|
|
||||||
|
|
||||||
1. **优先尝试方案2**:在应用端配置高优先级通知渠道,这是最可靠的方案
|
|
||||||
2. **联系客服**:如果必须使用通讯与服务类消息,联系 OPPO 客服咨询申请流程
|
|
||||||
3. **查看文档**:在 OPPO 开放平台的"文档"中查找相关说明
|
|
||||||
|
|
||||||
@@ -1,6 +1,11 @@
|
|||||||
honor.appSecret=a4e5e6a0c8a5d8424aba5a8f0aae3d0c
|
# 荣耀推送服务配置
|
||||||
honor.appId=100221325
|
# 包名: com.xunpaisoft.social
|
||||||
|
# APP ID: 104475849 (用于发送消息)
|
||||||
|
# Client ID: d9fbf0f049834fb992df547819f8b160 (用于获取 token)
|
||||||
|
# Client Secret: 37MeGLszVlQrNNcQ2JMZxhXTHq1E0FQy (用于获取 token)
|
||||||
|
honor.appId=104475849
|
||||||
|
honor.clientId=d9fbf0f049834fb992df547819f8b160
|
||||||
|
honor.clientSecret=37MeGLszVlQrNNcQ2JMZxhXTHq1E0FQy
|
||||||
|
|
||||||
#应用入口Activity类全路径,一定要根据你们的实际情况修改
|
# 应用入口Activity类全路径
|
||||||
#样例:com.example.test.MainActivity
|
honor.badgeClass=com.xunpaisoft.social.im.main.MainActivity
|
||||||
honor.badgeClass=cn.wildfire.chat.app.main.SplashActivity
|
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
vivo.appSecret=d0f24e5b-e92b-4b95-8d45-927bec3ba512
|
# Vivo推送服务配置
|
||||||
vivo.appId=12918
|
# 包名: com.xunpaisoft.social
|
||||||
vivo.appKey=c42feb05-de6c-427d-af55-4f902d9e0a75
|
# AppID: 105830948
|
||||||
|
vivo.appId=105830948
|
||||||
|
vivo.appKey=30dc4748b5bf287a74b5ce67ab5b182d
|
||||||
|
vivo.appSecret=963e208c-496c-4112-b975-7def907b0179
|
||||||
79
push.log
79
push.log
@@ -13,23 +13,23 @@ SLF4J: Actual binding is of type [ch.qos.logback.classic.util.ContextSelectorSta
|
|||||||
=========|_|==============|___/=/_/_/_/
|
=========|_|==============|___/=/_/_/_/
|
||||||
:: Spring Boot :: (v2.0.6.RELEASE)
|
:: Spring Boot :: (v2.0.6.RELEASE)
|
||||||
|
|
||||||
2025-12-31 09:59:06.314 INFO 24833 --- [ main] cn.wildfirechat.push.PushApplication : Starting PushApplication v0.1.2 on VM-4-13-centos with PID 24833 (/home/renjianbo/push/push_server-master/target/push-0.1.2.jar started by renjianbo in /home/renjianbo/push/push_server)
|
2025-12-31 16:18:32.548 INFO 31163 --- [ main] cn.wildfirechat.push.PushApplication : Starting PushApplication v0.1.2 on VM-4-13-centos with PID 31163 (/home/renjianbo/push/push_server-master/target/push-0.1.2.jar started by renjianbo in /home/renjianbo/push/push_server)
|
||||||
2025-12-31 09:59:06.321 INFO 24833 --- [ main] cn.wildfirechat.push.PushApplication : No active profile set, falling back to default profiles: default
|
2025-12-31 16:18:32.567 INFO 31163 --- [ main] cn.wildfirechat.push.PushApplication : No active profile set, falling back to default profiles: default
|
||||||
2025-12-31 09:59:06.433 INFO 24833 --- [ main] ConfigServletWebServerApplicationContext : Refreshing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@2a3046da: startup date [Wed Dec 31 09:59:06 CST 2025]; root of context hierarchy
|
2025-12-31 16:18:32.700 INFO 31163 --- [ main] ConfigServletWebServerApplicationContext : Refreshing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@3ada9e37: startup date [Wed Dec 31 16:18:32 CST 2025]; root of context hierarchy
|
||||||
2025-12-31 09:59:09.464 INFO 24833 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
|
2025-12-31 16:18:35.574 INFO 31163 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
|
||||||
2025-12-31 09:59:09.508 INFO 24833 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
|
2025-12-31 16:18:35.660 INFO 31163 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
|
||||||
2025-12-31 09:59:09.508 INFO 24833 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.34
|
2025-12-31 16:18:35.660 INFO 31163 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.34
|
||||||
2025-12-31 09:59:09.574 INFO 24833 --- [ost-startStop-1] o.a.catalina.core.AprLifecycleListener : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib]
|
2025-12-31 16:18:35.719 INFO 31163 --- [ost-startStop-1] o.a.catalina.core.AprLifecycleListener : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib]
|
||||||
2025-12-31 09:59:09.729 INFO 24833 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
|
2025-12-31 16:18:35.958 INFO 31163 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
|
||||||
2025-12-31 09:59:09.729 INFO 24833 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 3300 ms
|
2025-12-31 16:18:35.959 INFO 31163 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 3263 ms
|
||||||
2025-12-31 09:59:09.836 INFO 24833 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean : Servlet dispatcherServlet mapped to [/]
|
2025-12-31 16:18:36.110 INFO 31163 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean : Servlet dispatcherServlet mapped to [/]
|
||||||
2025-12-31 09:59:09.841 INFO 24833 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]
|
2025-12-31 16:18:36.116 INFO 31163 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]
|
||||||
2025-12-31 09:59:09.841 INFO 24833 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
|
2025-12-31 16:18:36.116 INFO 31163 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
|
||||||
2025-12-31 09:59:09.841 INFO 24833 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'httpPutFormContentFilter' to: [/*]
|
2025-12-31 16:18:36.117 INFO 31163 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'httpPutFormContentFilter' to: [/*]
|
||||||
2025-12-31 09:59:09.841 INFO 24833 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*]
|
2025-12-31 16:18:36.117 INFO 31163 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*]
|
||||||
2025-12-31 09:59:10.031 INFO 24833 --- [ main] c.w.push.android.oppo.OppoPush : OppoPush init start, appKey: bb0819c889ae40cd8bde5a8ad4e670fe, appSecret: 9b5a0e6d56..., appServerSecret: 2d8b4e922d...
|
2025-12-31 16:18:36.331 INFO 31163 --- [ main] c.w.push.android.oppo.OppoPush : OppoPush init start, appKey: bb0819c889ae40cd8bde5a8ad4e670fe, appSecret: 9b5a0e6d56..., appServerSecret: 2d8b4e922d...
|
||||||
2025-12-31 09:59:10.917 INFO 24833 --- [ main] c.w.push.android.oppo.OppoPush : OppoPush init success, using secret: appServerSecret
|
2025-12-31 16:18:37.143 INFO 31163 --- [ main] c.w.push.android.oppo.OppoPush : OppoPush init success, using secret: appServerSecret
|
||||||
2025-12-31 09:59:11.313 ERROR 24833 --- [ main] cn.wildfirechat.push.ios.ApnsServer : ApnsServer init failed
|
2025-12-31 16:18:37.511 ERROR 31163 --- [ main] cn.wildfirechat.push.ios.ApnsServer : ApnsServer init failed
|
||||||
java.security.InvalidKeyException: java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException : null
|
java.security.InvalidKeyException: java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException : null
|
||||||
at com.turo.pushy.apns.auth.ApnsSigningKey.loadFromInputStream(ApnsSigningKey.java:165)
|
at com.turo.pushy.apns.auth.ApnsSigningKey.loadFromInputStream(ApnsSigningKey.java:165)
|
||||||
at com.turo.pushy.apns.auth.ApnsSigningKey.loadFromPkcs8File(ApnsSigningKey.java:107)
|
at com.turo.pushy.apns.auth.ApnsSigningKey.loadFromPkcs8File(ApnsSigningKey.java:107)
|
||||||
@@ -105,29 +105,22 @@ Caused by: java.security.InvalidKeyException: IOException : null
|
|||||||
at sun.security.ec.ECKeyFactory.implGeneratePrivate(ECKeyFactory.java:237)
|
at sun.security.ec.ECKeyFactory.implGeneratePrivate(ECKeyFactory.java:237)
|
||||||
at sun.security.ec.ECKeyFactory.engineGeneratePrivate(ECKeyFactory.java:165)
|
at sun.security.ec.ECKeyFactory.engineGeneratePrivate(ECKeyFactory.java:165)
|
||||||
... 63 more
|
... 63 more
|
||||||
2025-12-31 09:59:11.489 INFO 24833 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
|
2025-12-31 16:18:37.687 INFO 31163 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
|
||||||
2025-12-31 09:59:11.858 INFO 24833 --- [ main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@2a3046da: startup date [Wed Dec 31 09:59:06 CST 2025]; root of context hierarchy
|
2025-12-31 16:18:38.094 INFO 31163 --- [ main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@3ada9e37: startup date [Wed Dec 31 16:18:32 CST 2025]; root of context hierarchy
|
||||||
2025-12-31 09:59:12.017 INFO 24833 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/android/push],methods=[POST],produces=[application/json;charset=UTF-8]}" onto public java.lang.Object cn.wildfirechat.push.PushController.androidPush(cn.wildfirechat.push.PushMessage)
|
2025-12-31 16:18:38.274 INFO 31163 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/android/push],methods=[POST],produces=[application/json;charset=UTF-8]}" onto public java.lang.Object cn.wildfirechat.push.PushController.androidPush(cn.wildfirechat.push.PushMessage)
|
||||||
2025-12-31 09:59:12.019 INFO 24833 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/ios/push],methods=[POST],produces=[application/json;charset=UTF-8]}" onto public java.lang.Object cn.wildfirechat.push.PushController.iOSPush(cn.wildfirechat.push.PushMessage)
|
2025-12-31 16:18:38.276 INFO 31163 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/ios/push],methods=[POST],produces=[application/json;charset=UTF-8]}" onto public java.lang.Object cn.wildfirechat.push.PushController.iOSPush(cn.wildfirechat.push.PushMessage)
|
||||||
2025-12-31 09:59:12.019 INFO 24833 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/harmony/push],methods=[POST],produces=[application/json;charset=UTF-8]}" onto public java.lang.Object cn.wildfirechat.push.PushController.hmPush(cn.wildfirechat.push.PushMessage)
|
2025-12-31 16:18:38.276 INFO 31163 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/harmony/push],methods=[POST],produces=[application/json;charset=UTF-8]}" onto public java.lang.Object cn.wildfirechat.push.PushController.hmPush(cn.wildfirechat.push.PushMessage)
|
||||||
2025-12-31 09:59:12.024 INFO 24833 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
|
2025-12-31 16:18:38.280 INFO 31163 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
|
||||||
2025-12-31 09:59:12.024 INFO 24833 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
|
2025-12-31 16:18:38.280 INFO 31163 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
|
||||||
2025-12-31 09:59:12.103 INFO 24833 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
|
2025-12-31 16:18:38.338 INFO 31163 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
|
||||||
2025-12-31 09:59:12.104 INFO 24833 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
|
2025-12-31 16:18:38.338 INFO 31163 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
|
||||||
2025-12-31 09:59:12.605 INFO 24833 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
|
2025-12-31 16:18:38.814 INFO 31163 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
|
||||||
2025-12-31 09:59:12.669 INFO 24833 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
|
2025-12-31 16:18:38.864 INFO 31163 --- [ main] ConditionEvaluationReportLoggingListener :
|
||||||
2025-12-31 09:59:12.677 INFO 24833 --- [ main] cn.wildfirechat.push.PushApplication : Started PushApplication in 7.306 seconds (JVM running for 8.144)
|
|
||||||
2025-12-31 09:59:22.368 INFO 24833 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization started
|
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
|
||||||
2025-12-31 09:59:22.389 INFO 24833 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization completed in 21 ms
|
2025-12-31 16:18:38.867 ERROR 31163 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :
|
||||||
2025-12-31 09:59:22.520 INFO 24833 --- [nio-8080-exec-1] c.w.push.android.AndroidPushServiceImpl : Android push {"sender":"test_user","senderName":"测试用户","convType":0,"target":"test_target","targetName":"测试目标","line":0,"cntType":1,"serverTime":1767146362000,"pushMessageType":0,"pushType":5,"pushContent":"这是一条测试推送消息 - 2025-12-31 09:59:22","unReceivedMsg":1,"mentionedType":0,"packageName":"com.xunpaisoft.social","deviceToken":"OPPO_CN_95ac9afc103d70bb26441ec0cbb06b97","isHiddenDetail":false,"language":"zh","messageId":1767146362,"callStartUid":0,"republish":false,"existBadgeNumber":0}
|
|
||||||
2025-12-31 09:59:22.626 INFO 24833 --- [pool-2-thread-1] c.w.push.android.oppo.OppoPush : Server response: MessageId: 32150237-1-1-6954837a1acc0c0174ca3d27 ErrorCode: ReturnCode{code=0, message='Success'} Reason: OK
|
*******2025-12-31 16:19:19.465 INFO 29953 --- [ Thread-5] ConfigServletWebServerApplicationContext : Closing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@567d299b: startup date [Wed Dec 31 16:18:07 CST 2025]; root of context hierarchy
|
||||||
2025-12-31 10:01:28.214 INFO 24833 --- [nio-8080-exec-2] c.w.push.android.AndroidPushServiceImpl : Android push {"sender":"test_user","senderName":"测试用户","convType":0,"target":"test_target","targetName":"测试目标","line":0,"cntType":1,"serverTime":1767146488000,"pushMessageType":0,"pushType":5,"pushContent":"这是一条测试推送消息 - 2025-12-31 10:01:28","unReceivedMsg":1,"mentionedType":0,"packageName":"com.xunpaisoft.social","deviceToken":"OPPO_CN_95ac9afc103d70bb26441ec0cbb06b97","isHiddenDetail":false,"language":"zh","messageId":1767146488,"callStartUid":0,"republish":false,"existBadgeNumber":0}
|
2025-12-31 16:19:19.467 INFO 29953 --- [ Thread-5] o.s.j.e.a.AnnotationMBeanExporter : Unregistering JMX-exposed beans on shutdown
|
||||||
2025-12-31 10:01:28.409 INFO 24833 --- [pool-2-thread-2] c.w.push.android.oppo.OppoPush : Server response: MessageId: 32150237-1-1-695483f82b1dd801763a31a4 ErrorCode: ReturnCode{code=0, message='Success'} Reason: OK
|
31163 --- [ main] ConfigServletWebServerApplicationContext : Closing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@3ada9e37: startup date [Wed Dec 31 16:18:32 CST 2025]; root of context hierarchy
|
||||||
2025-12-31 10:03:30.832 INFO 24833 --- [nio-8080-exec-4] c.w.push.android.AndroidPushServiceImpl : Android push {"sender":"test_user","senderName":"测试用户","convType":0,"target":"test_target","targetName":"测试目标","line":0,"cntType":1,"serverTime":1767146610000,"pushMessageType":0,"pushType":5,"pushContent":"这是一条测试推送消息 - 2025-12-31 10:03:30","unReceivedMsg":1,"mentionedType":0,"packageName":"com.xunpaisoft.social","deviceToken":"OPPO_CN_95ac9afc103d70bb26441ec0cbb06b97","isHiddenDetail":false,"language":"zh","messageId":1767146610,"callStartUid":0,"republish":false,"existBadgeNumber":0}
|
2025-12-31 16:18:38.874 INFO 31163 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Unregistering JMX-exposed beans on shutdown
|
||||||
2025-12-31 10:03:30.961 INFO 24833 --- [pool-2-thread-2] c.w.push.android.oppo.OppoPush : Server response: MessageId: 32150237-1-1-6954847239320c018f12aacb ErrorCode: ReturnCode{code=0, message='Success'} Reason: OK
|
|
||||||
2025-12-31 10:07:06.868 INFO 24833 --- [nio-8080-exec-6] c.w.push.android.AndroidPushServiceImpl : Android push {"sender":"api_user","senderName":"知你","convType":0,"target":"test_target","targetName":"测试目标","line":0,"cntType":1,"serverTime":1767146826000,"pushMessageType":0,"pushType":5,"pushContent":"我是api","unReceivedMsg":1,"mentionedType":0,"packageName":"com.xunpaisoft.social","deviceToken":"OPPO_CN_95ac9afc103d70bb26441ec0cbb06b97","isHiddenDetail":false,"language":"zh","messageId":1767146826,"callStartUid":0,"republish":false,"existBadgeNumber":0}
|
|
||||||
2025-12-31 10:07:07.002 INFO 24833 --- [pool-2-thread-2] c.w.push.android.oppo.OppoPush : Server response: MessageId: 32150237-1-1-6954854a35f9ec01757142d9 ErrorCode: ReturnCode{code=0, message='Success'} Reason: OK
|
|
||||||
2025-12-31 10:07:55.122 INFO 24833 --- [nio-8080-exec-8] c.w.push.android.AndroidPushServiceImpl : Android push {"sender":"api_user","senderName":"知你","convType":0,"target":"test_target","targetName":"测试目标","line":0,"cntType":1,"serverTime":1767146875000,"pushMessageType":0,"pushType":5,"pushContent":"我是api","unReceivedMsg":1,"mentionedType":0,"packageName":"com.xunpaisoft.social","deviceToken":"OPPO_CN_95ac9afc103d70bb26441ec0cbb06b97","isHiddenDetail":false,"language":"zh","messageId":1767146875,"callStartUid":0,"republish":false,"existBadgeNumber":0}
|
|
||||||
2025-12-31 10:07:55.249 INFO 24833 --- [pool-2-thread-2] c.w.push.android.oppo.OppoPush : Server response: MessageId: 32150237-1-1-6954857b816b510175dc87a7 ErrorCode: ReturnCode{code=0, message='Success'} Reason: OK
|
|
||||||
2025-12-31 10:13:08.533 INFO 24833 --- [nio-8080-exec-9] c.w.push.android.AndroidPushServiceImpl : Android push {"sender":"api_user","senderName":"知你","convType":0,"target":"test_target","targetName":"测试目标","line":0,"cntType":1,"serverTime":1767147188000,"pushMessageType":0,"pushType":5,"pushContent":"我是api","unReceivedMsg":1,"mentionedType":0,"packageName":"com.xunpaisoft.social","deviceToken":"OPPO_CN_95ac9afc103d70bb26441ec0cbb06b97","isHiddenDetail":false,"language":"zh","messageId":1767147188,"callStartUid":0,"republish":false,"existBadgeNumber":0}
|
|
||||||
2025-12-31 10:13:08.639 INFO 24833 --- [pool-2-thread-2] c.w.push.android.oppo.OppoPush : Server response: MessageId: 32150237-1-1-695486b415eb8d017545d1f9 ErrorCode: ReturnCode{code=0, message='Success'} Reason: OK
|
|
||||||
|
|||||||
@@ -1,115 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# OPPO推送 - 通讯与服务类消息测试脚本
|
|
||||||
# 此脚本使用 HTTP API 直接发送通讯与服务类消息,实现强提醒功能
|
|
||||||
|
|
||||||
if [ -z "$1" ]; then
|
|
||||||
echo "使用方法: $0 <device_token>"
|
|
||||||
echo "device_token: OPPO设备的registration_id"
|
|
||||||
echo ""
|
|
||||||
echo "示例: $0 OPPO_CN_95ac9afc103d70bb26441ec0cbb06b97"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
DEVICE_TOKEN=$1
|
|
||||||
|
|
||||||
# OPPO推送配置
|
|
||||||
APP_KEY="bb0819c889ae40cd8bde5a8ad4e670fe"
|
|
||||||
APP_SERVER_SECRET="2d8b4e922d60453d987f0d09de6eb4a6"
|
|
||||||
API_URL="https://api.push.oppomobile.com"
|
|
||||||
|
|
||||||
echo "=========================================="
|
|
||||||
echo "OPPO推送 - 通讯与服务类消息测试"
|
|
||||||
echo "=========================================="
|
|
||||||
echo "设备Token: $DEVICE_TOKEN"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# 1. 获取 auth_token
|
|
||||||
echo "步骤1: 获取 auth_token..."
|
|
||||||
TIMESTAMP=$(date +%s)000
|
|
||||||
|
|
||||||
# 生成签名: SHA256(app_key + timestamp + master_secret)
|
|
||||||
SIGN_STRING="${APP_KEY}${TIMESTAMP}${APP_SERVER_SECRET}"
|
|
||||||
SIGN=$(echo -n "$SIGN_STRING" | sha256sum | awk '{print $1}')
|
|
||||||
|
|
||||||
echo "Timestamp: $TIMESTAMP"
|
|
||||||
echo "Sign: $SIGN"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# 获取 token
|
|
||||||
AUTH_RESPONSE=$(curl -s -X POST "${API_URL}/server/v1/auth" \
|
|
||||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
|
||||||
-d "app_key=${APP_KEY}×tamp=${TIMESTAMP}&sign=${SIGN}")
|
|
||||||
|
|
||||||
echo "Auth响应: $AUTH_RESPONSE"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# 解析 token
|
|
||||||
AUTH_TOKEN=$(echo "$AUTH_RESPONSE" | grep -o '"auth_token":"[^"]*' | cut -d'"' -f4)
|
|
||||||
|
|
||||||
if [ -z "$AUTH_TOKEN" ]; then
|
|
||||||
echo "错误: 无法获取 auth_token"
|
|
||||||
echo "响应: $AUTH_RESPONSE"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "✓ 获取 auth_token 成功: ${AUTH_TOKEN:0:20}..."
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# 2. 发送通讯与服务类消息
|
|
||||||
echo "步骤2: 发送通讯与服务类消息..."
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# 构建消息体(包含通讯与服务类消息参数)
|
|
||||||
MESSAGE_JSON=$(cat <<EOF
|
|
||||||
{
|
|
||||||
"target_type": 1,
|
|
||||||
"target_value": "$DEVICE_TOKEN",
|
|
||||||
"notification": {
|
|
||||||
"title": "知你",
|
|
||||||
"content": "我是api",
|
|
||||||
"channel_id": "previte_message",
|
|
||||||
"channel_name": "消息推送",
|
|
||||||
"category": "IM",
|
|
||||||
"notify_level": 2,
|
|
||||||
"offLine": true,
|
|
||||||
"offLineTtl": 86400,
|
|
||||||
"showTimeType": 0,
|
|
||||||
"networkType": 0,
|
|
||||||
"style": 1,
|
|
||||||
"clickActionType": 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
)
|
|
||||||
|
|
||||||
echo "消息体:"
|
|
||||||
echo "$MESSAGE_JSON" | python -m json.tool 2>/dev/null || echo "$MESSAGE_JSON"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# 发送推送
|
|
||||||
PUSH_RESPONSE=$(curl -s -X POST "${API_URL}/server/v1/message/notification/unicast" \
|
|
||||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
|
||||||
-d "message=$(echo "$MESSAGE_JSON" | python -c "import sys, json, urllib.parse; print(urllib.parse.quote(json.dumps(json.load(sys.stdin))))" 2>/dev/null || echo "$MESSAGE_JSON")&auth_token=${AUTH_TOKEN}")
|
|
||||||
|
|
||||||
echo "推送响应:"
|
|
||||||
echo "$PUSH_RESPONSE" | python -m json.tool 2>/dev/null || echo "$PUSH_RESPONSE"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# 检查结果
|
|
||||||
if echo "$PUSH_RESPONSE" | grep -q '"code":0'; then
|
|
||||||
echo "✓ 推送成功!"
|
|
||||||
echo ""
|
|
||||||
echo "请检查OPPO手机:"
|
|
||||||
echo "1. 灭屏状态下应该有声音和振动提醒"
|
|
||||||
echo "2. 锁屏界面应该显示通知"
|
|
||||||
echo "3. 通知栏应该显示消息"
|
|
||||||
echo "4. 消息应该被分类为'通讯与服务'类型"
|
|
||||||
else
|
|
||||||
echo "✗ 推送失败"
|
|
||||||
echo "响应: $PUSH_RESPONSE"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "=========================================="
|
|
||||||
|
|
||||||
95
test_honor_push.sh
Executable file
95
test_honor_push.sh
Executable file
@@ -0,0 +1,95 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# 荣耀推送测试脚本 (使用8080端口)
|
||||||
|
# 使用方法: ./test_honor_push.sh <device_token>
|
||||||
|
# device_token: 荣耀手机的push token,需要从荣耀手机应用中获取
|
||||||
|
|
||||||
|
if [ -z "$1" ]; then
|
||||||
|
echo "=========================================="
|
||||||
|
echo "荣耀推送测试脚本 (端口: 8080)"
|
||||||
|
echo "=========================================="
|
||||||
|
echo ""
|
||||||
|
echo "使用方法: $0 <device_token>"
|
||||||
|
echo ""
|
||||||
|
echo "device_token: 荣耀手机的push token"
|
||||||
|
echo " (需要从荣耀手机应用中获取)"
|
||||||
|
echo ""
|
||||||
|
echo "示例: $0 your_honor_push_token"
|
||||||
|
echo ""
|
||||||
|
echo "如果没有device_token,请:"
|
||||||
|
echo "1. 在荣耀手机上安装应用 (包名: com.xunpaisoft.social)"
|
||||||
|
echo "2. 启动应用并查看日志获取push token"
|
||||||
|
echo "3. 或者从荣耀推送平台查看设备列表"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
DEVICE_TOKEN=$1
|
||||||
|
SERVER_URL="http://localhost:8080/android/push"
|
||||||
|
|
||||||
|
echo "=========================================="
|
||||||
|
echo "正在测试荣耀推送..."
|
||||||
|
echo "=========================================="
|
||||||
|
echo "设备Token: $DEVICE_TOKEN"
|
||||||
|
echo "服务器地址: $SERVER_URL"
|
||||||
|
echo "包名: com.xunpaisoft.social"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# 构建推送消息JSON
|
||||||
|
# pushType=8 表示 荣耀推送类型 (AndroidPushType.ANDROID_PUSH_TYPE_HONOR = 8)
|
||||||
|
TIMESTAMP=$(date +%s)
|
||||||
|
MESSAGE_ID=$TIMESTAMP
|
||||||
|
|
||||||
|
RESPONSE=$(curl -s -w "\nHTTP_CODE:%{http_code}" -X POST "$SERVER_URL" \
|
||||||
|
-H "Content-Type: application/json;charset=UTF-8" \
|
||||||
|
-d "{
|
||||||
|
\"pushType\": 8,
|
||||||
|
\"pushMessageType\": 0,
|
||||||
|
\"packageName\": \"com.xunpaisoft.social\",
|
||||||
|
\"deviceToken\": \"$DEVICE_TOKEN\",
|
||||||
|
\"pushContent\": \"这是一条测试推送消息 - $(date '+%Y-%m-%d %H:%M:%S')\",
|
||||||
|
\"sender\": \"test_user\",
|
||||||
|
\"senderName\": \"测试用户\",
|
||||||
|
\"target\": \"test_target\",
|
||||||
|
\"targetName\": \"测试目标\",
|
||||||
|
\"convType\": 0,
|
||||||
|
\"line\": 0,
|
||||||
|
\"cntType\": 1,
|
||||||
|
\"serverTime\": ${TIMESTAMP}000,
|
||||||
|
\"unReceivedMsg\": 1,
|
||||||
|
\"mentionedType\": 0,
|
||||||
|
\"isHiddenDetail\": false,
|
||||||
|
\"language\": \"zh\",
|
||||||
|
\"messageId\": $MESSAGE_ID,
|
||||||
|
\"republish\": false,
|
||||||
|
\"existBadgeNumber\": 0
|
||||||
|
}")
|
||||||
|
|
||||||
|
HTTP_CODE=$(echo "$RESPONSE" | grep "HTTP_CODE:" | cut -d: -f2)
|
||||||
|
BODY=$(echo "$RESPONSE" | sed '/HTTP_CODE:/d')
|
||||||
|
|
||||||
|
echo "----------------------------------------"
|
||||||
|
echo "服务器响应:"
|
||||||
|
echo "----------------------------------------"
|
||||||
|
echo "$BODY" | python -m json.tool 2>/dev/null || echo "$BODY"
|
||||||
|
echo ""
|
||||||
|
echo "HTTP状态码: $HTTP_CODE"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
if [ "$HTTP_CODE" = "200" ]; then
|
||||||
|
echo "✓ 推送请求已发送成功!"
|
||||||
|
echo ""
|
||||||
|
echo "请检查:"
|
||||||
|
echo "1. 荣耀手机是否收到推送通知"
|
||||||
|
echo "2. 查看服务器日志了解详细推送结果"
|
||||||
|
else
|
||||||
|
echo "✗ 推送请求失败 (HTTP $HTTP_CODE)"
|
||||||
|
echo ""
|
||||||
|
echo "请检查:"
|
||||||
|
echo "1. 服务器是否正常运行在8080端口"
|
||||||
|
echo "2. device_token 是否正确"
|
||||||
|
echo "3. 查看服务器日志: tail -f push.log 或查看控制台输出"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=========================================="
|
||||||
|
|
||||||
@@ -1,132 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# OPPO推送 - 使用新通道方式测试(通过category标记)
|
|
||||||
# 根据OPPO平台说明:如果标记category使用新通道能力,用户的通知二级开关默认开启
|
|
||||||
|
|
||||||
if [ -z "$1" ]; then
|
|
||||||
echo "使用方法: $0 <device_token>"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
DEVICE_TOKEN=$1
|
|
||||||
|
|
||||||
# OPPO推送配置
|
|
||||||
APP_KEY="bb0819c889ae40cd8bde5a8ad4e670fe"
|
|
||||||
APP_SERVER_SECRET="2d8b4e922d60453d987f0d09de6eb4a6"
|
|
||||||
API_URL="https://api.push.oppomobile.com"
|
|
||||||
|
|
||||||
echo "=========================================="
|
|
||||||
echo "OPPO推送 - 新通道方式测试(使用category标记)"
|
|
||||||
echo "=========================================="
|
|
||||||
|
|
||||||
# 1. 获取 auth_token
|
|
||||||
TIMESTAMP=$(date +%s)000
|
|
||||||
SIGN_STRING="${APP_KEY}${TIMESTAMP}${APP_SERVER_SECRET}"
|
|
||||||
SIGN=$(echo -n "$SIGN_STRING" | sha256sum | awk '{print $1}')
|
|
||||||
|
|
||||||
AUTH_RESPONSE=$(curl -s -X POST "${API_URL}/server/v1/auth" \
|
|
||||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
|
||||||
-d "app_key=${APP_KEY}×tamp=${TIMESTAMP}&sign=${SIGN}")
|
|
||||||
|
|
||||||
AUTH_TOKEN=$(echo "$AUTH_RESPONSE" | grep -o '"auth_token":"[^"]*' | cut -d'"' -f4)
|
|
||||||
|
|
||||||
if [ -z "$AUTH_TOKEN" ]; then
|
|
||||||
echo "错误: 无法获取 auth_token"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "✓ 获取 auth_token 成功"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# 2. 尝试方式1: 使用category标记,不指定channel_id(让系统自动使用新通道)
|
|
||||||
echo "方式1: 使用category=IM,不指定channel_id..."
|
|
||||||
MESSAGE_JSON1=$(cat <<EOF
|
|
||||||
{
|
|
||||||
"target_type": 1,
|
|
||||||
"target_value": "$DEVICE_TOKEN",
|
|
||||||
"notification": {
|
|
||||||
"title": "知你",
|
|
||||||
"content": "我是api - 新通道测试1",
|
|
||||||
"category": "IM",
|
|
||||||
"notify_level": 2,
|
|
||||||
"offLine": true,
|
|
||||||
"offLineTtl": 86400,
|
|
||||||
"showTimeType": 0,
|
|
||||||
"networkType": 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
)
|
|
||||||
|
|
||||||
PUSH_RESPONSE1=$(curl -s -X POST "${API_URL}/server/v1/message/notification/unicast" \
|
|
||||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
|
||||||
-d "message=$(echo "$MESSAGE_JSON1" | python -c "import sys, json, urllib.parse; print(urllib.parse.quote(json.dumps(json.load(sys.stdin))))" 2>/dev/null || echo "$MESSAGE_JSON1")&auth_token=${AUTH_TOKEN}")
|
|
||||||
|
|
||||||
echo "响应1:"
|
|
||||||
echo "$PUSH_RESPONSE1" | python -m json.tool 2>/dev/null || echo "$PUSH_RESPONSE1"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# 3. 尝试方式2: 使用已存在的通道ID
|
|
||||||
echo "方式2: 使用已存在的通道ID (previte_message)..."
|
|
||||||
MESSAGE_JSON2=$(cat <<EOF
|
|
||||||
{
|
|
||||||
"target_type": 1,
|
|
||||||
"target_value": "$DEVICE_TOKEN",
|
|
||||||
"notification": {
|
|
||||||
"title": "知你",
|
|
||||||
"content": "我是api - 新通道测试2",
|
|
||||||
"channel_id": "previte_message",
|
|
||||||
"channel_name": "消息推送",
|
|
||||||
"category": "IM",
|
|
||||||
"notify_level": 2,
|
|
||||||
"offLine": true,
|
|
||||||
"offLineTtl": 86400,
|
|
||||||
"showTimeType": 0,
|
|
||||||
"networkType": 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
)
|
|
||||||
|
|
||||||
PUSH_RESPONSE2=$(curl -s -X POST "${API_URL}/server/v1/message/notification/unicast" \
|
|
||||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
|
||||||
-d "message=$(echo "$MESSAGE_JSON2" | python -c "import sys, json, urllib.parse; print(urllib.parse.quote(json.dumps(json.load(sys.stdin))))" 2>/dev/null || echo "$MESSAGE_JSON2")&auth_token=${AUTH_TOKEN}")
|
|
||||||
|
|
||||||
echo "响应2:"
|
|
||||||
echo "$PUSH_RESPONSE2" | python -m json.tool 2>/dev/null || echo "$PUSH_RESPONSE2"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# 4. 尝试方式3: 使用其他已存在的通道ID
|
|
||||||
echo "方式3: 使用其他通道ID (oppo_push_im)..."
|
|
||||||
MESSAGE_JSON3=$(cat <<EOF
|
|
||||||
{
|
|
||||||
"target_type": 1,
|
|
||||||
"target_value": "$DEVICE_TOKEN",
|
|
||||||
"notification": {
|
|
||||||
"title": "知你",
|
|
||||||
"content": "我是api - 新通道测试3",
|
|
||||||
"channel_id": "oppo_push_im",
|
|
||||||
"channel_name": "重要消息通知",
|
|
||||||
"category": "IM",
|
|
||||||
"notify_level": 2,
|
|
||||||
"offLine": true,
|
|
||||||
"offLineTtl": 86400,
|
|
||||||
"showTimeType": 0,
|
|
||||||
"networkType": 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
)
|
|
||||||
|
|
||||||
PUSH_RESPONSE3=$(curl -s -X POST "${API_URL}/server/v1/message/notification/unicast" \
|
|
||||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
|
||||||
-d "message=$(echo "$MESSAGE_JSON3" | python -c "import sys, json, urllib.parse; print(urllib.parse.quote(json.dumps(json.load(sys.stdin))))" 2>/dev/null || echo "$MESSAGE_JSON3")&auth_token=${AUTH_TOKEN}")
|
|
||||||
|
|
||||||
echo "响应3:"
|
|
||||||
echo "$PUSH_RESPONSE3" | python -m json.tool 2>/dev/null || echo "$PUSH_RESPONSE3"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
echo "=========================================="
|
|
||||||
echo "测试完成!请检查哪个方式成功,并在手机上验证提醒效果。"
|
|
||||||
echo "=========================================="
|
|
||||||
|
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# OPPO推送 - 强提醒测试脚本(不使用通讯与服务类消息权限)
|
|
||||||
# 尝试通过其他参数实现强提醒效果
|
|
||||||
|
|
||||||
if [ -z "$1" ]; then
|
|
||||||
echo "使用方法: $0 <device_token>"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
DEVICE_TOKEN=$1
|
|
||||||
|
|
||||||
# OPPO推送配置
|
|
||||||
APP_KEY="bb0819c889ae40cd8bde5a8ad4e670fe"
|
|
||||||
APP_SERVER_SECRET="2d8b4e922d60453d987f0d09de6eb4a6"
|
|
||||||
API_URL="https://api.push.oppomobile.com"
|
|
||||||
|
|
||||||
echo "=========================================="
|
|
||||||
echo "OPPO推送 - 强提醒测试(不使用通讯与服务权限)"
|
|
||||||
echo "=========================================="
|
|
||||||
|
|
||||||
# 1. 获取 auth_token
|
|
||||||
TIMESTAMP=$(date +%s)000
|
|
||||||
SIGN_STRING="${APP_KEY}${TIMESTAMP}${APP_SERVER_SECRET}"
|
|
||||||
SIGN=$(echo -n "$SIGN_STRING" | sha256sum | awk '{print $1}')
|
|
||||||
|
|
||||||
AUTH_RESPONSE=$(curl -s -X POST "${API_URL}/server/v1/auth" \
|
|
||||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
|
||||||
-d "app_key=${APP_KEY}×tamp=${TIMESTAMP}&sign=${SIGN}")
|
|
||||||
|
|
||||||
AUTH_TOKEN=$(echo "$AUTH_RESPONSE" | grep -o '"auth_token":"[^"]*' | cut -d'"' -f4)
|
|
||||||
|
|
||||||
if [ -z "$AUTH_TOKEN" ]; then
|
|
||||||
echo "错误: 无法获取 auth_token"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "✓ 获取 auth_token 成功"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# 2. 发送消息(尝试使用 notify_level 等参数,但不使用 channel_id)
|
|
||||||
MESSAGE_JSON=$(cat <<EOF
|
|
||||||
{
|
|
||||||
"target_type": 1,
|
|
||||||
"target_value": "$DEVICE_TOKEN",
|
|
||||||
"notification": {
|
|
||||||
"title": "知你",
|
|
||||||
"content": "我是api - 强提醒测试",
|
|
||||||
"notify_level": 2,
|
|
||||||
"category": "IM",
|
|
||||||
"offLine": true,
|
|
||||||
"offLineTtl": 86400,
|
|
||||||
"showTimeType": 0,
|
|
||||||
"networkType": 0,
|
|
||||||
"style": 1,
|
|
||||||
"clickActionType": 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
)
|
|
||||||
|
|
||||||
echo "发送消息(不使用 channel_id)..."
|
|
||||||
PUSH_RESPONSE=$(curl -s -X POST "${API_URL}/server/v1/message/notification/unicast" \
|
|
||||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
|
||||||
-d "message=$(echo "$MESSAGE_JSON" | python -c "import sys, json, urllib.parse; print(urllib.parse.quote(json.dumps(json.load(sys.stdin))))" 2>/dev/null || echo "$MESSAGE_JSON")&auth_token=${AUTH_TOKEN}")
|
|
||||||
|
|
||||||
echo "响应:"
|
|
||||||
echo "$PUSH_RESPONSE" | python -m json.tool 2>/dev/null || echo "$PUSH_RESPONSE"
|
|
||||||
|
|
||||||
if echo "$PUSH_RESPONSE" | grep -q '"code":0'; then
|
|
||||||
echo ""
|
|
||||||
echo "✓ 推送成功!"
|
|
||||||
echo "注意:如果仍然没有强提醒,建议在应用端配置高优先级通知渠道"
|
|
||||||
else
|
|
||||||
echo ""
|
|
||||||
echo "✗ 推送失败"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "=========================================="
|
|
||||||
|
|
||||||
95
test_vivo_push.sh
Executable file
95
test_vivo_push.sh
Executable file
@@ -0,0 +1,95 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Vivo推送测试脚本 (使用8080端口)
|
||||||
|
# 使用方法: ./test_vivo_push.sh <reg_id>
|
||||||
|
# reg_id: Vivo手机的registration_id,格式为 v2-xxx
|
||||||
|
|
||||||
|
if [ -z "$1" ]; then
|
||||||
|
echo "=========================================="
|
||||||
|
echo "Vivo推送测试脚本 (端口: 8080)"
|
||||||
|
echo "=========================================="
|
||||||
|
echo ""
|
||||||
|
echo "使用方法: $0 <reg_id>"
|
||||||
|
echo ""
|
||||||
|
echo "reg_id: Vivo手机的registration_id"
|
||||||
|
echo " (格式: v2-xxx,需要从Vivo手机应用中获取)"
|
||||||
|
echo ""
|
||||||
|
echo "示例: $0 v2-CRujhn6Z8OU26yX4_EeUtGmiR6nJ21CXJmoFRMstHinrLqU9vH3u8g4OQQ"
|
||||||
|
echo ""
|
||||||
|
echo "如果没有reg_id,请:"
|
||||||
|
echo "1. 在Vivo手机上安装应用 (包名: com.xunpaisoft.social)"
|
||||||
|
echo "2. 启动应用并查看日志获取reg_id"
|
||||||
|
echo "3. 或者从Vivo推送平台查看设备列表"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
REG_ID=$1
|
||||||
|
SERVER_URL="http://localhost:8080/android/push"
|
||||||
|
|
||||||
|
echo "=========================================="
|
||||||
|
echo "正在测试Vivo推送..."
|
||||||
|
echo "=========================================="
|
||||||
|
echo "设备RegId: $REG_ID"
|
||||||
|
echo "服务器地址: $SERVER_URL"
|
||||||
|
echo "包名: com.xunpaisoft.social"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# 构建推送消息JSON
|
||||||
|
# pushType=4 表示 Vivo 推送类型 (AndroidPushType.ANDROID_PUSH_TYPE_VIVO = 4)
|
||||||
|
TIMESTAMP=$(date +%s)
|
||||||
|
MESSAGE_ID=$TIMESTAMP
|
||||||
|
|
||||||
|
RESPONSE=$(curl -s -w "\nHTTP_CODE:%{http_code}" -X POST "$SERVER_URL" \
|
||||||
|
-H "Content-Type: application/json;charset=UTF-8" \
|
||||||
|
-d "{
|
||||||
|
\"pushType\": 4,
|
||||||
|
\"pushMessageType\": 0,
|
||||||
|
\"packageName\": \"com.xunpaisoft.social\",
|
||||||
|
\"deviceToken\": \"$REG_ID\",
|
||||||
|
\"pushContent\": \"这是一条测试推送消息 - $(date '+%Y-%m-%d %H:%M:%S')\",
|
||||||
|
\"sender\": \"test_user\",
|
||||||
|
\"senderName\": \"测试用户\",
|
||||||
|
\"target\": \"test_target\",
|
||||||
|
\"targetName\": \"测试目标\",
|
||||||
|
\"convType\": 0,
|
||||||
|
\"line\": 0,
|
||||||
|
\"cntType\": 1,
|
||||||
|
\"serverTime\": ${TIMESTAMP}000,
|
||||||
|
\"unReceivedMsg\": 1,
|
||||||
|
\"mentionedType\": 0,
|
||||||
|
\"isHiddenDetail\": false,
|
||||||
|
\"language\": \"zh\",
|
||||||
|
\"messageId\": $MESSAGE_ID,
|
||||||
|
\"republish\": false,
|
||||||
|
\"existBadgeNumber\": 0
|
||||||
|
}")
|
||||||
|
|
||||||
|
HTTP_CODE=$(echo "$RESPONSE" | grep "HTTP_CODE:" | cut -d: -f2)
|
||||||
|
BODY=$(echo "$RESPONSE" | sed '/HTTP_CODE:/d')
|
||||||
|
|
||||||
|
echo "----------------------------------------"
|
||||||
|
echo "服务器响应:"
|
||||||
|
echo "----------------------------------------"
|
||||||
|
echo "$BODY" | python -m json.tool 2>/dev/null || echo "$BODY"
|
||||||
|
echo ""
|
||||||
|
echo "HTTP状态码: $HTTP_CODE"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
if [ "$HTTP_CODE" = "200" ]; then
|
||||||
|
echo "✓ 推送请求已发送成功!"
|
||||||
|
echo ""
|
||||||
|
echo "请检查:"
|
||||||
|
echo "1. Vivo手机是否收到推送通知"
|
||||||
|
echo "2. 查看服务器日志了解详细推送结果"
|
||||||
|
else
|
||||||
|
echo "✗ 推送请求失败 (HTTP $HTTP_CODE)"
|
||||||
|
echo ""
|
||||||
|
echo "请检查:"
|
||||||
|
echo "1. 服务器是否正常运行在8080端口"
|
||||||
|
echo "2. reg_id 是否正确"
|
||||||
|
echo "3. 查看服务器日志: tail -f push.log 或查看控制台输出"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=========================================="
|
||||||
|
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
# OPPO推送 - 通讯与服务类消息权限申请说明
|
|
||||||
|
|
||||||
## 问题
|
|
||||||
|
|
||||||
发送通讯与服务类消息时,返回错误:
|
|
||||||
```
|
|
||||||
{"code":67,"message":"private classify channel need permission"}
|
|
||||||
```
|
|
||||||
|
|
||||||
## 原因
|
|
||||||
|
|
||||||
使用 `previte_message` 频道(通讯与服务类消息)需要在 OPPO 开放平台申请特殊权限。
|
|
||||||
|
|
||||||
## 解决方案
|
|
||||||
|
|
||||||
### 步骤1: 登录 OPPO 开放平台
|
|
||||||
|
|
||||||
访问:https://open.oppomobile.com
|
|
||||||
|
|
||||||
### 步骤2: 进入应用管理
|
|
||||||
|
|
||||||
1. 登录后,进入"应用管理"
|
|
||||||
2. 找到您的应用(包名: com.xunpaisoft.social)
|
|
||||||
3. 进入应用详情页面
|
|
||||||
|
|
||||||
### 步骤3: 申请通讯与服务类消息权限
|
|
||||||
|
|
||||||
1. 在应用详情页面,找到"推送服务"或"消息推送"相关设置
|
|
||||||
2. 查找"通讯与服务类消息"或"私信类消息"权限申请入口
|
|
||||||
3. 提交权限申请,填写相关信息:
|
|
||||||
- 应用用途说明
|
|
||||||
- 使用场景说明
|
|
||||||
- 为什么需要通讯与服务类消息权限
|
|
||||||
|
|
||||||
### 步骤4: 等待审核
|
|
||||||
|
|
||||||
- 通常审核时间为 1-3 个工作日
|
|
||||||
- 审核通过后,即可使用 `previte_message` 频道发送通讯与服务类消息
|
|
||||||
|
|
||||||
## 申请权限后
|
|
||||||
|
|
||||||
权限申请通过后,可以使用以下参数发送通讯与服务类消息:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"notification": {
|
|
||||||
"channel_id": "previte_message",
|
|
||||||
"channel_name": "消息推送",
|
|
||||||
"category": "IM",
|
|
||||||
"notify_level": 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
这些参数将实现:
|
|
||||||
- ✓ 离线消息强提醒
|
|
||||||
- ✓ 通知栏、锁屏、铃声、振动
|
|
||||||
- ✓ 灭屏状态下的声音和振动提醒
|
|
||||||
|
|
||||||
## 临时方案
|
|
||||||
|
|
||||||
如果暂时无法申请权限,可以:
|
|
||||||
1. 使用普通推送消息(当前方式)
|
|
||||||
2. 在应用端配置通知渠道,实现部分强提醒效果
|
|
||||||
3. 等待权限申请通过后再使用通讯与服务类消息
|
|
||||||
|
|
||||||
## 测试脚本
|
|
||||||
|
|
||||||
权限申请通过后,可以使用以下脚本测试:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd /home/renjianbo/push/push_server
|
|
||||||
./test_communication_service_push.sh OPPO_CN_95ac9afc103d70bb26441ec0cbb06b97
|
|
||||||
```
|
|
||||||
|
|
||||||
## 相关文档
|
|
||||||
|
|
||||||
- OPPO推送服务文档:https://open.oppomobile.com/documentation/page/info?id=13189
|
|
||||||
- OPPO开放平台:https://open.oppomobile.com
|
|
||||||
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
# OPPO推送 - 通讯与服务类消息配置说明
|
|
||||||
|
|
||||||
## 问题描述
|
|
||||||
|
|
||||||
当前推送的消息是"内容与运营"类型,只有声音提醒,灭屏时没有强提醒。
|
|
||||||
需要发送"通讯与服务"类型的消息,实现:
|
|
||||||
- 离线消息强提醒
|
|
||||||
- 通知栏、锁屏、铃声、振动
|
|
||||||
|
|
||||||
## 解决方案
|
|
||||||
|
|
||||||
OPPO SDK 的 `Notification` 类不支持设置通讯与服务类消息的关键参数,需要使用 HTTP API 直接发送。
|
|
||||||
|
|
||||||
## 需要设置的参数
|
|
||||||
|
|
||||||
1. **channel_id**: `"previte_message"` - 通讯与服务频道ID(必须)
|
|
||||||
2. **channel_name**: `"消息推送"` - 频道名称(必须)
|
|
||||||
3. **category**: `"IM"` - 消息类别,IM表示即时聊天、音频、视频通话(必须)
|
|
||||||
4. **notify_level**: `2` - 通知级别,2表示通知栏、锁屏、铃声、振动(必须)
|
|
||||||
|
|
||||||
## 实现方式
|
|
||||||
|
|
||||||
由于 `push_server-master` 项目使用的是 OPPO SDK,而 SDK 的 `Notification` 类不支持这些参数,需要:
|
|
||||||
|
|
||||||
### 方案1: 修改为使用 HTTP API(推荐)
|
|
||||||
|
|
||||||
修改 `OppoPush.java`,添加使用 HTTP API 发送通讯与服务类消息的方法。
|
|
||||||
|
|
||||||
### 方案2: 通过 API 直接调用(临时方案)
|
|
||||||
|
|
||||||
不修改代码,直接通过 HTTP API 发送通讯与服务类消息。
|
|
||||||
|
|
||||||
## 直接使用 HTTP API 发送的示例
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 1. 先获取 auth_token
|
|
||||||
curl -X POST "https://api.push.oppomobile.com/server/v1/auth" \
|
|
||||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
|
||||||
-d "app_key=bb0819c889ae40cd8bde5a8ad4e670fe×tamp=$(date +%s)000&sign=生成的签名"
|
|
||||||
|
|
||||||
# 2. 使用 auth_token 发送通讯与服务类消息
|
|
||||||
curl -X POST "https://api.push.oppomobile.com/server/v1/message/notification/unicast" \
|
|
||||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
|
||||||
-d "message={\"target_type\":1,\"target_value\":\"OPPO_CN_95ac9afc103d70bb26441ec0cbb06b97\",\"notification\":{\"title\":\"知你\",\"content\":\"我是api\",\"channel_id\":\"previte_message\",\"channel_name\":\"消息推送\",\"category\":\"IM\",\"notify_level\":2,\"offLine\":true,\"offLineTtl\":86400,\"showTimeType\":0,\"networkType\":0}}&auth_token=你的auth_token"
|
|
||||||
```
|
|
||||||
|
|
||||||
## 注意事项
|
|
||||||
|
|
||||||
1. **频道ID必须正确**: `channel_id` 必须设置为 `"previte_message"`,这是 OPPO 系统识别的通讯与服务类消息标识
|
|
||||||
2. **频道名称**: `channel_name` 必须设置为 `"消息推送"`
|
|
||||||
3. **通知级别**: `notify_level` 设置为 `2` 才能实现通知栏、锁屏、铃声、振动的强提醒
|
|
||||||
4. **类别**: `category` 设置为 `"IM"` 表示即时聊天、音频、视频通话类消息
|
|
||||||
5. **离线消息**: `offLine` 设置为 `true`,`offLineTtl` 建议设置为 `86400`(24小时)
|
|
||||||
|
|
||||||
## 验证方法
|
|
||||||
|
|
||||||
发送通讯与服务类消息后,应该:
|
|
||||||
1. ✓ 在灭屏状态下有声音和振动提醒
|
|
||||||
2. ✓ 在锁屏界面显示通知
|
|
||||||
3. ✓ 在通知栏显示消息
|
|
||||||
4. ✓ 消息被分类为"通讯与服务"类型
|
|
||||||
|
|
||||||
## 下一步
|
|
||||||
|
|
||||||
需要修改 `push_server-master/src/main/java/cn/wildfirechat/push/android/oppo/OppoPush.java`,添加使用 HTTP API 发送通讯与服务类消息的功能。
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user