iOSAndroid native集成阿里移动推送实现

tech2025-11-19  1

iOS移动推送

iOS消息推送的工作机制如下图所示:

 

第一阶段:应用程序把要发送的消息、目的iPhone的标识打包,发给APNS。 

第二阶段:APNS在自身的已注册Push服务的iPhone列表中,查找有相应标识的iPhone,并把消息发送到iPhone。 

第三阶段:iPhone把发来的消息传递给相应的应用程序,并且按照设定弹出Push通知。

在实际的开发中,会使用第三方的移动推送平台运营商,如极光推送、阿里推送,这里我们使用的是阿里推送来做介绍

一、注册推送证书

简单介绍一下iOS移动推送预备工作,首先进入苹果开发者平台使用苹果开发者账号登陆

选择中间的Certificates, Identifiers & Profiles 

 

找到应用对应的Identifiers(Bundle ID)进入Edit your App ID Configuration,勾选Push Notifications, 生成推送证书,以上步骤需要有可用的Apple 开发者账号和已创建的应用ID。配置好后下载证书文件双击安装, 系统会自动打开钥匙串,选中安装的证书文件,右击导出为.p12文件保存好用于上传至第三方推送平台

二、Xcode项目配置

使用Xcode打开项目代码,点击左侧项目导航栏并选中项目,选择Signing & Capabilities

点击下方的+ Capability会弹出视图

分别搜索Push Notification和Remote Notifications,成功添加后如下图所示,Xcode移动推送配置就算完成了

三、使用阿里推送SDK集成

3.1 注册应用并上传p12文件

1、登录EMAS控制台。创建应用并通过审核

2、在控制台首页产品及应用模块,单击选择您的iOS应用,进入当前应用的应用管理页面。

3、单击右上角的应用配置,选择推送配置页签。

4、分别上传配置好的.P12证书、输入证书密码单击保存并验证证书。

5、输入测试设备的device Token,单击测试推送,测试成功后单击确定完成配置。

3.2 下载SDK集成到项目中

登录您的 阿里云 EMAS 控制台 显示如下页面 点击 SDK 下载:

在右侧弹窗 下载您需要集成的SDK:

公共包依赖

libz.tbdlibresolv.tbdCoreTelephony.frameworkSystemConfiguration.frameworklibsqlite3.tbd

SDK目录结构

CloudPushSDK.frameworkAlicloudUtils.frameworkUTDID.frameworkUTMini.framework

引入Framework

Xcode中,直接把下载SDK目录中的framework拖入对应Target下即可,在弹出框勾选Copy items if needed。在 Build Phases -> Link Binary With Libraries中,引入2.1.2列出的公共包;

3.3 Push SDK使用

在项目工程中引入CloudPush

#import <CloudPushSDK/CloudPushSDK.h>

应用的targets -> Build Settings -> Linking -> Other Linker Flags,请加上-ObjC这个属性,否则推送服务无法正常使用;如果之前已经设置了force_load,需要设置-force_load <framework_path>/CloudPushSDK.framework/CloudPushSDK。

注册阿里推送初始化,传入的参数就是在阿里注册应用时得到的appKey和appSecret,注册的应用包名必须和本地项目代码的Bundle ID一致

