react-native-nitro-ali-push 0.0.0-stage → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +240 -2
  3. package/android/CMakeLists.txt +31 -0
  4. package/android/build.gradle +139 -0
  5. package/android/src/main/AndroidManifest.xml +30 -0
  6. package/android/src/main/java/com/margelo/nitro/alipush/AliPushMessageReceiver.kt +156 -0
  7. package/android/src/main/java/com/margelo/nitro/alipush/HybridAliPushPlugin.kt +303 -0
  8. package/android/src/main/java/com/margelo/nitro/alipush/ThirdPartMessageActivity.kt +26 -0
  9. package/ios/HybridAliPushPlugin.swift +519 -0
  10. package/lib/index.d.ts +195 -0
  11. package/lib/index.js +269 -0
  12. package/lib/specs/AliPushPlugin.nitro.d.ts +88 -0
  13. package/lib/specs/AliPushPlugin.nitro.js +2 -0
  14. package/lib/types.d.ts +111 -0
  15. package/lib/types.js +11 -0
  16. package/nitrogen/generated/.gitattributes +1 -0
  17. package/nitrogen/generated/android/NitroAliPush+autolinking.cmake +84 -0
  18. package/nitrogen/generated/android/NitroAliPush+autolinking.gradle +27 -0
  19. package/nitrogen/generated/android/NitroAliPushOnLoad.cpp +58 -0
  20. package/nitrogen/generated/android/NitroAliPushOnLoad.hpp +34 -0
  21. package/nitrogen/generated/android/c++/JAliPushAppState.hpp +61 -0
  22. package/nitrogen/generated/android/c++/JAliPushMessage.hpp +98 -0
  23. package/nitrogen/generated/android/c++/JAliPushMessageType.hpp +58 -0
  24. package/nitrogen/generated/android/c++/JFunc_void.hpp +75 -0
  25. package/nitrogen/generated/android/c++/JFunc_void_AliPushMessage.hpp +87 -0
  26. package/nitrogen/generated/android/c++/JHybridAliPushPluginSpec.cpp +338 -0
  27. package/nitrogen/generated/android/c++/JHybridAliPushPluginSpec.hpp +78 -0
  28. package/nitrogen/generated/android/c++/JVariant_Double_String.cpp +26 -0
  29. package/nitrogen/generated/android/c++/JVariant_Double_String.hpp +68 -0
  30. package/nitrogen/generated/android/c++/JVariant_NullType_AliPushMessage.cpp +26 -0
  31. package/nitrogen/generated/android/c++/JVariant_NullType_AliPushMessage.hpp +80 -0
  32. package/nitrogen/generated/android/c++/JVariant_NullType_String.cpp +26 -0
  33. package/nitrogen/generated/android/c++/JVariant_NullType_String.hpp +70 -0
  34. package/nitrogen/generated/android/kotlin/com/margelo/nitro/alipush/AliPushAppState.kt +24 -0
  35. package/nitrogen/generated/android/kotlin/com/margelo/nitro/alipush/AliPushMessage.kt +91 -0
  36. package/nitrogen/generated/android/kotlin/com/margelo/nitro/alipush/AliPushMessageType.kt +23 -0
  37. package/nitrogen/generated/android/kotlin/com/margelo/nitro/alipush/Func_void.kt +78 -0
  38. package/nitrogen/generated/android/kotlin/com/margelo/nitro/alipush/Func_void_AliPushMessage.kt +78 -0
  39. package/nitrogen/generated/android/kotlin/com/margelo/nitro/alipush/HybridAliPushPluginSpec.kt +123 -0
  40. package/nitrogen/generated/android/kotlin/com/margelo/nitro/alipush/NitroAliPushOnLoad.kt +35 -0
  41. package/nitrogen/generated/android/kotlin/com/margelo/nitro/alipush/Variant_Double_String.kt +62 -0
  42. package/nitrogen/generated/android/kotlin/com/margelo/nitro/alipush/Variant_NullType_AliPushMessage.kt +62 -0
  43. package/nitrogen/generated/android/kotlin/com/margelo/nitro/alipush/Variant_NullType_String.kt +62 -0
  44. package/nitrogen/generated/ios/NitroAliPush+autolinking.rb +62 -0
  45. package/nitrogen/generated/ios/NitroAliPush-Swift-Cxx-Bridge.cpp +89 -0
  46. package/nitrogen/generated/ios/NitroAliPush-Swift-Cxx-Bridge.hpp +531 -0
  47. package/nitrogen/generated/ios/NitroAliPush-Swift-Cxx-Umbrella.hpp +60 -0
  48. package/nitrogen/generated/ios/NitroAliPushAutolinking.mm +33 -0
  49. package/nitrogen/generated/ios/NitroAliPushAutolinking.swift +26 -0
  50. package/nitrogen/generated/ios/c++/HybridAliPushPluginSpecSwift.cpp +11 -0
  51. package/nitrogen/generated/ios/c++/HybridAliPushPluginSpecSwift.hpp +217 -0
  52. package/nitrogen/generated/ios/swift/AliPushAppState.swift +44 -0
  53. package/nitrogen/generated/ios/swift/AliPushMessage.swift +191 -0
  54. package/nitrogen/generated/ios/swift/AliPushMessageType.swift +40 -0
  55. package/nitrogen/generated/ios/swift/Func_void.swift +46 -0
  56. package/nitrogen/generated/ios/swift/Func_void_AliPushMessage.swift +46 -0
  57. package/nitrogen/generated/ios/swift/Func_void_bool.swift +46 -0
  58. package/nitrogen/generated/ios/swift/Func_void_double.swift +46 -0
  59. package/nitrogen/generated/ios/swift/Func_void_std__exception_ptr.swift +46 -0
  60. package/nitrogen/generated/ios/swift/Func_void_std__string.swift +46 -0
  61. package/nitrogen/generated/ios/swift/Func_void_std__variant_nitro__NullType__AliPushMessage_.swift +58 -0
  62. package/nitrogen/generated/ios/swift/HybridAliPushPluginSpec.swift +70 -0
  63. package/nitrogen/generated/ios/swift/HybridAliPushPluginSpec_cxx.swift +476 -0
  64. package/nitrogen/generated/ios/swift/Variant_Double_String.swift +30 -0
  65. package/nitrogen/generated/ios/swift/Variant_NullType_AliPushMessage.swift +30 -0
  66. package/nitrogen/generated/ios/swift/Variant_NullType_String.swift +30 -0
  67. package/nitrogen/generated/shared/c++/AliPushAppState.hpp +80 -0
  68. package/nitrogen/generated/shared/c++/AliPushMessage.hpp +123 -0
  69. package/nitrogen/generated/shared/c++/AliPushMessageType.hpp +76 -0
  70. package/nitrogen/generated/shared/c++/HybridAliPushPluginSpec.cpp +36 -0
  71. package/nitrogen/generated/shared/c++/HybridAliPushPluginSpec.hpp +85 -0
  72. package/package.json +61 -4
  73. package/react-native-nitro-ali-push.podspec +41 -0
  74. package/src/index.ts +284 -0
  75. package/src/specs/AliPushPlugin.nitro.ts +104 -0
  76. package/src/types.ts +117 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 hengkx
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,241 @@
1
- # Temporary Holding Version
1
+ # react-native-nitro-ali-push
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ 阿里云移动推送(Alibaba Cloud Push)的 React Native 封装,基于 **Nitro Modules** 实现:
4
+
5
+ - iOS 原生端:**Swift**(`HybridAliPushPlugin` 实现 Nitro 生成的 `HybridAliPushPluginSpec`)
6
+ - Android 原生端:**Kotlin**(`HybridAliPushPlugin` 继承 Nitro 生成的 `HybridAliPushPluginSpec`)
7
+ - 原生桥接层由 `nitrogen` 代码生成器生成,无需手写 C++ / JNI / Objective-C
8
+ - 推送事件通过 Nitro 回调(`addListener` 返回退订闭包)直接派发,不再依赖 `NativeEventEmitter`
9
+
10
+ > 旧版(基于 TurboModule + 经典 bridge interop)位于 `react-native-ali-push`,本库为其 Nitro 重构版。
11
+
12
+ ---
13
+
14
+ ## 要求
15
+
16
+ | 依赖 | 版本 |
17
+ | --- | --- |
18
+ | react-native | >= 0.76(新架构) |
19
+ | react | * |
20
+ | react-native-nitro-modules | >= 0.37.0 |
21
+ | Android | `minSdk 21`、`compileSdk 34` |
22
+ | iOS | `13.0+`、Xcode 14+ |
23
+
24
+ ---
25
+
26
+ ## 安装
27
+
28
+ ```bash
29
+ npm install react-native-nitro-ali-push
30
+ # 或
31
+ yarn add react-native-nitro-ali-push
32
+ ```
33
+
34
+ iOS 需要执行:
35
+
36
+ ```bash
37
+ cd ios && pod install
38
+ ```
39
+
40
+ ---
41
+
42
+ ## iOS 集成
43
+
44
+ ### 1. 引入阿里云推送 SDK(`CloudPushSDK`)
45
+
46
+ **方式一:CocoaPods(默认,推荐)**
47
+
48
+ 阿里云推送的 pod 不在 CocoaPods trunk,而在官方自己的 spec 仓库,所以要先在 `ios/Podfile` **顶部**声明 source:
49
+
50
+ ```ruby
51
+ source 'https://github.com/aliyun/aliyun-specs.git'
52
+ source 'https://cdn.cocoapods.org/'
53
+ ```
54
+
55
+ 若本机还没添加过该仓库,先执行一次:
56
+
57
+ ```bash
58
+ pod repo add AliyunRepo https://github.com/aliyun/aliyun-specs.git
59
+ ```
60
+
61
+ 本库 podspec 默认已声明 `s.dependency "AlicloudPush", "~> 3"`,因此无需再做其它配置,直接 `pod install` 即可。
62
+
63
+ **方式二:手动集成**
64
+
65
+ 从 [阿里云移动推送控制台](https://push.console.aliyun.com/) 下载 iOS SDK,把 `CloudPushSDK.framework`(3.x 为 `CloudPushSDK.xcframework`)放到本库 `ios/` 目录下。
66
+ podspec 检测到该文件后会自动改用 `vendored_frameworks`,不再依赖 `AlicloudPush`,无需修改 podspec。
67
+
68
+ > 若 `pod install` 报 `Unable to find a specification for 'AlicloudPush'`,说明 Podfile 里缺少上面的阿里云 source。
69
+
70
+ ### 2. AppDelegate 中初始化
71
+
72
+ iOS 端的推送初始化必须在原生层完成(不能在 JS 中 `initPush`):
73
+
74
+ ```swift
75
+ import UIKit
76
+ import UserNotifications
77
+ // 本库模块名由 podspec 名 react-native-nitro-ali-push 推导为 react_native_nitro_ali_push。
78
+ // HybridAliPushPlugin 是 public,跨模块使用需 import 本库模块(不在 NitroAliPush)。
79
+ import react_native_nitro_ali_push
80
+
81
+ @main
82
+ class AppDelegate: UIResponder, UIApplicationDelegate {
83
+
84
+ func application(_ application: UIApplication,
85
+ didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
86
+ // ... 其他初始化(RCTBridge 等)...
87
+
88
+ // 初始化阿里云推送
89
+ HybridAliPushPlugin.shared().setParams(
90
+ "<appKey>",
91
+ appSecret: "<appSecret>",
92
+ lauchOptions: launchOptions as? [AnyHashable: Any],
93
+ createNotificationCategoryHandler: {}
94
+ )
95
+
96
+ return true
97
+ }
98
+
99
+ // 注册 deviceToken
100
+ func application(_ application: UIApplication,
101
+ didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
102
+ HybridAliPushPlugin.shared().application(application,
103
+ didRegisterForRemoteNotificationsWithDeviceToken: deviceToken)
104
+ }
105
+
106
+ func application(_ application: UIApplication,
107
+ didFailToRegisterForRemoteNotificationsWithError error: Error) {
108
+ HybridAliPushPlugin.shared().application(application,
109
+ didFailToRegisterForRemoteNotificationsWithError: error)
110
+ }
111
+
112
+ // 收到远程通知
113
+ func application(_ application: UIApplication,
114
+ didReceiveRemoteNotification userInfo: [AnyHashable: Any],
115
+ fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
116
+ HybridAliPushPlugin.shared().application(application,
117
+ didReceiveRemoteNotification: userInfo,
118
+ fetchCompletionHandler: completionHandler)
119
+ }
120
+ }
121
+ ```
122
+
123
+ > 若 CocoaPods 编译时提示找不到 `React` / `CloudPushSDK` 模块,请在 Podfile 中开启 `use_frameworks!` 或 `use_modular_headers!`。
124
+
125
+ ---
126
+
127
+ ## Android 集成
128
+
129
+ ### 1. `AndroidManifest.xml` 配置 AppKey / AppSecret
130
+
131
+ 在 `Application` 节点下(或 `MainApplication`)添加 `meta-data`:
132
+
133
+ ```xml
134
+ <application ...>
135
+ <meta-data android:name="com.alibaba.app.appkey" android:value="<appKey>" />
136
+ <meta-data android:name="com.alibaba.app.appsecret" android:value="<appSecret>" />
137
+ </application>
138
+ ```
139
+
140
+ ### 2. 初始化
141
+
142
+ Android 端在 JS 中调用 `initPush` 即可:
143
+
144
+ ```ts
145
+ import AliPush from 'react-native-nitro-ali-push';
146
+
147
+ await AliPush.initPush('<appKey>', '<appSecret>');
148
+ ```
149
+
150
+ ---
151
+
152
+ ## 用法
153
+
154
+ ### 订阅推送消息
155
+
156
+ ```ts
157
+ import AliPush from 'react-native-nitro-ali-push';
158
+
159
+ const unsubscribe = AliPush.addEventListener('aliyunPushReceived', (message) => {
160
+ console.log(message.title, message.body, message.extras, message.type);
161
+ });
162
+
163
+ // ... 不再需要时
164
+ unsubscribe();
165
+ ```
166
+
167
+ ### 账号 / 标签 / 别名
168
+
169
+ ```ts
170
+ await AliPush.bindAccount('user_001');
171
+ await AliPush.unbindAccount();
172
+
173
+ await AliPush.bindTag(1, ['news', 'sports'], null); // target: 1 设备 / 2 账号 / 3 别名
174
+ await AliPush.unbindTag(1, ['news'], null);
175
+
176
+ await AliPush.addAlias('alias_001');
177
+ await AliPush.removeAlias('alias_001');
178
+
179
+ const tags = await AliPush.listTags(1);
180
+ const aliases = await AliPush.listAliases();
181
+ ```
182
+
183
+ ### 设备号与角标
184
+
185
+ ```ts
186
+ const deviceId = await AliPush.getDeviceId();
187
+
188
+ await AliPush.setApplicationIconBadgeNumber(0);
189
+ const badge = await AliPush.getApplicationIconBadgeNumber();
190
+ ```
191
+
192
+ ---
193
+
194
+ ## API 参考
195
+
196
+ 所有方法均返回 `Promise`(除事件订阅)。详见源码 `src/index.ts` 的 JSDoc。
197
+
198
+ | 方法 | 说明 | 平台差异 |
199
+ | --- | --- | --- |
200
+ | `initPush(appKey, appSecret)` | 初始化推送 | Android 必需;iOS 为无操作(在 AppDelegate 初始化) |
201
+ | `getDeviceId()` | 获取设备 `deviceId` | — |
202
+ | `bindAccount(account)` | 绑定账号 | — |
203
+ | `unbindAccount()` | 解绑账号 | — |
204
+ | `bindTag(target, tags, alias)` | 绑定标签 | `target`: 1 设备 / 2 账号 / 3 别名 |
205
+ | `unbindTag(target, tags, alias)` | 解绑标签 | 同上 |
206
+ | `listTags(target)` | 列出标签 | 返回服务端响应字符串 |
207
+ | `addAlias(alias)` / `removeAlias(alias)` | 添加 / 移除别名 | — |
208
+ | `listAliases()` | 列出别名 | 返回服务端响应字符串 |
209
+ | `setApplicationIconBadgeNumber(badge)` | 设置角标 | — |
210
+ | `getApplicationIconBadgeNumber()` | 获取角标 | — |
211
+ | `getInitialMessage()` | 获取冷启动首条消息 | 无则 `null` |
212
+ | `getAuthorizationStatus()` | 获取通知授权状态 | Android 返回系统通知权限实际状态 |
213
+ | `syncBadgeNum(badge)` | 同步角标到服务端 | 仅 iOS 有效 |
214
+ | `addEventListener(event, listener)` | 订阅 `aliyunPushReceived` | 返回退订函数 |
215
+ | `removeEventListener(unsubscribe)` | 取消订阅 | — |
216
+
217
+ 事件载荷类型见 `src/types.ts` 的 `AliPushMessage`。
218
+
219
+ ---
220
+
221
+ ## 开发 / 重新生成原生代码
222
+
223
+ 修改 `src/specs/*.nitro.ts` 后,运行代码生成器重新产出原生桥接层:
224
+
225
+ ```bash
226
+ npm run codegen # 等价于 npx nitrogen
227
+ ```
228
+
229
+ 类型检查:
230
+
231
+ ```bash
232
+ npm run typecheck # tsc --noEmit
233
+ ```
234
+
235
+ 本库源码(含类型与 JSDoc)位于 `src/`,原生端位于 `android/` 与 `ios/`,生成的桥接代码位于 `nitrogen/generated/`(随包发布,消费者无需自行运行 codegen)。Metro 会直接使用 `src/index.ts`(`package.json` 的 `source` / `react-native` 字段)。
236
+
237
+ ## License
238
+
239
+ [MIT](./LICENSE) © hengkx &lt;ycxzhkx@gmail.com&gt;
240
+
241
+ 仓库与问题反馈:<https://github.com/hengkx/react-native-nitro-ali-push>
@@ -0,0 +1,31 @@
1
+ project(NitroAliPush)
2
+ cmake_minimum_required(VERSION 3.9.0)
3
+
4
+ set (PACKAGE_NAME NitroAliPush)
5
+ set (CMAKE_VERBOSE_MAKEFILE ON)
6
+ set (CMAKE_CXX_STANDARD 20)
7
+
8
+ # 定义 C++ 库(具体的源文件由 Nitro 代码生成器自动加入)。
9
+ add_library(${PACKAGE_NAME} SHARED)
10
+
11
+ set(NITRO_SANITIZER "" CACHE STRING "Native sanitizer")
12
+ if(NITRO_SANITIZER STREQUAL "address")
13
+ target_compile_options(${PACKAGE_NAME} PUBLIC -fsanitize=address -fno-omit-frame-pointer)
14
+ set_target_properties(${PACKAGE_NAME} PROPERTIES LINK_FLAGS "-fsanitize=address")
15
+ elseif(NOT NITRO_SANITIZER STREQUAL "")
16
+ message(FATAL_ERROR "Unsupported NITRO_SANITIZER: ${NITRO_SANITIZER}")
17
+ endif()
18
+
19
+ # 引入 Nitro 生成的自动链接脚本与所有生成的 C++ 源文件。
20
+ include(${CMAKE_SOURCE_DIR}/../nitrogen/generated/android/NitroAliPush+autolinking.cmake)
21
+
22
+ # 本地头文件包含目录。
23
+ include_directories("src/main/cpp")
24
+
25
+ # 日志库与 Android 核心库。
26
+ find_library(LOG_LIB log)
27
+ target_link_libraries(
28
+ ${PACKAGE_NAME}
29
+ ${LOG_LIB}
30
+ android # <-- Android core
31
+ )
@@ -0,0 +1,139 @@
1
+ buildscript {
2
+ // buildscript 块会先于脚本其余部分求值,因此这里不能复用下面定义的 getKotlinVersion()
3
+ def kotlin_version = rootProject.ext.has('kotlinVersion')
4
+ ? rootProject.ext.get('kotlinVersion')
5
+ : '1.9.24'
6
+
7
+ repositories {
8
+ google()
9
+ mavenCentral()
10
+ }
11
+
12
+ dependencies {
13
+ classpath 'com.android.tools.build:gradle:7.3.1'
14
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
15
+ }
16
+ }
17
+
18
+ def getKotlinVersion() {
19
+ return rootProject.ext.has('kotlinVersion')
20
+ ? rootProject.ext.get('kotlinVersion')
21
+ : '1.9.24'
22
+ }
23
+
24
+ def reactNativeArchitectures() {
25
+ def value = rootProject.getProperties().get("reactNativeArchitectures")
26
+ return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
27
+ }
28
+
29
+ apply plugin: "com.android.library"
30
+ apply plugin: "kotlin-android"
31
+ apply from: '../nitrogen/generated/android/NitroAliPush+autolinking.gradle'
32
+
33
+ android {
34
+ namespace "com.margelo.nitro.alipush"
35
+ compileSdkVersion 34
36
+
37
+ defaultConfig {
38
+ minSdkVersion 21
39
+ targetSdkVersion 34
40
+ buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", "true"
41
+
42
+ externalNativeBuild {
43
+ cmake {
44
+ cppFlags "-frtti -fexceptions -Wall -Wextra -fstack-protector-all"
45
+ arguments "-DANDROID_STL=c++_shared"
46
+ abiFilters (*reactNativeArchitectures())
47
+ }
48
+ }
49
+ }
50
+
51
+ compileOptions {
52
+ sourceCompatibility JavaVersion.VERSION_17
53
+ targetCompatibility JavaVersion.VERSION_17
54
+ }
55
+
56
+ kotlinOptions {
57
+ jvmTarget = "17"
58
+ }
59
+
60
+ externalNativeBuild {
61
+ cmake {
62
+ path "CMakeLists.txt"
63
+ }
64
+ }
65
+
66
+ buildFeatures {
67
+ buildConfig true
68
+ prefab true
69
+ }
70
+
71
+ sourceSets {
72
+ main {
73
+ java.srcDirs += "src/main/java"
74
+ }
75
+ }
76
+
77
+ packagingOptions {
78
+ excludes = [
79
+ "META-INF",
80
+ "META-INF/**",
81
+ "**/libc++_shared.so",
82
+ "**/libfbjni.so",
83
+ "**/libjsi.so",
84
+ "**/libfolly_json.so",
85
+ "**/libfolly_runtime.so",
86
+ "**/libglog.so",
87
+ "**/libhermes.so",
88
+ "**/libhermes-executor-debug.so",
89
+ "**/libhermes_executor.so",
90
+ "**/libreactnative.so",
91
+ "**/libreactnativejni.so",
92
+ "**/libturbomodulejsijni.so",
93
+ "**/libreact_nativemodule_core.so",
94
+ "**/libjscexecutor.so"
95
+ ]
96
+ }
97
+
98
+ buildTypes {
99
+ release {
100
+ minifyEnabled false
101
+ }
102
+ }
103
+ }
104
+
105
+ repositories {
106
+ maven { url "https://maven.aliyun.com/repository/public" }
107
+ maven { url "https://maven.aliyun.com/repository/google" }
108
+ google()
109
+ mavenCentral()
110
+ maven { url 'https://developer.huawei.com/repo/' }
111
+ maven { url 'https://developer.hihonor.com/repo' }
112
+ }
113
+
114
+ dependencies {
115
+ // 新架构下使用 react-android(内含 Nitro / TurboModule 基础设施)。
116
+ implementation "com.facebook.react:react-android:+"
117
+
118
+ implementation "org.jetbrains.kotlin:kotlin-stdlib:${getKotlinVersion()}"
119
+
120
+ // 阿里云移动推送 SDK(含 CloudPush、自建通道与厂商通道依赖)。
121
+ api("com.aliyun.ams:alicloud-android-push:3.10.1") {
122
+ // 若宿主工程已引入以下依赖,可取消对应 exclude 注释避免重复。
123
+ // exclude(module: 'alicloud-android-utdid')
124
+ // exclude(module: 'alicloud-android-beacon')
125
+ }
126
+ api 'com.aliyun.ams:alicloud-android-third-push:3.10.1'
127
+ //华为依赖
128
+ api 'com.aliyun.ams:alicloud-android-third-push-huawei:3.10.1'
129
+ //小米依赖
130
+ api 'com.aliyun.ams:alicloud-android-third-push-xiaomi:3.10.1'
131
+ //OPPO依赖
132
+ api 'com.aliyun.ams:alicloud-android-third-push-oppo:3.10.1'
133
+ //vivo依赖
134
+ api 'com.aliyun.ams:alicloud-android-third-push-vivo:3.10.1'
135
+ //魅族依赖
136
+ api 'com.aliyun.ams:alicloud-android-third-push-meizu:3.10.1'
137
+ //荣耀
138
+ api 'com.aliyun.ams:alicloud-android-third-push-honor:3.10.1'
139
+ }
@@ -0,0 +1,30 @@
1
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android">
2
+
3
+ <!-- 阿里云推送需要网络与后台运行权限 -->
4
+ <uses-permission android:name="android.permission.INTERNET" />
5
+ <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
6
+ <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
7
+ <uses-permission android:name="android.permission.WAKE_LOCK" />
8
+ <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
9
+
10
+ <application>
11
+ <!-- 阿里云推送广播接收器(务必 exported=false) -->
12
+ <receiver
13
+ android:name="com.margelo.nitro.alipush.AliPushMessageReceiver"
14
+ android:exported="false">
15
+ <intent-filter>
16
+ <action android:name="com.alibaba.push2.action.NOTIFICATION_OPENED" />
17
+ </intent-filter>
18
+ </receiver>
19
+
20
+ <!-- 第三方通道通知点击中转 -->
21
+ <activity
22
+ android:name="com.margelo.nitro.alipush.ThirdPartMessageActivity"
23
+ android:exported="true"
24
+ android:launchMode="singleTask">
25
+ <intent-filter>
26
+ <action android:name="android.intent.action.VIEW" />
27
+ </intent-filter>
28
+ </activity>
29
+ </application>
30
+ </manifest>
@@ -0,0 +1,156 @@
1
+ package com.margelo.nitro.alipush
2
+
3
+ import android.content.Context
4
+ import android.os.Bundle
5
+ import android.util.Log
6
+ import com.alibaba.sdk.android.push.MessageReceiver
7
+ import com.alibaba.sdk.android.push.notification.CPushMessage
8
+ import com.margelo.nitro.core.AnyMap
9
+
10
+ /**
11
+ * 阿里云推送广播接收器。
12
+ *
13
+ * 在 `AndroidManifest.xml` 中静态注册(见同目录 `AndroidManifest.xml`)。收到通知 /
14
+ * 消息 / 通知打开 / 通知删除等回调时,把数据组装成 [AliPushMessage] 并通过
15
+ * [HybridAliPushPlugin.dispatch] 发往 JS 的 `aliyunPushReceived` 事件;同时把「App 未
16
+ * 运行被通知唤起」场景下的首条消息缓存到 [HybridAliPushPlugin](由 `getInitialMessage`
17
+ * 读取后清空)。
18
+ */
19
+ class AliPushMessageReceiver : MessageReceiver() {
20
+
21
+ override fun onNotification(
22
+ context: Context?,
23
+ title: String?,
24
+ summary: String?,
25
+ extraMap: Map<String, String>?,
26
+ ) {
27
+ val message = AliPushMessage(
28
+ title = title,
29
+ subtitle = null,
30
+ body = summary,
31
+ badge = null,
32
+ extras = buildExtras(extraMap),
33
+ type = AliPushMessageType.NOTIFICATION,
34
+ actionIdentifier = null,
35
+ appState = null,
36
+ date = Variant_Double_String.create(System.currentTimeMillis().toDouble()),
37
+ )
38
+ HybridAliPushPlugin.dispatch(message)
39
+ }
40
+
41
+ override fun onMessage(context: Context?, intent: android.content.Intent?) {
42
+ val message = intent?.getSerializableExtra("message") as? CPushMessage
43
+ val extras = AnyMap()
44
+ message?.let {
45
+ extras.setString("appId", it.appId ?: "")
46
+ extras.setString("messageId", it.messageId ?: "")
47
+ }
48
+ intent?.extras?.let { putBundle(extras, it) }
49
+ val payload = AliPushMessage(
50
+ title = message?.title,
51
+ subtitle = null,
52
+ body = message?.content,
53
+ badge = null,
54
+ extras = extras,
55
+ type = AliPushMessageType.MESSAGE,
56
+ actionIdentifier = null,
57
+ appState = null,
58
+ date = Variant_Double_String.create(System.currentTimeMillis().toDouble()),
59
+ )
60
+ HybridAliPushPlugin.dispatch(payload)
61
+ }
62
+
63
+ override fun onNotificationOpened(
64
+ context: Context?,
65
+ title: String?,
66
+ summary: String?,
67
+ extraMap: Map<String, String>?,
68
+ ) {
69
+ val message = AliPushMessage(
70
+ title = title,
71
+ subtitle = null,
72
+ body = summary,
73
+ badge = null,
74
+ extras = buildExtras(extraMap),
75
+ type = AliPushMessageType.NOTIFICATION,
76
+ actionIdentifier = "opened",
77
+ appState = null,
78
+ date = Variant_Double_String.create(System.currentTimeMillis().toDouble()),
79
+ )
80
+ HybridAliPushPlugin.dispatch(message)
81
+ }
82
+
83
+ override fun onNotificationRemoved(context: Context?, messageId: String?) {
84
+ val extras = AnyMap()
85
+ if (messageId != null) extras.setString("messageId", messageId)
86
+ val message = AliPushMessage(
87
+ title = null,
88
+ subtitle = null,
89
+ body = null,
90
+ badge = null,
91
+ extras = extras,
92
+ type = AliPushMessageType.NOTIFICATION,
93
+ actionIdentifier = "removed",
94
+ appState = null,
95
+ date = Variant_Double_String.create(System.currentTimeMillis().toDouble()),
96
+ )
97
+ HybridAliPushPlugin.dispatch(message)
98
+ }
99
+
100
+ override fun onChannelRegistration(context: Context?, errorCode: String?) {
101
+ Log.d("AliPush", "onChannelRegistration: $errorCode")
102
+ }
103
+
104
+ // ---------------------------------------------------------------------------
105
+ // 内部工具
106
+ // ---------------------------------------------------------------------------
107
+
108
+ private fun buildExtras(extraMap: Map<String, String>?): AnyMap? {
109
+ if (extraMap.isNullOrEmpty()) return null
110
+ val map = AnyMap()
111
+ for ((k, v) in extraMap) {
112
+ map.setString(k, v)
113
+ }
114
+ return map
115
+ }
116
+
117
+ private fun putBundle(target: AnyMap, bundle: Bundle) {
118
+ bundle.keySet()?.forEach { key ->
119
+ when (val value = bundle.get(key)) {
120
+ is String -> target.setString(key, value)
121
+ is Double -> target.setDouble(key, value)
122
+ is Int -> target.setDouble(key, value.toDouble())
123
+ is Boolean -> target.setBoolean(key, value)
124
+ is Long -> target.setInt64(key, value)
125
+ }
126
+ }
127
+ }
128
+
129
+ companion object {
130
+ /**
131
+ * 由中转 Activity 传入点击通知的 `Bundle`,组装并派发到 JS。
132
+ * 第三方通道的通知点击数据通常放在 `Intent` 的 extras 中。
133
+ */
134
+ fun dispatchFromIntent(extras: Bundle?) {
135
+ if (extras == null) return
136
+ val title = extras.getString("title")
137
+ val body = extras.getString("body") ?: extras.getString("summary")
138
+ val e = AnyMap()
139
+ extras.keySet()?.forEach { key ->
140
+ (extras.get(key) as? String)?.let { e.setString(key, it) }
141
+ }
142
+ val message = AliPushMessage(
143
+ title = title,
144
+ subtitle = null,
145
+ body = body,
146
+ badge = null,
147
+ extras = e,
148
+ type = AliPushMessageType.NOTIFICATION,
149
+ actionIdentifier = "opened",
150
+ appState = null,
151
+ date = Variant_Double_String.create(System.currentTimeMillis().toDouble()),
152
+ )
153
+ HybridAliPushPlugin.dispatch(message)
154
+ }
155
+ }
156
+ }