uni-app分享使用原生Android推送消息(内推)以及点击通知监听数据的方法

发布于 1周前 作者 ionicwang 来自 Uni-App

uni-app分享使用原生Android推送消息(内推)以及点击通知监听数据的方法

前言

由于用uniapp官方的plus.push.createMessage()在Android平台下推送通知无法显示推送时间,需要调用原生Android推送通知。
在社区综合了各大神的代码,具体如下:

推送

推送事件

/**  
  * android原生通知发送  
  * @param content 通知内容  
  * @param data json对象,存储通知的隐藏数据,用于点击通知时接收使用  
  */  
android_notify(content = '', data = {}) {  
  // #ifdef APP-PLUS  
  var title = '通知标题';  

  console.log('准备通知');  
  console.log(plus.os.name);  

  // Android平台下才使用此推送  
  if (plus.os.name != 'Android') {  
    return false;  
  }  

  // 随机生成通知ID  
  var NotifyID = Math.floor(Math.random() * 10000) + 1;  

  var main = plus.android.runtimeMainActivity();  
  var Context = plus.android.importClass("android.content.Context");  
  var NotificationManager = plus.android.importClass("android.app.NotificationManager");    
  var nm = main.getSystemService(Context.NOTIFICATION_SERVICE);  

  var Notification = plus.android.importClass("android.app.Notification");  
  var Intent = plus.android.importClass("android.content.Intent");  
  var PendingIntent = plus.android.importClass("android.app.PendingIntent");  
  var intent = new Intent(main, main.getClass());  

  // 传递参数  
  var payload = {  
    'msg': content,  
    'notify_id': NotifyID,  
    'data': data  
  };  
  intent.putExtra("receive", JSON.stringify(payload));  

  // PendingIntent.getActivity的第二个参数需要设置为随机数,否则多个通知时会导致前面的通知被后面的通知替换Extra的数据  
  var pendingIntent = PendingIntent.getActivity(main, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);  
  var SystemVersion = plus.os.version;  
  var firstVersionNumber = Number(SystemVersion.split('.')[0]);  
  var r = plus.android.importClass("android.R");  
  var mNotification;  

  // 判断当前系统版本在8.0及以上  
  if (firstVersionNumber >= 8){  
    var NotificationChannel = plus.android.importClass('android.app.NotificationChannel');  
    var channel = new NotificationChannel("s" + NotifyID, "1", NotificationManager.IMPORTANCE_HIGH);  
    nm.createNotificationChannel(channel);  
    Notification = plus.android.importClass("android.support.v4.app.NotificationCompat");  
    mNotification = new Notification.Builder(main, "s" + NotifyID);  
  } else {  
    Notification = plus.android.importClass("android.app.Notification");  
    mNotification = new Notification.Builder(main);      
  }  

  mNotification.setContentTitle(title)       // 设置标题  
  mNotification.setContentText(content);       // 设置内容  
  // mNotification.setSubText('');        // 子内容暂时去掉  
  mNotification.setAutoCancel(true);       // 设置点击消失  
  mNotification.setShowWhen(true);       // 显示通知时间,貌似不加这句也能显示  
  mNotification.setTicker("PadInfo");       // 弹出通知  
  mNotification.setSmallIcon(17301620);       // 设置当前app图标  
  // mNotification.setDefaults(Notification.DEFAULT_VIBRATE);  // 声音、闪灯、震动效果,可叠加,此语句无效  
  mNotification.setPriority(Notification.PRIORITY_DEFAULT);   // 通知优先级    
  mNotification.flags = Notification.FLAG_ONLY_ALERT_ONCE;     // 发起通知时震动    
  mNotification.setContentIntent(pendingIntent);    
  var mNb = mNotification.build();  

  // 判断当前系统版本在8.0及以上    
  if (firstVersionNumber >= 8){  
    nm.notify("s" + NotifyID, NotifyID, mNb);    
  } else {  
    nm.notify(NotifyID, mNb);  
  }  
  // void plus.device.beep(2);// bee bee叫  
  plus.device.vibrate(300); // 震动  

  console.log('通知结束');  
  return true;  
  // #endif  
}  

调用方法

android_notify('test', {  
  params1: 'params1',  
  params2: 'params2',  
  params3: 'params3',  
  params4: 'params4'  
});

接收

点击通知接收通知数据

/**  
  * android原生通知接收  
  */  