- (void)initCloudPush { // SDK初始化 [CloudPushSDK asyncInit:@"*****" appSecret:@"*****" callback:^(CloudPushCallbackResult *res) { if (res.success) { NSLog(@"Push SDK init success, deviceId: %@.", [CloudPushSDK getDeviceId]); } else { NSLog(@"Push SDK init failed, error: %@", res.error); } }]; }

向苹果 APNs 注册获取 deviceToken 并上报到阿里云推送服务器;

# pragma mark -- 向APNs注册, 获取deviceToken并上报给SDK - (void)registerAPNS:(UIApplication *)application { float systemVersionNum = [[[UIDevice currentDevice] systemVersion] floatValue]; NSLog(@"\n \n ==== 当前手机系统版本 : %f",systemVersionNum); if (systemVersionNum >= 10.0) { _notificationCenter = [UNUserNotificationCenter currentNotificationCenter]; // 创建 category , 并注册到通知中心 [self createCustomNotificationCategory]; // 遵循协议 _notificationCenter.delegate = self; // 咨询客户是否允许推送通知 , 以及设置推送的类型 [_notificationCenter requestAuthorizationWithOptions:UNAuthorizationOptionAlert | UNAuthorizationOptionBadge | UNAuthorizationOptionSound completionHandler:^(BOOL granted, NSError * _Nullable error) { if (granted) { NSLog(@"\n \n ==== 客户允许通知. "); // 向APNs注册, 获取 deviceToken // 要求在主线程中 dispatch_async(dispatch_get_main_queue(), ^{ [application registerForRemoteNotifications]; }); } else { } }]; } else if (systemVersionNum >= 8.0) { // 适配 iOS_8, iOS_10.0 // iOS 8 Notifications #pragma clang diagnostic push #pragma clang diagnostic ignored"-Wdeprecated-declarations" [application registerUserNotificationSettings: [UIUserNotificationSettings settingsForTypes: (UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]]; [application registerForRemoteNotifications]; #pragma clang diagnostic pop } else { // iOS < 8 Notifications #pragma clang diagnostic push #pragma clang diagnostic ignored"-Wdeprecated-declarations" [[UIApplication sharedApplication] registerForRemoteNotificationTypes: (UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)]; #pragma clang diagnostic pop } } /* * 苹果推送注册成功回调,将苹果返回的deviceToken上传到CloudPush服务器 */ - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { [CloudPushSDK registerDevice:deviceToken withCallback:^(CloudPushCallbackResult *res) { if (res.success) { NSLog(@"Register deviceToken success."); } else { NSLog(@"Register deviceToken failed, error: %@", res.error); } }]; } /* * 苹果推送注册失败回调 */ - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error { NSLog(@"didFailToRegisterForRemoteNotificationsWithError %@", error); }

推送消息到来监听;

/** * 注册推送消息到来监听 */ - (void)registerMessageReceive { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onMessageReceived:) name:@"CCPDidReceiveMessageNotification" object:nil]; } /** * 处理到来推送消息 * * @param notification */ - (void)onMessageReceived:(NSNotification *)notification { CCPSysMessage *message = [notification object]; NSString *title = [[NSString alloc] initWithData:message.title encoding:NSUTF8StringEncoding]; NSString *body = [[NSString alloc] initWithData:message.body encoding:NSUTF8StringEncoding]; NSLog(@"Receive message title: %@, content: %@.", title, body); }

申请推送通知的权限

UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; if (@available(iOS 10, *)) { center = [UNUserNotificationCenter currentNotificationCenter]; [center requestAuthorizationWithOptions:UNAuthorizationOptionAlert | UNAuthorizationOptionBadge | UNAuthorizationOptionSound completionHandler:^(BOOL granted, NSError * _Nullable error) { if (granted) { // granted NSLog(@"User authored notification."); dispatch_async(dispatch_get_main_queue(), ^{ [application registerForRemoteNotifications]; }); } else { // not granted NSLog(@"User denied notification."); } }]; }

绑定用户和推送设备(推送机制推送的目标是设备,如果需求要求推送到用户,需要将设备和用户绑定)

[CloudPushSDK bindAccount:account withCallback:^(CloudPushCallbackResult *res) { NSLog(@"CloudPushSDK--绑定用户成功"); }]; [CloudPushSDK unbindAccount:^(CloudPushCallbackResult *res) { NSLog(@"CloudPushSDK--解除绑定成功"); }];

解决用户在运行时无法显示通知,iOS在前台运行时,收到的通知默认是不会显示通知栏,需要手动处理实现接受远程通知的代理,在接收到通知后转为本地通知并弹出显示

- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler{ //[self showLocalNotification]; completionHandler(UNNotificationPresentationOptionSound | UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionBadge); } - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo { self.remoteNotificationUserInfo = userInfo; if (application.applicationState == UIApplicationStateActive) { [self showLocalNotification]; } } -(void)showLocalNotification { UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; center.delegate = self; UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init]; content.body = self.remoteNotificationUserInfo[@"aps"][@"alert"][@"body"]; content.title = self.remoteNotificationUserInfo[@"aps"][@"alert"][@"title"]; content.userInfo = self.remoteNotificationUserInfo; content.sound = [UNNotificationSound defaultSound]; UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:@"Notif" content:content trigger:nil]; [[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) { }]; }

iOS 原生端的移动推送介绍基本结束,更详细的介绍可以参考阿里官方的推送文档https://help.aliyun.com/document_detail/30072.html

 

Android 原生移动推送-阿里推送

Android可以使用Gradle maven库集成阿里推送SDK,同iOS,需要先在阿里推送管理平台注册应用,填写包名

集成阿里推送SDK

在Project根目录下build.gradle文件中配置maven库URL:

allprojects { repositories { jcenter() maven { url 'http://maven.aliyun.com/nexus/content/repositories/releases/' } } }

在对应的module下的build.gradle文件中添加对应依赖

android { ...... defaultConfig { applicationId "com.xxx.xxx" //包名 ...... ndk { //选择要添加的对应cpu类型的.so库。 abiFilters 'armeabi', 'x86' } ...... } ...... } dependencies { ...... compile 'com.aliyun.ams:alicloud-android-push:3.2.1@aar' compile 'com.aliyun.ams:alicloud-android-utdid:2.5.1-proguard' compile 'com.aliyun.ams:alicloud-android-utils:1.1.6.4' compile 'com.aliyun.ams:alicloud-android-ut:5.4.3' compile 'com.aliyun.ams:alicloud-android-beacon:1.0.4.3' compile 'com.aliyun.ams:alicloud-android-agoo:1.0.0' compile 'com.taobao.android:accs_sdk_taobao:3.3.7.6-emas' compile 'com.taobao.android:networksdk:3.5.5.2-open' compile 'com.taobao.android:tnet4android:3.1.14.7-all' // 或 compile 'com.aliyun.ams:alicloud-android-push:3.2.1' ...... }

注意⚠️,compile在Gradle3.0中被弃用,需要使用implementation替代

集成阿里推送后还需要在其他厂商注册APP才能支持Huawei、XiaoMi等推送,因此还需要修改我们的依赖,增加对其他厂商的推送支持

dependencies { ... implementation 'com.aliyun.ams:alicloud-android-third-push:3.1.0@aar' implementation 'com.aliyun.ams:huawei-push:2.6.3.305' implementation 'com.aliyun.ams:huawei-push-base:2.6.3.305' }

修改AndroidMainfest.xml文件

<meta-data android:name="com.alibaba.app.appkey" android:value="******"/> <!-- 请填写你自己的- appKey --> <meta-data android:name="com.alibaba.app.appsecret" android:value="*******"/> <!-- 请填写你自己的appSecret -->

小米/华为/FCM/OPPO/VIVO/魅族 系统推送支持

配置应用

在 小米开放平台 注册你的App, 得到相应的小米AppID,小米AppKey,小米AppSecert。在控制台应用配置设置你的小米AppSecert。(注意:最新的小米开放平台是分开 push 功能的,需要在 push 功能区 开通/启用 推送功能)

在 华为开发者联盟 注册 App,应用审核通过后,能够得到华为的AppID和AppSecert。在控制台应用配置中设置你的应用 AppID 和 AppSecert。(注意:最新的华为开放平台是分开push功能的,需要在push功能区 开通/启用 推送功能),华为后台添加消息回执回调地址,https://agoo-ack.m.taobao.com/hw/

 

在阿里云移动推送控制台配置辅助通道,具体操作查看官方文档https://help.aliyun.com/document_detail/30067.html

在AndroidMainfest.xml文件中application标签下添加对应厂商的APPSecret等配置,具体操作需要查看对应厂商给出的官方文档例如华为:

<meta-data android:name="com.huawei.hms.client.appid" android:value="appid=你的appid" />

消息接收Receiver配置

创建消息接收Receiver,继承自com.alibaba.sdk.android.push.MessageReceiver,并在对应回调中添加业务处理逻辑,可参考以下代码:

public class MyMessageReceiver extends MessageReceiver { // 消息接收部分的LOG_TAG public static final String REC_TAG = "receiver"; @Override public void onNotification(Context context, String title, String summary, Map<String, String> extraMap) { // TODO 处理推送通知 Log.e("MyMessageReceiver", "Receive notification, title: " + title + ", summary: " + summary + ", extraMap: " + extraMap); } @Override public void onMessage(Context context, CPushMessage cPushMessage) { Log.e("MyMessageReceiver", "onMessage, messageId: " + cPushMessage.getMessageId() + ", title: " + cPushMessage.getTitle() + ", content:" + cPushMessage.getContent()); } @Override public void onNotificationOpened(Context context, String title, String summary, String extraMap) { Log.e("MyMessageReceiver", "onNotificationOpened, title: " + title + ", summary: " + summary + ", extraMap:" + extraMap); } @Override protected void onNotificationClickedWithNoAction(Context context, String title, String summary, String extraMap) { Log.e("MyMessageReceiver", "onNotificationClickedWithNoAction, title: " + title + ", summary: " + summary + ", extraMap:" + extraMap); } @Override protected void onNotificationReceivedInApp(Context context, String title, String summary, Map<String, String> extraMap, int openType, String openActivity, String openUrl) { Log.e("MyMessageReceiver", "onNotificationReceivedInApp, title: " + title + ", summary: " + summary + ", extraMap:" + extraMap + ", openType:" + openType + ", openActivity:" + openActivity + ", openUrl:" + openUrl); } @Override protected void onNotificationRemoved(Context context, String messageId) { Log.e("MyMessageReceiver", "onNotificationRemoved"); } }

将该receiver添加到AndroidManifest.xml中

<!-- 消息接收监听器 (用户可自主扩展) --> <receiver android:name=".MyMessageReceiver" android:exported="false"> <!-- 为保证receiver安全,建议设置不可导出,如需对其他应用开放可通过android:permission进行限制 --> <intent-filter> <action android:name="com.alibaba.push2.action.NOTIFICATION_OPENED" /> </intent-filter> <intent-filter> <action android:name="com.alibaba.push2.action.NOTIFICATION_REMOVED" /> </intent-filter> <intent-filter> <action android:name="com.alibaba.sdk.android.push.RECEIVE" /> </intent-filter> </receiver>

在应用中注册和启动移动推送

首先通过PushServiceFactory获取到CloudPushService,然后调用register()初始化并注册云推送通道,并确保Application上下文中进行初始化工作。

import android.app.Application; import android.content.Context; import android.util.Log; import com.alibaba.sdk.android.push.CloudPushService; import com.alibaba.sdk.android.push.CommonCallback; import com.alibaba.sdk.android.push.noonesdk.PushServiceFactory; public class MainApplication extends Application { private static final String TAG = "Init"; @Override public void onCreate() { super.onCreate(); initCloudChannel(this); } /** * 初始化云推送通道 * @param applicationContext */ private void initCloudChannel(Context applicationContext) { PushServiceFactory.init(applicationContext); CloudPushService pushService = PushServiceFactory.getCloudPushService(); pushService.register(applicationContext, new CommonCallback() { @Override public void onSuccess(String response) { Log.d(TAG, "init cloudchannel success"); } @Override public void onFailed(String errorCode, String errorMessage) { Log.d(TAG, "init cloudchannel failed -- errorcode:" + errorCode + " -- errorMessage:" + errorMessage); } }); } } 移动推送的初始化必须在Application主线程中,不能放到Activity中执行,也不能异步初始化。移动推送在初始化过程中将启动后台进程channel,必须保证应用进程和channel进程都执行到推送初始化代码。如果设备成功注册,将回调callback.onSuccess()方法。但如果注册服务器连接失败,则调用callback.onFailed方法,并且自动进行重新注册,直到onSuccess为止。(重试规则会由网络切换等时间自动触发。)

Android 阿里推送配置官方文档 https://help.aliyun.com/document_detail/51056.html

 

最新回复(0)