capacitor-jpush-core 0.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.

Potentially problematic release.


This version of capacitor-jpush-core might be problematic. Click here for more details.

@@ -0,0 +1,261 @@
1
+ package com.capacitor.jpush.core
2
+
3
+ import android.content.Context
4
+ import android.content.Intent
5
+ import android.os.Build
6
+ import android.util.Log
7
+ import cn.jpush.android.api.JPushInterface
8
+ import cn.jpush.android.data.JPushConfig
9
+ import cn.jpush.android.helper.Logger
10
+ import cn.jpush.android.ups.JPushUPSManager
11
+ import com.capacitor.jpush.core.JPushReceiver.Companion.ACTION_REGISTRATION_COMPLETED
12
+ import com.getcapacitor.JSObject
13
+
14
+
15
+ class JPush(private val context: Context) {
16
+
17
+ private val TAG = "JPush"
18
+ private val sequenceCallbackMap = mutableMapOf<Int, String>()
19
+ private var sequence = 0
20
+ private var hasInit = false
21
+
22
+ /**
23
+ * 初始化极光推送服务
24
+ *
25
+ * @param appKey 应用密钥
26
+ * @param channel 渠道
27
+ * @param production 是否为生产环境
28
+ */
29
+ fun setupJPush(appKey: String, channel: String, production: Boolean) {
30
+ try {
31
+ Logger.d(
32
+ TAG,
33
+ "初始化极光推送,appKey: $appKey, production: $production, channel: $channel"
34
+ )
35
+ if (!hasInit) {
36
+ hasInit = true
37
+ // 设置调试模式
38
+ JPushInterface.setDebugMode(!production)
39
+ // init也要设置key,
40
+ val config = JPushConfig()
41
+ config.setjAppKey(appKey)
42
+ JPushInterface.init(context, config)
43
+ // 开启回调才能收到点击事件,这坑排查了很久...
44
+ JPushInterface.setNotificationCallBackEnable(context, true)
45
+ }
46
+
47
+ // 使用JPushUPSManager.registerToken方法动态设置appKey(文档推荐方式)
48
+ // https://docs.jiguang.cn/jpush/client/Android/android_api#开启推送业务功能-api
49
+ // context: 应用上下文
50
+ // appId: 在极光官网注册应用时生成的 APPKEY
51
+ // appKey: 填 null 即可
52
+ // appSecret: 填空即可
53
+ // callback: 该接口的结果回调,状态码为 0 则说明调用成功,其它值均为失败
54
+ JPushUPSManager.registerToken(
55
+ context,
56
+ appKey,
57
+ null,
58
+ ""
59
+ ) { tokenResult ->
60
+ Log.d(TAG, tokenResult.toString())
61
+ tokenResult?.let {
62
+ // 和iOS端统一, 使用监听传递成功和失败结果。
63
+ if (it.returnCode == 0) {
64
+ val data = JSObject().apply {
65
+ put("registrationID", getRegistrationID())
66
+ }
67
+ sendEventBroadcast(context, ACTION_REGISTRATION_COMPLETED, data)
68
+ } else {
69
+ val data = JSObject().apply {
70
+ put("errorCode", it.returnCode)
71
+ put("errorMessage", "注册失败,错误码: ${it.returnCode}")
72
+ }
73
+ sendEventBroadcast(context, JPushReceiver.ACTION_REGISTRATION_FAILED, data)
74
+ }
75
+ }
76
+ }
77
+ } catch (e: Exception) {
78
+ Log.e(TAG, "初始化极光推送失败: ${e.message}")
79
+ e.printStackTrace()
80
+ // 初始化异常,发送注册失败广播
81
+ val data = JSObject().apply {
82
+ put("errorCode", -1)
83
+ put("errorMessage", e.message ?: "未知错误")
84
+ }
85
+ sendEventBroadcast(context, JPushReceiver.ACTION_REGISTRATION_FAILED, data)
86
+ }
87
+ }
88
+
89
+ /**
90
+ * 发送事件广播
91
+ */
92
+ private fun sendEventBroadcast(context: Context, action: String, data: JSObject) {
93
+ val intent = Intent(action).apply {
94
+ putExtra(JPushReceiver.EXTRA_DATA, data.toString())
95
+ }
96
+ context.sendBroadcast(intent)
97
+ }
98
+
99
+ /**
100
+ * 获取设备的注册ID
101
+ *
102
+ * @return 注册ID,如果未注册则返回空字符串
103
+ */
104
+ fun getRegistrationID(): String {
105
+ try {
106
+ val registrationID = JPushInterface.getRegistrationID(context)
107
+ Log.d(TAG, "获取注册ID: $registrationID")
108
+ return registrationID
109
+ } catch (e: Exception) {
110
+ Log.e(TAG, "获取注册ID失败: ${e.message}")
111
+ return ""
112
+ }
113
+ }
114
+
115
+ /**
116
+ * 设置别名
117
+ *
118
+ * @param alias 别名
119
+ * @param seq 序列号,用户自定义,用来标识操作唯一性
120
+ * @param callbackId 回调ID
121
+ * @return 是否设置成功
122
+ */
123
+ fun setAlias(alias: String, seq: Int?, callbackId: String): Boolean {
124
+ try {
125
+ val sequence = seq ?: 0
126
+ sequenceCallbackMap[sequence] = callbackId
127
+
128
+ Log.d(TAG, "设置别名: $alias, seq: $sequence")
129
+ JPushInterface.setAlias(context, sequence, alias)
130
+ return true
131
+ } catch (e: Exception) {
132
+ Log.e(TAG, "设置别名失败: ${e.message}")
133
+ return false
134
+ }
135
+ }
136
+
137
+ /**
138
+ * 清除别名
139
+ *
140
+ * @param seq 序列号,用户自定义,用来标识操作唯一性
141
+ * @param callbackId 回调ID
142
+ * @return 是否清除成功
143
+ */
144
+ fun deleteAlias(seq: Int?, callbackId: String): Boolean {
145
+ try {
146
+ val sequence = seq ?: 0
147
+ sequenceCallbackMap[sequence] = callbackId
148
+
149
+ Log.d(TAG, "清除别名, seq: $sequence")
150
+ JPushInterface.deleteAlias(context, sequence)
151
+ return true
152
+ } catch (e: Exception) {
153
+ Log.e(TAG, "清除别名失败: ${e.message}")
154
+ return false
155
+ }
156
+ }
157
+
158
+ /**
159
+ * 设置标签(替换所有现有标签)
160
+ *
161
+ * @param tags 标签列表
162
+ * @param seq 序列号,用户自定义,用来标识操作唯一性
163
+ * @param callbackId 回调ID
164
+ * @return 是否设置成功
165
+ */
166
+ fun setTags(tags: List<String>, seq: Int?, callbackId: String): Boolean {
167
+ try {
168
+ val sequence = seq ?: 0
169
+ sequenceCallbackMap[sequence] = callbackId
170
+ val tagSet = tags.toMutableSet()
171
+
172
+ Log.d(TAG, "设置标签: $tags, seq: $sequence")
173
+ JPushInterface.setTags(context, sequence, tagSet)
174
+ return true
175
+ } catch (e: Exception) {
176
+ Log.e(TAG, "设置标签失败: ${e.message}")
177
+ return false
178
+ }
179
+ }
180
+
181
+ /**
182
+ * 添加标签
183
+ *
184
+ * @param tags 标签列表
185
+ * @param seq 序列号,用户自定义,用来标识操作唯一性
186
+ * @param callbackId 回调ID
187
+ * @return 是否添加成功
188
+ */
189
+ fun addTags(tags: List<String>, seq: Int?, callbackId: String): Boolean {
190
+ try {
191
+ val sequence = seq ?: 0
192
+ sequenceCallbackMap[sequence] = callbackId
193
+ val tagSet = tags.toMutableSet()
194
+
195
+ Log.d(TAG, "添加标签: $tags, seq: $sequence")
196
+ JPushInterface.addTags(context, sequence, tagSet)
197
+ return true
198
+ } catch (e: Exception) {
199
+ Log.e(TAG, "添加标签失败: ${e.message}")
200
+ return false
201
+ }
202
+ }
203
+
204
+ /**
205
+ * 删除标签
206
+ *
207
+ * @param tags 标签列表
208
+ * @param seq 序列号,用户自定义,用来标识操作唯一性
209
+ * @param callbackId 回调ID
210
+ * @return 是否删除成功
211
+ */
212
+ fun deleteTags(tags: List<String>, seq: Int?, callbackId: String): Boolean {
213
+ try {
214
+ val sequence = seq ?: 0
215
+ sequenceCallbackMap[sequence] = callbackId
216
+ val tagSet = tags.toMutableSet()
217
+
218
+ Log.d(TAG, "删除标签: $tags, seq: $sequence")
219
+ JPushInterface.deleteTags(context, sequence, tagSet)
220
+ return true
221
+ } catch (e: Exception) {
222
+ Log.e(TAG, "删除标签失败: ${e.message}")
223
+ return false
224
+ }
225
+ }
226
+
227
+ /**
228
+ * 清除所有标签
229
+ *
230
+ * @param seq 序列号,用户自定义,用来标识操作唯一性
231
+ * @param callbackId 回调ID
232
+ * @return 是否清除成功
233
+ */
234
+ fun cleanTags(seq: Int?, callbackId: String): Boolean {
235
+ try {
236
+ val sequence = seq ?: 0
237
+ sequenceCallbackMap[sequence] = callbackId
238
+
239
+ Log.d(TAG, "清除所有标签, seq: $sequence")
240
+ JPushInterface.cleanTags(context, sequence)
241
+ return true
242
+ } catch (e: Exception) {
243
+ Log.e(TAG, "清除所有标签失败: ${e.message}")
244
+ return false
245
+ }
246
+ }
247
+
248
+ /**
249
+ * 设置未读角标数量
250
+ *
251
+ * @param badge 角标数量,0 表示清空角标
252
+ * @return 是否设置成功
253
+ */
254
+ fun setBadge(badge: Int): Boolean {
255
+ // 设置角标数字(目前仅支持华为手机)
256
+ // 如果需要调用这个接口,还需要在 AndroidManifest.xml 里配置华为指定的权限
257
+ JPushInterface.setBadgeNumber(context, badge)
258
+ return true
259
+ }
260
+
261
+ }
@@ -0,0 +1,431 @@
1
+ package com.capacitor.jpush.core
2
+
3
+ import android.content.BroadcastReceiver
4
+ import android.content.Context
5
+ import android.content.Intent
6
+ import android.content.IntentFilter
7
+ import android.os.Build
8
+ import android.util.Log
9
+ import androidx.core.content.ContextCompat
10
+ import com.getcapacitor.JSObject
11
+ import com.getcapacitor.Plugin
12
+ import com.getcapacitor.PluginCall
13
+ import com.getcapacitor.PluginMethod
14
+ import com.getcapacitor.annotation.CapacitorPlugin
15
+ import com.getcapacitor.annotation.Permission
16
+ import com.getcapacitor.annotation.PermissionCallback
17
+
18
+
19
+
20
+
21
+ @CapacitorPlugin(
22
+ name = "JPush",
23
+ permissions = [
24
+ Permission(strings = ["android.permission.POST_NOTIFICATIONS"], alias = JPushPlugin.NOTIFICATIONS_STATUS_KEY)
25
+ ]
26
+ )
27
+ class JPushPlugin : Plugin() {
28
+
29
+ private val TAG = "JPushPlugin"
30
+ private lateinit var jPush: JPush
31
+ private var isInitialized = false
32
+ private var activeClearBadge = false // 是否自动清除角标
33
+
34
+ companion object {
35
+ // 移除private修饰符,让常量在类外部可见
36
+ const val NOTIFICATIONS_STATUS_KEY = "permission"
37
+
38
+ // JPush事件名称常量
39
+ const val NOTIFICATION_RECEIVED = "notificationReceived"
40
+ const val NOTIFICATION_OPENED = "notificationOpened"
41
+ const val CUSTOM_MESSAGE_RECEIVED = "customMessageReceived"
42
+ const val REGISTRATION_COMPLETED = "registrationCompleted"
43
+ const val REGISTRATION_FAILED = "registrationFailed"
44
+ }
45
+
46
+
47
+ // 保存获取注册ID的回调
48
+ private var registrationIdCall: PluginCall? = null
49
+
50
+ // 广播接收器,用于接收JPush事件
51
+ private val broadcastReceiver = object : BroadcastReceiver() {
52
+ override fun onReceive(context: Context, intent: Intent) {
53
+ val action = intent.action
54
+ val dataString = intent.getStringExtra(JPushReceiver.EXTRA_DATA)
55
+
56
+ if (dataString.isNullOrEmpty()) {
57
+ return
58
+ }
59
+
60
+ try {
61
+ val data = JSObject(dataString)
62
+
63
+ when (action) {
64
+ JPushReceiver.ACTION_REGISTRATION_COMPLETED -> {
65
+ // 处理注册完成事件
66
+ Log.d(TAG, "注册完成: $dataString")
67
+ notifyListeners(REGISTRATION_COMPLETED, data)
68
+
69
+ // 如果有等待的注册ID回调,则解析并返回
70
+ registrationIdCall?.let {
71
+ val registrationID = data.getString("registrationID") ?: ""
72
+ val ret = JSObject().apply {
73
+ put("registrationID", registrationID)
74
+ }
75
+ it.resolve(ret)
76
+ registrationIdCall = null
77
+ }
78
+ }
79
+ JPushReceiver.ACTION_REGISTRATION_FAILED -> {
80
+ // 处理注册失败事件
81
+ Log.d(TAG, "注册失败: $dataString")
82
+ notifyListeners(REGISTRATION_FAILED, data)
83
+ }
84
+ JPushReceiver.ACTION_NOTIFICATION_RECEIVED -> {
85
+ // 处理收到通知事件
86
+ Log.d(TAG, "收到通知: $dataString")
87
+ notifyListeners(NOTIFICATION_RECEIVED, data)
88
+ }
89
+ JPushReceiver.ACTION_NOTIFICATION_OPENED -> {
90
+ // 处理点击通知事件
91
+ Log.d(TAG, "点击通知: $dataString")
92
+ notifyListeners(NOTIFICATION_OPENED, data)
93
+ }
94
+ JPushReceiver.ACTION_CUSTOM_MESSAGE_RECEIVED -> {
95
+ // 处理收到自定义消息事件
96
+ Log.d(TAG, "收到自定义消息: $dataString")
97
+ notifyListeners(CUSTOM_MESSAGE_RECEIVED, data)
98
+ }
99
+
100
+ }
101
+ } catch (e: Exception) {
102
+ Log.e(TAG, "处理广播事件失败: ${e.message}")
103
+ }
104
+ }
105
+ }
106
+
107
+ override fun load() {
108
+ super.load()
109
+ jPush = JPush(context)
110
+
111
+ // 注册广播接收器
112
+ registerBroadcastReceiver()
113
+
114
+ Log.d(TAG, "JPushPlugin 已加载")
115
+ }
116
+
117
+ override fun handleOnResume() {
118
+ super.handleOnResume()
119
+
120
+ // 当应用回到前台时,如果配置了activeClearBadge为true,则清除角标
121
+ if (activeClearBadge) {
122
+ Log.d(TAG, "应用回到前台,清除角标")
123
+ jPush.setBadge(0)
124
+ }
125
+ }
126
+
127
+ override fun handleOnDestroy() {
128
+ super.handleOnDestroy()
129
+
130
+ // 注销广播接收器
131
+ unregisterBroadcastReceiver()
132
+
133
+ Log.d(TAG, "JPushPlugin 已销毁")
134
+ }
135
+
136
+ /**
137
+ * 初始化极光推送服务
138
+ */
139
+ @PluginMethod
140
+ fun setupJPush(call: PluginCall) {
141
+ // 从Capacitor配置中读取参数
142
+ val appKey = config.getString("appKey")
143
+ val channel = config.getString("channel", "Android")
144
+ val production = config.getBoolean("production", false)
145
+ activeClearBadge = config.getBoolean("activeClearBadge", false)
146
+
147
+ if (appKey.isNullOrEmpty()) {
148
+ call.reject("appKey 不能为空")
149
+ return
150
+ }
151
+
152
+ // 初始化极光推送(异步)
153
+ jPush.setupJPush(appKey, channel, production)
154
+ isInitialized = true
155
+ // 直接返回成功,初始化结果通过事件通知
156
+ call.resolve()
157
+ }
158
+
159
+ /**
160
+ * 获取设备的注册ID
161
+ */
162
+ @PluginMethod
163
+ fun getRegistrationID(call: PluginCall) {
164
+ if (!isInitialized) {
165
+ call.reject("极光推送未初始化,请先调用initJPush方法")
166
+ return
167
+ }
168
+
169
+ val registrationID = jPush.getRegistrationID()
170
+
171
+ if (registrationID.isNotEmpty()) {
172
+ val ret = JSObject().apply {
173
+ put("registrationID", registrationID)
174
+ }
175
+ call.resolve(ret)
176
+ } else {
177
+ // 保存回调,等待注册完成
178
+ this.registrationIdCall = call
179
+ }
180
+ }
181
+
182
+ /**
183
+ * 设置别名
184
+ */
185
+ @PluginMethod
186
+ fun setAlias(call: PluginCall) {
187
+ val alias = call.getString("alias")
188
+
189
+ val seq = call.getInt("seq")
190
+
191
+ if (alias.isNullOrEmpty()) {
192
+ call.reject("alias 不能为空")
193
+ return
194
+ }
195
+
196
+ if (!isInitialized) {
197
+ call.reject("极光推送未初始化,请先调用initJPush方法")
198
+ return
199
+ }
200
+
201
+ val success = jPush.setAlias(alias, seq, call.callbackId)
202
+
203
+ if (success) {
204
+ call.resolve()
205
+ } else {
206
+ call.reject("设置别名失败")
207
+ }
208
+ }
209
+
210
+ /**
211
+ * 清除别名
212
+ */
213
+ @PluginMethod
214
+ fun deleteAlias(call: PluginCall) {
215
+ val seq = call.getInt("seq")
216
+
217
+ if (!isInitialized) {
218
+ call.reject("极光推送未初始化,请先调用initJPush方法")
219
+ return
220
+ }
221
+
222
+ val success = jPush.deleteAlias(seq, call.callbackId)
223
+
224
+ if (success) {
225
+ call.resolve()
226
+ } else {
227
+ call.reject("清除别名失败")
228
+ }
229
+ }
230
+
231
+ /**
232
+ * 设置标签(替换所有现有标签)
233
+ */
234
+ @PluginMethod
235
+ fun setTags(call: PluginCall) {
236
+ val tagsArray = call.getArray("tags")
237
+ val seq = call.getInt("seq")
238
+
239
+ val tags = mutableListOf<String>()
240
+ if (tagsArray != null) {
241
+ for (i in 0 until tagsArray.length()) {
242
+ tagsArray.getString(i)?.let { tags.add(it) }
243
+ }
244
+ }
245
+
246
+ if (tags.isEmpty()) {
247
+ call.reject("tags 不能为空")
248
+ return
249
+ }
250
+
251
+ if (!isInitialized) {
252
+ call.reject("极光推送未初始化,请先调用initJPush方法")
253
+ return
254
+ }
255
+
256
+ val success = jPush.setTags(tags, seq, call.callbackId)
257
+
258
+ if (success) {
259
+ call.resolve()
260
+ } else {
261
+ call.reject("设置标签失败")
262
+ }
263
+ }
264
+
265
+ /**
266
+ * 添加标签
267
+ */
268
+ @PluginMethod
269
+ fun addTags(call: PluginCall) {
270
+ val tagsArray = call.getArray("tags")
271
+ val seq = call.getInt("seq")
272
+
273
+ val tags = mutableListOf<String>()
274
+ if (tagsArray != null) {
275
+ for (i in 0 until tagsArray.length()) {
276
+ tagsArray.getString(i)?.let { tags.add(it) }
277
+ }
278
+ }
279
+
280
+ if (tags.isEmpty()) {
281
+ call.reject("tags 不能为空")
282
+ return
283
+ }
284
+
285
+ if (!isInitialized) {
286
+ call.reject("极光推送未初始化,请先调用initJPush方法")
287
+ return
288
+ }
289
+
290
+ val success = jPush.addTags(tags, seq, call.callbackId)
291
+
292
+ if (success) {
293
+ call.resolve()
294
+ } else {
295
+ call.reject("添加标签失败")
296
+ }
297
+ }
298
+
299
+ /**
300
+ * 删除标签
301
+ */
302
+ @PluginMethod
303
+ fun deleteTags(call: PluginCall) {
304
+ val tagsArray = call.getArray("tags")
305
+ val seq = call.getInt("seq")
306
+
307
+ val tags = mutableListOf<String>()
308
+ if (tagsArray != null) {
309
+ for (i in 0 until tagsArray.length()) {
310
+ tagsArray.getString(i)?.let { tags.add(it) }
311
+ }
312
+ }
313
+
314
+ if (tags.isEmpty()) {
315
+ call.reject("tags 不能为空")
316
+ return
317
+ }
318
+
319
+ if (!isInitialized) {
320
+ call.reject("极光推送未初始化,请先调用initJPush方法")
321
+ return
322
+ }
323
+
324
+ val success = jPush.deleteTags(tags, seq, call.callbackId)
325
+
326
+ if (success) {
327
+ call.resolve()
328
+ } else {
329
+ call.reject("删除标签失败")
330
+ }
331
+ }
332
+
333
+ /**
334
+ * 清除所有标签
335
+ */
336
+ @PluginMethod
337
+ fun cleanTags(call: PluginCall) {
338
+ if (!isInitialized) {
339
+ call.reject("极光推送未初始化,请先调用initJPush方法")
340
+ return
341
+ }
342
+
343
+ val success = jPush.cleanTags(null, call.callbackId)
344
+
345
+ if (success) {
346
+ call.resolve()
347
+ } else {
348
+ call.reject("清除标签失败")
349
+ }
350
+ }
351
+
352
+ /**
353
+ * 检查推送权限
354
+ */
355
+ @PluginMethod
356
+ override fun checkPermissions(call: PluginCall) {
357
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
358
+ // Android 13以下:通知权限不是运行时权限,默认授予
359
+ val permissionsResult = JSObject()
360
+ permissionsResult.put("permission", "granted")
361
+ call.resolve(permissionsResult)
362
+ } else {
363
+ // Android 13+:使用Capacitor框架的权限检查机制
364
+ super.checkPermissions(call)
365
+ }
366
+ }
367
+
368
+ /**
369
+ * 请求推送权限
370
+ */
371
+ @PluginMethod
372
+ override fun requestPermissions(call: PluginCall) {
373
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
374
+ // Android 13以下:通知权限不是运行时权限,默认授予
375
+ val permissionsResult = JSObject()
376
+ permissionsResult.put(NOTIFICATIONS_STATUS_KEY, "granted")
377
+ call.resolve(permissionsResult)
378
+ } else {
379
+ // Android 13+:使用Capacitor框架的权限请求机制
380
+ super.requestPermissionForAlias(NOTIFICATIONS_STATUS_KEY, call, "permissionsCallback")
381
+ }
382
+ }
383
+
384
+ @PermissionCallback
385
+ private fun permissionsCallback(call: PluginCall) {
386
+ this.checkPermissions(call)
387
+ }
388
+
389
+ /**
390
+ * 设置未读角标数量
391
+ */
392
+ @PluginMethod
393
+ fun setBadge(call: PluginCall) {
394
+ if (!isInitialized) {
395
+ call.reject("极光推送未初始化,请先调用initJPush方法")
396
+ return
397
+ }
398
+
399
+ val badge = call.getInt("badge", 0) ?: 0
400
+
401
+ jPush.setBadge(badge)
402
+ call.resolve()
403
+ }
404
+
405
+ /**
406
+ * 注册广播接收器
407
+ */
408
+ private fun registerBroadcastReceiver() {
409
+ val filter = IntentFilter().apply {
410
+ addAction(JPushReceiver.ACTION_REGISTRATION_COMPLETED)
411
+ addAction(JPushReceiver.ACTION_REGISTRATION_FAILED)
412
+ addAction(JPushReceiver.ACTION_NOTIFICATION_RECEIVED)
413
+ addAction(JPushReceiver.ACTION_NOTIFICATION_OPENED) // 取消注释,接收点击通知事件
414
+ addAction(JPushReceiver.ACTION_CUSTOM_MESSAGE_RECEIVED)
415
+ }
416
+
417
+ ContextCompat.registerReceiver(context, broadcastReceiver, filter, ContextCompat.RECEIVER_NOT_EXPORTED)
418
+ }
419
+
420
+ /**
421
+ * 注销广播接收器
422
+ */
423
+ private fun unregisterBroadcastReceiver() {
424
+ try {
425
+ context.unregisterReceiver(broadcastReceiver)
426
+ } catch (e: Exception) {
427
+ Log.e(TAG, "注销广播接收器失败: ${e.message}")
428
+ }
429
+ }
430
+
431
+ }