android_receive() {  
  // #ifdef APP-PLUS  
  if (plus.os.name != 'Android') {  
    return false;  
  }  
  // android原生通知栏接收器(程序退出后无效)  
  var main = plus.android.runtimeMainActivity();  
  var intent = main.getIntent();  
  var message = intent && intent.getExtra != undefined ? intent.getExtra("receive") : null;  
  console.log(message);  
  message = message ? JSON.parse(message) : '';  
  if (message) {  
    // 删除当前通知  
    // var Context = plus.android.importClass("android.content.Context");  
    // var nm = main.getSystemService(Context.NOTIFICATION_SERVICE);  
    // console.log(message.notify_id);  
    // nm.cancel('s' + message.notify_id, message.notify_id); // 安卓版本大于等于8的  
    // nm.cancel(message.notify_id); // 安卓版本小于8的  
    // nm.cancelAll();  

    // 把消息数据置空,以免再次打开APP时重复执行此处  
    intent.putExtra("receive", '');  

    var params = message.data;  
    if (params1 == 'xxx') {  
      // TODO do something.  
    } else if (params1 == 'yyy') {  
      // TODO do something.  
    }  
  }  
  // #endif  
}

调用方法

// App.Vue  
onShow: function() {  
  ...  

  // #ifdef APP-PLUS  
  android_receive();  
  // #endif  

  ...  
},

注意事项

  1. 已知问题:第一次通知会有通知延迟现象,大概2-3秒后才会收到通知,之后就不会了(官方的推送没有此问题);
  2. 程序被关闭后点击通知消息无法再接收到通知的数据(暂时没有好的解决方案,如果大家有好的方法,欢迎回复分享);

希望以上内容能帮助大家。


补充

2020年4月3日补充:多行显示通知消息

// 创建大文本样式  
var bigTextStyle = plus.android.importClass("android.support.v4.app.NotificationCompat$BigTextStyle");  
var style = new bigTextStyle();  
style.setBigContentTitle(title);  
// style.setSummaryText("备注一行");  
style.bigText(content); // 这里可以设置超长的文本  
mNotification.setStyle(style); // 设置大文本样式

以上代码放到 var mNb = mNotification.build(); 之前即可。


1 回复

在uni-app中集成原生Android推送消息(内推)并监听点击通知的数据,通常需要借助原生插件或者直接编写原生代码来实现。以下是一个基本的实现思路和相关代码案例。

步骤1:配置原生插件

首先,你需要一个支持Android推送消息的原生插件。假设你使用的是一个名为uni-push的插件,你可以在manifest.json中配置这个插件。

{
  "plugins": {
    "uni-push": {
      "version": "x.x.x",  // 插件版本号
      "provider": "your-provider-name"  // 插件提供者
    }
  }
}

步骤2:在Android原生代码中实现推送

在你的Android原生项目中(通常是在platforms/android目录下),配置推送服务。这里以Firebase Cloud Messaging (FCM)为例:

  1. 添加依赖:在build.gradle文件中添加FCM依赖。
dependencies {
    implementation 'com.google.firebase:firebase-messaging:20.2.4'
}
  1. 配置Firebase:在AndroidManifest.xml中添加必要的权限和服务配置。
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<application>
    <service
        android:name=".MyFirebaseMessagingService"
        android:exported="true">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
    </service>
</application>
  1. 创建推送服务:创建一个类MyFirebaseMessagingService来处理推送消息。
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;

public class MyFirebaseMessagingService extends FirebaseMessagingService {
    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        // 处理推送消息
        String from = remoteMessage.getFrom();
        // 你可以在这里处理数据消息并发送本地通知
    }
}

步骤3:监听通知点击事件

MyFirebaseMessagingService中处理推送消息时,可以发送带有额外数据的本地通知。在点击通知时,通过启动一个带有特定Intent的Activity来监听数据。

// 发送本地通知时,设置PendingIntent
Intent intent = new Intent(this, MainActivity.class);
intent.putExtra("notification_data", "your_data");
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

Notification notification = new Notification.Builder(this)
    .setContentTitle("Title")
    .setContentText("Message")
    .setSmallIcon(R.drawable.ic_notification)
    .setContentIntent(pendingIntent)
    .build();

NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(1, notification);

MainActivityonCreate方法中获取通知数据:

Intent intent = getIntent();
if (intent != null && intent.hasExtra("notification_data")) {
    String data = intent.getStringExtra("notification_data");
    // 处理数据
}

通过上述步骤,你可以在uni-app中实现原生Android推送消息并监听点击通知的数据。

回到顶部