@haykmkrtich/react-native-patriot-native 1.0.6 → 1.1.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.
package/README.md CHANGED
@@ -1,204 +1,217 @@
1
- # React Native Patriot Native
2
-
3
- [![npm version](https://badge.fury.io/js/%40haykmkrtich%2Freact-native-patriot-native.svg)](https://badge.fury.io/js/%40haykmkrtich%2Freact-native-patriot-native)
4
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
- [![Platform](https://img.shields.io/badge/platform-react--native-lightgrey)](https://reactnative.dev/)
6
-
7
- > 🚀 Seamlessly install WearOS watch faces and retrieve device information directly from your React Native mobile application.
8
-
9
- ## ✨ What's New in v1.0.5
10
-
11
- - 🔍 **Device Detection**: New `getConnectedWatchProperties()` function
12
- - 📱 **Multi-Platform Support**: Detect WearOS, Fitbit, and other wearable devices
13
- - 🏷️ **Device Information**: Get name, platform, type, and unique ID
14
- - 🛡️ **Enhanced Error Handling**: Improved disconnection detection
15
-
16
- ## 🚀 Quick Start
17
-
18
- ```bash
19
- npm install @haykmkrtich/react-native-patriot-native
20
- ```
21
-
22
- ```typescript
23
- import { installWatchface, getConnectedWatchProperties } from '@haykmkrtich/react-native-patriot-native';
24
-
25
- // Install watchface
26
- await installWatchface('com.example.watchface.package');
27
-
28
- // Get device info
29
- const watch = await getConnectedWatchProperties();
30
- console.log(`Connected: ${watch.displayName} (${watch.platform})`);
31
- ```
32
-
33
- ## 📋 Requirements
34
-
35
- - ⚛️ React Native ≥ 0.60.0
36
- - 🤖 Android API level 21+ (Android 5.0+)
37
- - ⌚ Paired WearOS device
38
-
39
- ## 🎯 Features
40
-
41
- | Feature | Description |
42
- |---------|-------------|
43
- | 📦 **Watch Face Installation** | Install watch faces directly on paired WearOS devices |
44
- | 🔍 **Device Detection** | Retrieve detailed information about connected devices |
45
- | 🏷️ **Platform Detection** | Identify WearOS, Fitbit, and other wearable platforms |
46
- | 📡 **Connection Status** | Monitor device connectivity and proximity |
47
- | 🔄 **Promise-based API** | Modern async/await support |
48
- | 💬 **Native Feedback** | Toast notifications for user feedback |
49
-
50
- ## 📖 API Reference
51
-
52
- ### `installWatchface(packageName: string)`
53
-
54
- Initiates watch face installation on connected WearOS device.
55
-
56
- ```typescript
57
- try {
58
- await installWatchface('com.example.watchface.package');
59
- // Installation initiated successfully
60
- } catch (error) {
61
- // ❌ Handle installation errors
62
- }
63
- ```
64
-
65
- **Errors:**
66
- - `NO_NODES` - No connected WearOS device
67
- - `INSTALL_FAILED` - Installation process failed
68
-
69
- ### `getConnectedWatchProperties()`
70
-
71
- Retrieves detailed information about connected wearable devices.
72
-
73
- ```typescript
74
- interface WatchProperties {
75
- id: string; // Unique device identifier
76
- displayName: string; // Human-readable device name
77
- isNearby: boolean; // Device proximity status
78
- type: string; // Device type (e.g., "watch")
79
- platform: string; // Platform ("wearOS" | "fitbit")
80
- isDisconnected?: boolean; // No device connected
81
- }
82
- ```
83
-
84
- **Example Response:**
85
- ```typescript
86
- // Connected Device
87
- {
88
- id: "node_12345_abcdef",
89
- displayName: "Galaxy Watch 4",
90
- isNearby: true,
91
- type: "watch",
92
- platform: "wearOS"
93
- }
94
-
95
- // ❌ No Device
96
- { isDisconnected: true }
97
- ```
98
-
99
- ## 🔧 Setup Requirements
100
-
101
- ### Android Dependencies
102
-
103
- Add to your `android/app/build.gradle`:
104
-
105
- ```gradle
106
- dependencies {
107
- implementation 'com.google.android.gms:play-services-wearable:18.1.0'
108
- implementation 'androidx.wear:wear-remote-interactions:1.0.0'
109
- }
110
- ```
111
-
112
- ### WearOS Development Best Practices
113
-
114
- > ⚠️ **Important**: For Google Play Console compliance, create **two applications** with identical package names:
115
- > - 📱 Mobile companion app (React Native)
116
- > - WearOS watch face app
117
-
118
- This ensures proper functionality and distribution through Google Play Store.
119
-
120
- ## 🛠️ How It Works
121
-
122
- ```mermaid
123
- graph LR
124
- A[Mobile App] --> B[WearOS Remote API]
125
- B --> C[Connected Watch]
126
- C --> D[Google Play Store]
127
- D --> E[Watch Face Installation]
128
- ```
129
-
130
- 1. **Device Discovery** - Scan for connected WearOS devices
131
- 2. **Remote Installation** - Send installation request to watch
132
- 3. **Play Store Integration** - Open watch face listing on device
133
- 4. **User Confirmation** - User confirms installation on watch
134
-
135
- ## 💡 Usage Examples
136
-
137
- ### Basic Installation
138
- ```typescript
139
- import { installWatchface } from '@haykmkrtich/react-native-patriot-native';
140
-
141
- const handleInstall = async (packageName: string) => {
142
- try {
143
- await installWatchface(packageName);
144
- console.log('✅ Check your watch for installation prompt');
145
- } catch (error) {
146
- console.error('❌ Installation failed:', error.message);
147
- }
148
- };
149
- ```
150
-
151
- ### Device Information
152
- ```typescript
153
- import { getConnectedWatchProperties } from '@haykmkrtich/react-native-patriot-native';
154
-
155
- const checkWatchStatus = async () => {
156
- try {
157
- const watch = await getConnectedWatchProperties();
158
-
159
- if (watch.isDisconnected) {
160
- return '❌ No watch connected';
161
- }
162
-
163
- return `✅ ${watch.displayName} (${watch.platform}) - ${watch.isNearby ? 'Nearby' : 'Away'}`;
164
- } catch (error) {
165
- return `❌ Detection failed: ${error.message}`;
166
- }
167
- };
168
- ```
169
-
170
- ## 🤝 Contributing
171
-
172
- Contributions are welcome! Please read our [contributing guidelines](CONTRIBUTING.md) before submitting PRs.
173
-
174
- 1. Fork the repository
175
- 2. Create your feature branch (`git checkout -b feature/amazing-feature`)
176
- 3. Commit your changes (`git commit -m 'Add amazing feature'`)
177
- 4. Push to the branch (`git push origin feature/amazing-feature`)
178
- 5. Open a Pull Request
179
-
180
- ## 📄 License
181
-
182
- This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
183
-
184
- ## 👨‍💻 Author
185
-
186
- **Hayk Mkrtich**
187
- - GitHub: [@HaykMkrtich](https://github.com/HaykMkrtich)
188
- - NPM: [@haykmkrtich](https://www.npmjs.com/~haykmkrtich)
189
-
190
- ## 🆘 Support
191
-
192
- - 🐛 **Bug Reports**: [Create an issue](https://github.com/HaykMkrtich/react-native-patriot-native/issues/new?template=bug_report.md)
193
- - 💡 **Feature Requests**: [Request a feature](https://github.com/HaykMkrtich/react-native-patriot-native/issues/new?template=feature_request.md)
194
- - 📖 **Documentation**: [View full docs](https://github.com/HaykMkrtich/react-native-patriot-native/wiki)
195
-
196
- ---
197
-
198
- <div align="center">
199
-
200
- **⭐ Star this repository if it helped you!**
201
-
202
- Made with ❤️ for the React Native community
203
-
204
- </div>
1
+ # React Native Patriot Native
2
+
3
+ [![npm version](https://badge.fury.io/js/%40haykmkrtich%2Freact-native-patriot-native.svg)](https://badge.fury.io/js/%40haykmkrtich%2Freact-native-patriot-native)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+ [![Platform](https://img.shields.io/badge/platform-react--native-lightgrey)](https://reactnative.dev/)
6
+
7
+ A React Native module that enables seamless interaction with WearOS devices — install watch faces, detect connected devices, check app installations, and send messages directly from your mobile app.
8
+
9
+ ## Features
10
+
11
+ | Feature | Description |
12
+ |---------|-------------|
13
+ | **Watch Face Installation** | Install watch faces directly on paired WearOS devices |
14
+ | **Device Detection** | Get detailed info on all connected WearOS devices |
15
+ | **Platform Detection** | Identify WearOS vs other wearable platforms |
16
+ | **App Install Check** | Verify if a specific app is installed on the watch |
17
+ | **Custom Messaging** | Send arbitrary messages to specific watch nodes |
18
+ | **New Architecture** | TurboModule support for React Native 0.77+ |
19
+ | **16KB Page Size** | Compliant with Google Play's 16KB page size requirements |
20
+
21
+ ## Installation
22
+
23
+ ```bash
24
+ npm install @haykmkrtich/react-native-patriot-native
25
+ # or
26
+ yarn add @haykmkrtich/react-native-patriot-native
27
+ ```
28
+
29
+ ## Requirements
30
+
31
+ - React Native >= 0.60.0
32
+ - Android API level 24+ (Android 7.0+)
33
+ - Java 17+
34
+ - Paired WearOS device
35
+
36
+ ## Quick Start
37
+
38
+ ```typescript
39
+ import {
40
+ installWatchface,
41
+ getConnectedDevices,
42
+ isAppInstalledOnWatch,
43
+ sendMessageToWatch,
44
+ } from '@haykmkrtich/react-native-patriot-native';
45
+
46
+ // Get all connected devices
47
+ const devices = await getConnectedDevices();
48
+ console.log(devices);
49
+ // [{ id: "node_123", displayName: "Galaxy Watch 4", isNearby: true, type: "watch", platform: "wearOS" }]
50
+
51
+ // Install a watch face
52
+ await installWatchface('com.example.watchface.package');
53
+
54
+ // Check if an app is installed on the watch
55
+ const status = await isAppInstalledOnWatch('com.example.watchface');
56
+ // { isInstalled: true, installedOnNodes: ["node_123"] }
57
+
58
+ // Send a custom message to a specific watch
59
+ await sendMessageToWatch(devices[0].id, '/my-path', 'hello');
60
+ ```
61
+
62
+ ## API Reference
63
+
64
+ ### `getConnectedDevices(): Promise<ConnectedDevice[]>`
65
+
66
+ Returns all connected WearOS devices with full details. Returns an empty array if no devices are connected.
67
+
68
+ ```typescript
69
+ interface ConnectedDevice {
70
+ id: string; // Unique device identifier
71
+ displayName: string; // Human-readable device name
72
+ isNearby: boolean; // Device proximity status
73
+ type: string; // Device type (e.g., "watch")
74
+ platform: string; // Platform ("wearOS" | "unknown")
75
+ }
76
+ ```
77
+
78
+ **Example:**
79
+ ```typescript
80
+ const devices = await getConnectedDevices();
81
+
82
+ if (devices.length === 0) {
83
+ console.log('No watches connected');
84
+ } else {
85
+ devices.forEach(device => {
86
+ console.log(`${device.displayName} (${device.platform}) - ${device.isNearby ? 'Nearby' : 'Away'}`);
87
+ });
88
+ }
89
+ ```
90
+
91
+ **Error Codes:**
92
+ - `DETECTION_FAILED` — Failed to communicate with WearOS API
93
+
94
+ ---
95
+
96
+ ### `installWatchface(packageName: string): Promise<void>`
97
+
98
+ Initiates watch face installation on all connected WearOS devices.
99
+
100
+ **Parameters:**
101
+ - `packageName` — The Google Play package name of the watch face to install
102
+
103
+ **Example:**
104
+ ```typescript
105
+ try {
106
+ await installWatchface('com.awesome.watchface');
107
+ // User will see a toast and installation prompt on their watch
108
+ } catch (error) {
109
+ if (error.code === 'NO_NODES') {
110
+ console.log('No watch connected');
111
+ }
112
+ }
113
+ ```
114
+
115
+ **Error Codes:**
116
+ - `NO_NODES` — No connected WearOS device found
117
+ - `INSTALL_FAILED` — Installation request failed
118
+
119
+ ---
120
+
121
+ ### `isAppInstalledOnWatch(packageName: string): Promise<AppInstallStatus>`
122
+
123
+ Checks if a specific app or capability is available on connected watches.
124
+
125
+ ```typescript
126
+ interface AppInstallStatus {
127
+ isInstalled: boolean; // Whether the app is found on any watch
128
+ installedOnNodes: string[]; // IDs of watches that have the app
129
+ }
130
+ ```
131
+
132
+ **Example:**
133
+ ```typescript
134
+ const status = await isAppInstalledOnWatch('com.example.watchface');
135
+ if (status.isInstalled) {
136
+ console.log(`Installed on ${status.installedOnNodes.length} device(s)`);
137
+ }
138
+ ```
139
+
140
+ **Error Codes:**
141
+ - `CHECK_FAILED` Failed to query capabilities
142
+
143
+ ---
144
+
145
+ ### `sendMessageToWatch(nodeId: string, path: string, data?: string): Promise<void>`
146
+
147
+ Sends a custom message to a specific watch node. Use `getConnectedDevices()` first to get the node ID.
148
+
149
+ **Parameters:**
150
+ - `nodeId` — Target device ID (from `getConnectedDevices()`)
151
+ - `path` — Message path (e.g., `/my-action`)
152
+ - `data` — Optional string payload (defaults to empty string)
153
+
154
+ **Example:**
155
+ ```typescript
156
+ const devices = await getConnectedDevices();
157
+ if (devices.length > 0) {
158
+ await sendMessageToWatch(devices[0].id, '/sync-settings', JSON.stringify({ theme: 'dark' }));
159
+ }
160
+ ```
161
+
162
+ **Error Codes:**
163
+ - `MESSAGE_FAILED` Failed to send message
164
+
165
+ ---
166
+
167
+ ### `getConnectedWatchProperties(): Promise<ConnectedDevice>` *(deprecated)*
168
+
169
+ Returns the first connected device. Use `getConnectedDevices()` instead.
170
+
171
+ ## WearOS Development Best Practices
172
+
173
+ This module is designed for WearOS watch face companion apps. For Google Play Console compliance:
174
+
175
+ 1. Create **two applications** with identical package names:
176
+ - Mobile companion app (React Native, using this module)
177
+ - WearOS watch face app
178
+ 2. This package name consistency is required for proper functionality and distribution through Google Play Store.
179
+
180
+ ## How It Works
181
+
182
+ 1. **Device Discovery** Scan for connected WearOS devices via NodeClient
183
+ 2. **Remote Installation** — Send installation request to connected watches
184
+ 3. **Play Store Integration** — Opens the watch face listing on the watch's Play Store
185
+ 4. **User Confirmation** — User confirms installation on their watch
186
+
187
+ ## Changelog
188
+
189
+ ### 1.1.0
190
+ - **New:** `getConnectedDevices()` — returns all connected devices with full details (replaces `getConnectedWatchProperties`)
191
+ - **New:** `isAppInstalledOnWatch(packageName)` — check if an app is installed on connected watches
192
+ - **New:** `sendMessageToWatch(nodeId, path, data)` — send custom messages to specific watch nodes
193
+ - **Deprecated:** `getConnectedWatchProperties()` use `getConnectedDevices()` instead
194
+ - **Fixed:** "No matching variant" build error on React Native 0.78+ / AGP 8.11+
195
+ - Added `publishing` block for AGP 8.11+ compatibility
196
+ - Updated `compileSdk`/`targetSdk` to 35
197
+ - Java 17 compatibility
198
+ - **Fixed:** Duplicate class errors from broken newarch/oldarch stubs — both now have full implementations
199
+
200
+ ## Contributing
201
+
202
+ Contributions are welcome! Please feel free to submit a Pull Request.
203
+
204
+ ## License
205
+
206
+ MIT License - see the [LICENSE](LICENSE) file for details.
207
+
208
+ ## Author
209
+
210
+ **Hayk Mkrtich**
211
+ - GitHub: [@HaykMkrtich](https://github.com/HaykMkrtich)
212
+ - NPM: [@haykmkrtich](https://www.npmjs.com/~haykmkrtich)
213
+
214
+ ## Support
215
+
216
+ - [Report Issues](https://github.com/HaykMkrtich/react-native-patriot-native/issues)
217
+ - [Feature Requests](https://github.com/HaykMkrtich/react-native-patriot-native/issues)
@@ -1,50 +1,39 @@
1
1
  apply plugin: 'com.android.library'
2
2
  apply plugin: 'com.facebook.react'
3
3
 
4
- // Поддержка новой архитектуры React Native
5
- def isNewArchitectureEnabled() {
6
- return rootProject.hasProperty("newArchEnabled") && rootProject.getProperty("newArchEnabled") == "true"
7
- }
8
-
9
4
  android {
10
- compileSdkVersion 34
5
+ compileSdk 35
11
6
  namespace "com.patriotnative"
12
7
 
13
8
  defaultConfig {
14
- minSdkVersion 24 // Повышаем минимальную версию для поддержки новых возможностей
15
- targetSdkVersion 34
9
+ minSdk 24
10
+ targetSdk 35
16
11
 
17
- // Добавляем поддержка 16KB страниц
18
12
  ndk {
19
13
  abiFilters "arm64-v8a", "x86_64"
20
14
  }
21
15
  }
22
16
 
23
17
  compileOptions {
24
- sourceCompatibility JavaVersion.VERSION_17 // Обновляем до Java 17 для RN 0.77
18
+ sourceCompatibility JavaVersion.VERSION_17
25
19
  targetCompatibility JavaVersion.VERSION_17
26
20
  }
27
21
 
28
- // Исправляем packagingOptions на packaging
29
22
  packaging {
30
23
  pickFirst "**/libc++_shared.so"
31
24
  pickFirst "**/libjsc.so"
32
25
  }
33
26
 
34
- // Оптимизация для 16KB страниц
35
- buildFeatures {
36
- prefab true
37
- buildConfig false
27
+ publishing {
28
+ singleVariant("release") {
29
+ withSourcesJar()
30
+ }
38
31
  }
39
32
 
40
- // Поддержка новой архитектуры
41
33
  sourceSets {
42
34
  main {
43
- if (isNewArchitectureEnabled()) {
44
- java.srcDirs += [
45
- "src/newarch/java",
46
- "${project.buildDir}/generated/source/codegen/java"
47
- ]
35
+ if (project.hasProperty("newArchEnabled") && project.property("newArchEnabled") == "true") {
36
+ java.srcDirs += ["src/newarch/java"]
48
37
  } else {
49
38
  java.srcDirs += ["src/oldarch/java"]
50
39
  }
@@ -52,7 +41,6 @@ android {
52
41
  }
53
42
  }
54
43
 
55
- // Поддержка React Native Codegen
56
44
  react {
57
45
  libraryName = "PatriotNative"
58
46
  codegenJavaPackageName = "com.patriotnative"
@@ -63,9 +51,4 @@ dependencies {
63
51
  implementation 'androidx.annotation:annotation:1.7.0'
64
52
  implementation 'com.google.android.gms:play-services-wearable:18.2.0'
65
53
  implementation 'androidx.wear:wear-remote-interactions:1.0.0'
66
-
67
- // Исправляем условие для новой архитектуры
68
- if (isNewArchitectureEnabled()) {
69
- implementation project(":ReactAndroid") // Правильная зависимость для новой архитектуры
70
- }
71
54
  }
@@ -1,25 +1,9 @@
1
- <?xml version="1.0" encoding="utf-8"?>
2
- <manifest xmlns:android="http://schemas.android.com/apk/res/android">
3
-
4
- <!-- Разрешения для работы с WearOS устройствами -->
5
- <uses-permission android:name="android.permission.WAKE_LOCK" />
6
- <uses-permission android:name="com.google.android.permission.PROVIDE_BACKGROUND" />
7
-
8
- <!-- Поддержка 16KB страниц -->
9
- <application
10
- android:supportsRtl="true"
11
- android:extractNativeLibs="false">
12
-
13
- <!-- Метаданные для WearOS -->
14
- <meta-data
15
- android:name="com.google.android.gms.version"
16
- android:value="@integer/google_play_services_version" />
17
-
18
- <!-- Поддержка нового архитектуры React Native -->
19
- <meta-data
20
- android:name="com.facebook.react.modules.core.DefaultHardwareBackBtnHandler"
21
- android:value="true" />
22
- </application>
23
-
24
- </manifest>
25
-
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android">
3
+
4
+ <uses-permission android:name="android.permission.WAKE_LOCK" />
5
+ <uses-permission android:name="com.google.android.permission.PROVIDE_BACKGROUND" />
6
+
7
+ <application android:extractNativeLibs="false" />
8
+
9
+ </manifest>
@@ -1,39 +1,47 @@
1
- /**
2
- * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
3
- *
4
- * Do not edit this file as changes may cause incorrect behavior and will be lost
5
- * once the code is regenerated.
6
- *
7
- * @generated by codegen project: GenerateModuleJavaSpec.js
8
- */
9
-
10
- package com.patriotnative;
11
-
12
- import com.facebook.proguard.annotations.DoNotStrip;
13
- import com.facebook.react.bridge.Promise;
14
- import com.facebook.react.bridge.ReactApplicationContext;
15
- import com.facebook.react.bridge.ReactContextBaseJavaModule;
16
- import com.facebook.react.bridge.ReactMethod;
17
- import com.facebook.react.turbomodule.core.interfaces.TurboModule;
18
-
19
- public abstract class NativePatriotNativeSpec extends ReactContextBaseJavaModule implements TurboModule {
20
-
21
- public static final String NAME = "PatriotNative";
22
-
23
- public NativePatriotNativeSpec(ReactApplicationContext reactContext) {
24
- super(reactContext);
25
- }
26
-
27
- @Override
28
- public String getName() {
29
- return NAME;
30
- }
31
-
32
- @ReactMethod
33
- @DoNotStrip
34
- public abstract void installWatchface(String packageName, Promise promise);
35
-
36
- @ReactMethod
37
- @DoNotStrip
38
- public abstract void getConnectedWatchProperties(Promise promise);
39
- }
1
+ /**
2
+ * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
3
+ *
4
+ * Do not edit this file as changes may cause incorrect behavior and will be lost
5
+ * once the code is regenerated.
6
+ *
7
+ * @generated by codegen project: GenerateModuleJavaSpec.js
8
+ */
9
+
10
+ package com.patriotnative;
11
+
12
+ import com.facebook.proguard.annotations.DoNotStrip;
13
+ import com.facebook.react.bridge.Promise;
14
+ import com.facebook.react.bridge.ReactApplicationContext;
15
+ import com.facebook.react.bridge.ReactContextBaseJavaModule;
16
+ import com.facebook.react.bridge.ReactMethod;
17
+ import com.facebook.react.turbomodule.core.interfaces.TurboModule;
18
+
19
+ public abstract class NativePatriotNativeSpec extends ReactContextBaseJavaModule implements TurboModule {
20
+
21
+ public static final String NAME = "PatriotNative";
22
+
23
+ public NativePatriotNativeSpec(ReactApplicationContext reactContext) {
24
+ super(reactContext);
25
+ }
26
+
27
+ @Override
28
+ public String getName() {
29
+ return NAME;
30
+ }
31
+
32
+ @ReactMethod
33
+ @DoNotStrip
34
+ public abstract void installWatchface(String packageName, Promise promise);
35
+
36
+ @ReactMethod
37
+ @DoNotStrip
38
+ public abstract void getConnectedDevices(Promise promise);
39
+
40
+ @ReactMethod
41
+ @DoNotStrip
42
+ public abstract void isAppInstalledOnWatch(String packageName, Promise promise);
43
+
44
+ @ReactMethod
45
+ @DoNotStrip
46
+ public abstract void sendMessageToWatch(String nodeId, String path, String data, Promise promise);
47
+ }