Files
bluememe-cordova-utils/README.md
T

252 lines
8.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# bluememe-utils
Cordova plugin for OutSystems 11 mobile apps.
功能:
- 保存或连接指定 WiFi 热点
- Firebase Cloud Messaging 推送通知
- Touch ID / Face ID / Android biometric 解锁,并把解锁结果通知给应用
插件 ID:`bluememe-utils`
JS 全局对象:
- `BluememeUtils`
- `cordova.plugins.bluememeUtils`
## Install
在 OutSystems 11 的 extensibility configuration 中添加插件仓库或本地包后,可使用下面的参数覆盖 Firebase 配置。
```json
{
"plugin": {
"url": "bluememe-utils",
"variables": {
"ANDROID_FIREBASE_APP_ID": "1:000000000000:android:xxxxxxxxxxxxxxxx",
"ANDROID_FIREBASE_API_KEY": "AIza...",
"ANDROID_FIREBASE_PROJECT_ID": "your-firebase-project",
"ANDROID_FIREBASE_SENDER_ID": "000000000000",
"ANDROID_FIREBASE_STORAGE_BUCKET": "your-firebase-project.appspot.com",
"IOS_FIREBASE_GOOGLE_APP_ID": "1:000000000000:ios:xxxxxxxxxxxxxxxx",
"IOS_FIREBASE_API_KEY": "AIza...",
"IOS_FIREBASE_PROJECT_ID": "your-firebase-project",
"IOS_FIREBASE_GCM_SENDER_ID": "000000000000",
"IOS_FIREBASE_STORAGE_BUCKET": "your-firebase-project.appspot.com",
"IOS_FACE_ID_USAGE_DESCRIPTION": "Use Face ID to unlock this application."
}
}
}
```
也可以让宿主 App 提供并处理标准 Firebase 配置文件:
- Android:`google-services.json`
- iOS:`GoogleService-Info.plist`
如果宿主工程已经由 OutSystems、MABS 配置或其他插件初始化 Firebase,本插件会复用已有的 default Firebase app。否则建议使用上面的 plugin variables,让本插件在运行时手动初始化 Firebase。
## JavaScript API
所有方法都使用 Cordova callback 风格,适合在 OutSystems client action 中封装。
```js
BluememeUtils.getDeviceInfo(function (info) {
console.log(info.deviceKey);
}, error);
```
`getDeviceInfo` 返回:
```json
{
"deviceKey": "generated-and-persisted-uuid",
"platform": "Android",
"appIdentifier": "com.company.app",
"appVersion": "1.0.0",
"buildNumber": "1",
"osVersion": "15",
"sdkVersion": 35,
"deviceModel": "Google Pixel 8",
"manufacturer": "Google",
"brand": "google",
"model": "Pixel 8",
"locale": "ja-JP",
"timeZone": "Asia/Tokyo"
}
```
`deviceKey` 首次调用时生成并保存在本地,用于标识当前 App 安装实例。App 卸载或清除数据后会重新生成。iOS 不返回 `sdkVersion`、`manufacturer`、`brand`,但会返回 `systemName`。
```js
BluememeUtils.requestWifiPermission(success, error);
BluememeUtils.saveWifi({
ssid: "MyHotspot",
password: "password123",
security: "wpa2"
}, success, error);
BluememeUtils.connectWifi({
ssid: "MyHotspot",
password: "password123",
security: "wpa2"
}, success, error);
BluememeUtils.removeWifi({ ssid: "MyHotspot", password: "password123", security: "wpa2" }, success, error);
BluememeUtils.disconnectWifi(success, error);
```
WiFi options:
- `ssid`:必填
- `password`:开放网络可省略
- `security`:`open`、`wep`、`wpa2`、`wpa3`,默认按是否存在 password 推断为 `open` 或 `wpa2`
- `hiddenSsid`:可选;Android 支持隐藏 SSID;iOS 15+ 会设置 `NEHotspotConfiguration.hidden`
- `bssid`:可选,仅 Android 10+ 临时连接使用
- `joinOnce`:可选,仅 iOS;`connectWifi` 默认 `true`,`saveWifi` 默认 `false`
## Push Notifications
```js
BluememeUtils.requestPushPermission(success, error);
BluememeUtils.getPushPermissionStatus(success, error);
BluememeUtils.getFirebaseToken(function (result) {
console.log(result.token);
}, error);
BluememeUtils.subscribeToTopic("news", success, error);
BluememeUtils.unsubscribeFromTopic("news", success, error);
BluememeUtils.startNotificationListener(function (event) {
if (event.type === "token") {
console.log(event.token);
}
if (event.type === "notification") {
console.log(event.notification);
}
if (event.type === "notificationOpened") {
console.log(event.notification);
}
}, error);
BluememeUtils.getInitialNotification(success, error);
BluememeUtils.stopNotificationListener(success, error);
```
`getPushPermissionStatus` 只读取当前系统通知状态,不弹授权框。可用于填充后端 `NotificationsEnabled`。
返回示例:
```json
{
"type": "notification",
"platform": "Android",
"enabled": true,
"granted": true,
"runtimePermissionGranted": true,
"appNotificationsEnabled": true,
"authorizationStatus": "authorized",
"missing": []
}
```
推荐注册 token 前调用:
```js
BluememeUtils.getPushPermissionStatus(function (status) {
var notificationsEnabled = status.enabled === true;
}, error);
```
事件也会派发到 `window`:
- `bluememeutils.token`
- `bluememeutils.notification`
- `bluememeutils.notificationOpened`
- `bluememeutils.unlock`
也可以用插件内置监听器:
```js
BluememeUtils.on("unlock", function (event) {
console.log(event.unlocked);
});
```
## Biometric Unlock
```js
BluememeUtils.isBiometricAvailable(success, error);
BluememeUtils.unlockWithBiometrics({
reason: "Unlock application",
title: "Unlock",
subtitle: "",
description: "",
cancelText: "Cancel",
fallbackTitle: "Use Passcode",
allowDeviceCredential: true
}, function (result) {
console.log(result.unlocked, result.biometryType);
}, error);
```
`biometryType` 可能值:
- iOS:`face`、`touch`、`none`、`biometric`
- Android:`face`、`fingerprint`、`iris`、`biometric`
## Platform Notes
Android WiFi:
- Android 10+ 不允许第三方应用静默保存并强制切换系统 WiFi。
- `saveWifi` 在 Android 10+ 使用 `WifiNetworkSuggestion`,系统可能要求用户批准。
- `connectWifi` 在 Android 10+ 使用 `WifiNetworkSpecifier`,这是临时连接,通常只绑定当前应用进程网络。
- Android 9 及以下使用旧 `WifiConfiguration` API,可保存并启用网络。
- 调用 WiFi API 前先调用 `requestWifiPermission`,并确保系统位置服务开启。
iOS WiFi:
- 使用 `NEHotspotConfiguration`,当前插件 WiFi 功能要求 iOS 15+。
- 插件将 iOS deployment target 设置为 `15.0`;如果宿主 App 或构建平台覆盖该值,需要在宿主配置中同步设置 iOS 最低版本为 15.0 或更高。
- 插件会向 Cordova iOS entitlements 写入 `com.apple.developer.networking.HotspotConfiguration`,但仍必须在 Apple Developer App ID 中开启 `Hotspot Configuration` capability,并使用包含该 capability 的 provisioning profile 重新构建。
- 如果 iOS 返回 `NEHotspotConfigurationErrorDomain` code `8` / `internal error`,优先检查 App ID、entitlements、provisioning profile 是否都包含 `Hotspot Configuration`,并确认是在真机前台运行,不是在模拟器中测试。若签名和参数都正确,常见原因是真实热点使用 WPA2/WPA3 transition mode、WPA3 Personal、iPhone Personal Hotspot 默认安全模式,或其他 `NEHotspotConfiguration` 无法表达的 WiFi 能力。
- iOS 错误结果会包含 `applicationState`、`ssidUtf8Length`、`passwordUtf8Length`、`passwordAsciiPrintable` 等诊断字段;WPA/WPA2 密码建议使用 8-63 位可打印 ASCII 字符。
- iOS 的 `NEHotspotConfiguration` password initializer 公开支持 WEP/WPA/WPA2 Personal,不提供 WPA3 Personal 参数。iOS 传入 `security` 包含 `wpa3` 时会返回 `UNSUPPORTED_WIFI_SECURITY`。WPA2/WPA3 mixed 通常只能按 `security: "wpa2"` 尝试;如果仍失败,需要用户手动加入,或改用配置描述文件/MDM 流程。
- iOS 不提供第三方 App 断开当前 WiFi 的公开 API,因此 `disconnectWifi` 在 iOS 返回错误。
Firebase:
- Android 13+ 需要通知权限,调用 `requestPushPermission`。
- iOS 需要 Push Notifications capability、Background Modes 中的 Remote notifications,以及 APNs key/certificate 已配置到 Firebase。
- 如果项目中还有其他推送插件,也可能同时修改 `UNUserNotificationCenterDelegate` 或 Firebase service,需要在真机上确认通知打开事件。
Biometric:
- iOS Face ID 需要 `NSFaceIDUsageDescription`,可通过 `IOS_FACE_ID_USAGE_DESCRIPTION` 设置。
- Android 本插件使用平台 `BiometricPrompt`,`unlockWithBiometrics` 支持 Android 9+。
## Error Shape
错误 callback 返回对象:
```json
{
"code": "ERROR_CODE",
"message": "Human readable message"
}
```
常见错误:
- `PERMISSION_REQUIRED`
- `INVALID_WIFI_OPTIONS`
- `WIFI_CONNECT_FAILED`
- `FIREBASE_NOT_CONFIGURED`
- `FCM_TOKEN_FAILED`
- `BIOMETRIC_UNAVAILABLE`
- `AUTHENTICATION_ERROR`