@bits-innovate/react-native-vstarcam 1.0.25 → 1.0.27

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.
@@ -0,0 +1,9 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
3
+ package="com.vstarcam.app_p2p_api" >
4
+
5
+ <uses-sdk
6
+ android:minSdkVersion="16"
7
+ android:targetSdkVersion="16" />
8
+
9
+ </manifest>
@@ -0,0 +1,4 @@
1
+ aarFormatVersion=1.0
2
+ aarMetadataVersion=1.0
3
+ minCompileSdk=1
4
+ minAndroidGradlePluginVersion=1.0.0
@@ -0,0 +1,229 @@
1
+ int attr activityAction 0x0
2
+ int attr activityName 0x0
3
+ int attr alpha 0x0
4
+ int attr alwaysExpand 0x0
5
+ int attr clearTop 0x0
6
+ int attr finishPrimaryWithSecondary 0x0
7
+ int attr finishSecondaryWithPrimary 0x0
8
+ int attr font 0x0
9
+ int attr fontProviderAuthority 0x0
10
+ int attr fontProviderCerts 0x0
11
+ int attr fontProviderFetchStrategy 0x0
12
+ int attr fontProviderFetchTimeout 0x0
13
+ int attr fontProviderPackage 0x0
14
+ int attr fontProviderQuery 0x0
15
+ int attr fontProviderSystemFontFamily 0x0
16
+ int attr fontStyle 0x0
17
+ int attr fontVariationSettings 0x0
18
+ int attr fontWeight 0x0
19
+ int attr nestedScrollViewStyle 0x0
20
+ int attr placeholderActivityName 0x0
21
+ int attr primaryActivityName 0x0
22
+ int attr queryPatterns 0x0
23
+ int attr secondaryActivityAction 0x0
24
+ int attr secondaryActivityName 0x0
25
+ int attr shortcutMatchRequired 0x0
26
+ int attr splitLayoutDirection 0x0
27
+ int attr splitMinSmallestWidth 0x0
28
+ int attr splitMinWidth 0x0
29
+ int attr splitRatio 0x0
30
+ int attr ttcIndex 0x0
31
+ int color androidx_core_ripple_material_light 0x0
32
+ int color androidx_core_secondary_text_default_material_light 0x0
33
+ int color notification_action_color_filter 0x0
34
+ int color notification_icon_bg_color 0x0
35
+ int color ripple_material_light 0x0
36
+ int color secondary_text_default_material_light 0x0
37
+ int dimen compat_button_inset_horizontal_material 0x0
38
+ int dimen compat_button_inset_vertical_material 0x0
39
+ int dimen compat_button_padding_horizontal_material 0x0
40
+ int dimen compat_button_padding_vertical_material 0x0
41
+ int dimen compat_control_corner_material 0x0
42
+ int dimen compat_notification_large_icon_max_height 0x0
43
+ int dimen compat_notification_large_icon_max_width 0x0
44
+ int dimen notification_action_icon_size 0x0
45
+ int dimen notification_action_text_size 0x0
46
+ int dimen notification_big_circle_margin 0x0
47
+ int dimen notification_content_margin_start 0x0
48
+ int dimen notification_large_icon_height 0x0
49
+ int dimen notification_large_icon_width 0x0
50
+ int dimen notification_main_column_padding_top 0x0
51
+ int dimen notification_media_narrow_margin 0x0
52
+ int dimen notification_right_icon_size 0x0
53
+ int dimen notification_right_side_padding_top 0x0
54
+ int dimen notification_small_icon_background_padding 0x0
55
+ int dimen notification_small_icon_size_as_large 0x0
56
+ int dimen notification_subtext_size 0x0
57
+ int dimen notification_top_pad 0x0
58
+ int dimen notification_top_pad_large_text 0x0
59
+ int drawable launch_background 0x0
60
+ int drawable notification_action_background 0x0
61
+ int drawable notification_bg 0x0
62
+ int drawable notification_bg_low 0x0
63
+ int drawable notification_bg_low_normal 0x0
64
+ int drawable notification_bg_low_pressed 0x0
65
+ int drawable notification_bg_normal 0x0
66
+ int drawable notification_bg_normal_pressed 0x0
67
+ int drawable notification_icon_background 0x0
68
+ int drawable notification_template_icon_bg 0x0
69
+ int drawable notification_template_icon_low_bg 0x0
70
+ int drawable notification_tile_bg 0x0
71
+ int drawable notify_panel_notification_icon_bg 0x0
72
+ int id accessibility_action_clickable_span 0x0
73
+ int id accessibility_custom_action_0 0x0
74
+ int id accessibility_custom_action_1 0x0
75
+ int id accessibility_custom_action_10 0x0
76
+ int id accessibility_custom_action_11 0x0
77
+ int id accessibility_custom_action_12 0x0
78
+ int id accessibility_custom_action_13 0x0
79
+ int id accessibility_custom_action_14 0x0
80
+ int id accessibility_custom_action_15 0x0
81
+ int id accessibility_custom_action_16 0x0
82
+ int id accessibility_custom_action_17 0x0
83
+ int id accessibility_custom_action_18 0x0
84
+ int id accessibility_custom_action_19 0x0
85
+ int id accessibility_custom_action_2 0x0
86
+ int id accessibility_custom_action_20 0x0
87
+ int id accessibility_custom_action_21 0x0
88
+ int id accessibility_custom_action_22 0x0
89
+ int id accessibility_custom_action_23 0x0
90
+ int id accessibility_custom_action_24 0x0
91
+ int id accessibility_custom_action_25 0x0
92
+ int id accessibility_custom_action_26 0x0
93
+ int id accessibility_custom_action_27 0x0
94
+ int id accessibility_custom_action_28 0x0
95
+ int id accessibility_custom_action_29 0x0
96
+ int id accessibility_custom_action_3 0x0
97
+ int id accessibility_custom_action_30 0x0
98
+ int id accessibility_custom_action_31 0x0
99
+ int id accessibility_custom_action_4 0x0
100
+ int id accessibility_custom_action_5 0x0
101
+ int id accessibility_custom_action_6 0x0
102
+ int id accessibility_custom_action_7 0x0
103
+ int id accessibility_custom_action_8 0x0
104
+ int id accessibility_custom_action_9 0x0
105
+ int id action_container 0x0
106
+ int id action_divider 0x0
107
+ int id action_image 0x0
108
+ int id action_text 0x0
109
+ int id actions 0x0
110
+ int id androidx_window_activity_scope 0x0
111
+ int id async 0x0
112
+ int id blocking 0x0
113
+ int id chronometer 0x0
114
+ int id dialog_button 0x0
115
+ int id forever 0x0
116
+ int id icon 0x0
117
+ int id icon_group 0x0
118
+ int id info 0x0
119
+ int id italic 0x0
120
+ int id line1 0x0
121
+ int id line3 0x0
122
+ int id locale 0x0
123
+ int id ltr 0x0
124
+ int id normal 0x0
125
+ int id notification_background 0x0
126
+ int id notification_main_column 0x0
127
+ int id notification_main_column_container 0x0
128
+ int id right_icon 0x0
129
+ int id right_side 0x0
130
+ int id rtl 0x0
131
+ int id tag_accessibility_actions 0x0
132
+ int id tag_accessibility_clickable_spans 0x0
133
+ int id tag_accessibility_heading 0x0
134
+ int id tag_accessibility_pane_title 0x0
135
+ int id tag_on_apply_window_listener 0x0
136
+ int id tag_on_receive_content_listener 0x0
137
+ int id tag_on_receive_content_mime_types 0x0
138
+ int id tag_screen_reader_focusable 0x0
139
+ int id tag_state_description 0x0
140
+ int id tag_transition_group 0x0
141
+ int id tag_unhandled_key_event_manager 0x0
142
+ int id tag_unhandled_key_listeners 0x0
143
+ int id tag_window_insets_animation_callback 0x0
144
+ int id text 0x0
145
+ int id text2 0x0
146
+ int id time 0x0
147
+ int id title 0x0
148
+ int integer status_bar_notification_info_maxnum 0x0
149
+ int layout custom_dialog 0x0
150
+ int layout notification_action 0x0
151
+ int layout notification_action_tombstone 0x0
152
+ int layout notification_template_custom_big 0x0
153
+ int layout notification_template_icon_group 0x0
154
+ int layout notification_template_part_chronometer 0x0
155
+ int layout notification_template_part_time 0x0
156
+ int string status_bar_notification_info_overflow 0x0
157
+ int style LaunchTheme 0x0
158
+ int style TextAppearance_Compat_Notification 0x0
159
+ int style TextAppearance_Compat_Notification_Info 0x0
160
+ int style TextAppearance_Compat_Notification_Line2 0x0
161
+ int style TextAppearance_Compat_Notification_Time 0x0
162
+ int style TextAppearance_Compat_Notification_Title 0x0
163
+ int style Widget_Compat_NotificationActionContainer 0x0
164
+ int style Widget_Compat_NotificationActionText 0x0
165
+ int[] styleable ActivityFilter { 0x0, 0x0 }
166
+ int styleable ActivityFilter_activityAction 0
167
+ int styleable ActivityFilter_activityName 1
168
+ int[] styleable ActivityRule { 0x0 }
169
+ int styleable ActivityRule_alwaysExpand 0
170
+ int[] styleable Capability { 0x0, 0x0 }
171
+ int styleable Capability_queryPatterns 0
172
+ int styleable Capability_shortcutMatchRequired 1
173
+ int[] styleable ColorStateListItem { 0x0, 0x101031f, 0x10101a5 }
174
+ int styleable ColorStateListItem_alpha 0
175
+ int styleable ColorStateListItem_android_alpha 1
176
+ int styleable ColorStateListItem_android_color 2
177
+ int[] styleable FontFamily { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }
178
+ int styleable FontFamily_fontProviderAuthority 0
179
+ int styleable FontFamily_fontProviderCerts 1
180
+ int styleable FontFamily_fontProviderFetchStrategy 2
181
+ int styleable FontFamily_fontProviderFetchTimeout 3
182
+ int styleable FontFamily_fontProviderPackage 4
183
+ int styleable FontFamily_fontProviderQuery 5
184
+ int styleable FontFamily_fontProviderSystemFontFamily 6
185
+ int[] styleable FontFamilyFont { 0x1010532, 0x101053f, 0x1010570, 0x1010533, 0x101056f, 0x0, 0x0, 0x0, 0x0, 0x0 }
186
+ int styleable FontFamilyFont_android_font 0
187
+ int styleable FontFamilyFont_android_fontStyle 1
188
+ int styleable FontFamilyFont_android_fontVariationSettings 2
189
+ int styleable FontFamilyFont_android_fontWeight 3
190
+ int styleable FontFamilyFont_android_ttcIndex 4
191
+ int styleable FontFamilyFont_font 5
192
+ int styleable FontFamilyFont_fontStyle 6
193
+ int styleable FontFamilyFont_fontVariationSettings 7
194
+ int styleable FontFamilyFont_fontWeight 8
195
+ int styleable FontFamilyFont_ttcIndex 9
196
+ int[] styleable GradientColor { 0x101020b, 0x10101a2, 0x10101a3, 0x101019e, 0x1010512, 0x1010513, 0x10101a4, 0x101019d, 0x1010510, 0x1010511, 0x1010201, 0x10101a1 }
197
+ int styleable GradientColor_android_centerColor 0
198
+ int styleable GradientColor_android_centerX 1
199
+ int styleable GradientColor_android_centerY 2
200
+ int styleable GradientColor_android_endColor 3
201
+ int styleable GradientColor_android_endX 4
202
+ int styleable GradientColor_android_endY 5
203
+ int styleable GradientColor_android_gradientRadius 6
204
+ int styleable GradientColor_android_startColor 7
205
+ int styleable GradientColor_android_startX 8
206
+ int styleable GradientColor_android_startY 9
207
+ int styleable GradientColor_android_tileMode 10
208
+ int styleable GradientColor_android_type 11
209
+ int[] styleable GradientColorItem { 0x10101a5, 0x1010514 }
210
+ int styleable GradientColorItem_android_color 0
211
+ int styleable GradientColorItem_android_offset 1
212
+ int[] styleable SplitPairFilter { 0x0, 0x0, 0x0 }
213
+ int styleable SplitPairFilter_primaryActivityName 0
214
+ int styleable SplitPairFilter_secondaryActivityAction 1
215
+ int styleable SplitPairFilter_secondaryActivityName 2
216
+ int[] styleable SplitPairRule { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }
217
+ int styleable SplitPairRule_clearTop 0
218
+ int styleable SplitPairRule_finishPrimaryWithSecondary 1
219
+ int styleable SplitPairRule_finishSecondaryWithPrimary 2
220
+ int styleable SplitPairRule_splitLayoutDirection 3
221
+ int styleable SplitPairRule_splitMinSmallestWidth 4
222
+ int styleable SplitPairRule_splitMinWidth 5
223
+ int styleable SplitPairRule_splitRatio 6
224
+ int[] styleable SplitPlaceholderRule { 0x0, 0x0, 0x0, 0x0, 0x0 }
225
+ int styleable SplitPlaceholderRule_placeholderActivityName 0
226
+ int styleable SplitPlaceholderRule_splitLayoutDirection 1
227
+ int styleable SplitPlaceholderRule_splitMinSmallestWidth 2
228
+ int styleable SplitPlaceholderRule_splitMinWidth 3
229
+ int styleable SplitPlaceholderRule_splitRatio 4
@@ -0,0 +1,12 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!-- Modify this file to customize your launch splash screen -->
3
+ <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
4
+ <item android:drawable="@android:color/white" />
5
+
6
+ <!-- You can insert your own image assets here -->
7
+ <!-- <item>
8
+ <bitmap
9
+ android:gravity="center"
10
+ android:src="@mipmap/launch_image" />
11
+ </item> -->
12
+ </layer-list>
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <resources>
3
+ <style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
4
+
5
+ <item name="android:windowBackground">@drawable/launch_background</item>
6
+ <item name="android:windowIsTranslucent">true</item>
7
+ </style>
8
+ </resources>
@@ -0,0 +1,4 @@
1
+ aarFormatVersion=1.0
2
+ aarMetadataVersion=1.0
3
+ minCompileSdk=1
4
+ minAndroidGradlePluginVersion=1.0.0
@@ -11,6 +11,7 @@ import com.facebook.react.bridge.ReactApplicationContext;
11
11
  import com.facebook.react.bridge.ReactContextBaseJavaModule;
12
12
  import com.facebook.react.bridge.ReactMethod;
13
13
  import com.facebook.react.bridge.WritableMap;
14
+ import com.facebook.react.module.annotations.ReactModule;
14
15
  import com.facebook.react.modules.core.DeviceEventManagerModule;
15
16
 
16
17
  import java.io.BufferedReader;
@@ -44,12 +45,19 @@ import org.json.JSONObject;
44
45
  * - writeCgi(long clientPtr, String cgi, int timeout)
45
46
  * - init(ClientStateListener, ClientCommandListener, ClientReleaseListener)
46
47
  */
48
+ @ReactModule(name = "VStarCam")
47
49
  public class VStarCamModule extends ReactContextBaseJavaModule {
50
+ static {
51
+ Log.d("VStarCamModule", "VStarCamModule class loaded by JVM");
52
+ }
48
53
  private static final String TAG = "VStarCamModule";
49
- private static final String MODULE_NAME = "VStarCam";
54
+ public static final String MODULE_NAME = "VStarCam";
50
55
 
51
56
  // Set to true for verbose logging during development
52
- private static final boolean DEBUG_LOGGING = false;
57
+ private static final boolean DEBUG_LOGGING = true;
58
+
59
+ // Counter for unique internal client IDs
60
+ private static final java.util.concurrent.atomic.AtomicInteger nextClientPtr = new java.util.concurrent.atomic.AtomicInteger(1000);
53
61
 
54
62
  // Helper for conditional debug logging
55
63
  private static void logDebug(String message) {
@@ -207,6 +215,13 @@ public class VStarCamModule extends ReactContextBaseJavaModule {
207
215
  jniApiClass = Class.forName("com.vstarcam.JNIApi");
208
216
  Log.d(TAG, "JNIApi class found: " + jniApiClass.getName());
209
217
 
218
+ // Log JNIApi methods to find hidden functionality (Sound Wave, SmartConfig, etc.)
219
+ Log.d(TAG, "=== JNIApi Methods ===");
220
+ for (Method m : jniApiClass.getDeclaredMethods()) {
221
+ Log.d(TAG, " -> " + m.getName() + "(" + java.util.Arrays.toString(m.getParameterTypes()) + ")");
222
+ }
223
+ Log.d(TAG, "======================");
224
+
210
225
  // Load listener interfaces
211
226
  stateListenerClass = Class.forName("com.vstarcam.app_p2p_api.ClientStateListener");
212
227
  commandListenerClass = Class.forName("com.vstarcam.app_p2p_api.ClientCommandListener");
@@ -448,8 +463,8 @@ public class VStarCamModule extends ReactContextBaseJavaModule {
448
463
  return;
449
464
  }
450
465
 
451
- // Generate our own client ID (hash of deviceId) and store mapping
452
- int ourClientPtr = Math.abs(deviceId.hashCode());
466
+ // Generate a unique internal client ID
467
+ int ourClientPtr = nextClientPtr.getAndIncrement();
453
468
 
454
469
  ClientInfo clientInfo = new ClientInfo();
455
470
  clientInfo.deviceId = deviceId;
@@ -867,4 +882,37 @@ public class VStarCamModule extends ReactContextBaseJavaModule {
867
882
  }
868
883
  promise.resolve(result);
869
884
  }
885
+
886
+ /**
887
+ * Get the current Wi-Fi SSID of the Android device
888
+ */
889
+ @ReactMethod
890
+ public void getWiFiSSID(Promise promise) {
891
+ try {
892
+ android.net.wifi.WifiManager wifiManager = (android.net.wifi.WifiManager)
893
+ reactContext.getApplicationContext().getSystemService(android.content.Context.WIFI_SERVICE);
894
+
895
+ if (wifiManager != null) {
896
+ android.net.wifi.WifiInfo info = wifiManager.getConnectionInfo();
897
+ if (info != null) {
898
+ String ssid = info.getSSID();
899
+ // Android returns SSID with quotes, e.g. "MyNetwork", remove them
900
+ if (ssid != null && ssid.length() > 1 && ssid.startsWith("\"") && ssid.endsWith("\"")) {
901
+ ssid = ssid.substring(1, ssid.length() - 1);
902
+ }
903
+ // Handle "unknown ssid" case
904
+ if ("<unknown ssid>".equals(ssid)) {
905
+ promise.resolve(null);
906
+ } else {
907
+ promise.resolve(ssid);
908
+ }
909
+ return;
910
+ }
911
+ }
912
+ promise.resolve(null);
913
+ } catch (Exception e) {
914
+ Log.e(TAG, "Failed to get WiFi SSID", e);
915
+ promise.resolve(null);
916
+ }
917
+ }
870
918
  }
@@ -15,8 +15,11 @@ public class VStarCamPackage implements ReactPackage {
15
15
  @NonNull
16
16
  @Override
17
17
  public List<NativeModule> createNativeModules(@NonNull ReactApplicationContext reactContext) {
18
+ android.util.Log.d("VStarCamPackage", "Creating Native Modules...");
18
19
  List<NativeModule> modules = new ArrayList<>();
19
20
  modules.add(new VStarCamModule(reactContext));
21
+ modules.add(new WifiModule(reactContext));
22
+ android.util.Log.d("VStarCamPackage", "Added modules: VStarCam and WifiModule");
20
23
  return modules;
21
24
  }
22
25
 
@@ -22,7 +22,7 @@ public class VStarCamVideoView extends FrameLayout
22
22
  private static final String TAG = "VStarCamVideoView";
23
23
 
24
24
  // Set to true for verbose logging during development
25
- private static final boolean DEBUG_LOGGING = false;
25
+ private static final boolean DEBUG_LOGGING = true;
26
26
 
27
27
  private static void logDebug(String message) {
28
28
  if (DEBUG_LOGGING) {
@@ -7,6 +7,7 @@ import androidx.annotation.Nullable;
7
7
 
8
8
  import com.facebook.react.bridge.ReadableArray;
9
9
  import com.facebook.react.common.MapBuilder;
10
+ import com.facebook.react.module.annotations.ReactModule;
10
11
  import com.facebook.react.uimanager.SimpleViewManager;
11
12
  import com.facebook.react.uimanager.ThemedReactContext;
12
13
  import com.facebook.react.uimanager.annotations.ReactProp;
@@ -17,6 +18,7 @@ import java.util.Map;
17
18
  * React Native ViewManager for VStarCamVideoView.
18
19
  * Exposes the native video view as a React component.
19
20
  */
21
+ @ReactModule(name = VStarCamVideoViewManager.REACT_CLASS)
20
22
  public class VStarCamVideoViewManager extends SimpleViewManager<VStarCamVideoView> {
21
23
  public static final String REACT_CLASS = "VStarCamVideoView";
22
24
 
@@ -0,0 +1,155 @@
1
+ package com.reactnativevstarcam;
2
+
3
+ import android.content.Context;
4
+ import android.content.pm.PackageManager;
5
+ import android.net.wifi.ScanResult;
6
+ import android.net.wifi.WifiInfo;
7
+ import android.net.wifi.WifiManager;
8
+ import android.os.Build;
9
+ import android.util.Log;
10
+
11
+ import androidx.annotation.NonNull;
12
+ import androidx.core.app.ActivityCompat;
13
+
14
+ import com.facebook.react.bridge.Arguments;
15
+ import com.facebook.react.bridge.Promise;
16
+ import com.facebook.react.bridge.ReactApplicationContext;
17
+ import com.facebook.react.bridge.ReactContextBaseJavaModule;
18
+ import com.facebook.react.bridge.ReactMethod;
19
+ import com.facebook.react.bridge.WritableArray;
20
+ import com.facebook.react.bridge.WritableMap;
21
+ import com.facebook.react.module.annotations.ReactModule;
22
+
23
+ import java.util.List;
24
+
25
+ @ReactModule(name = "WifiModule")
26
+ public class WifiModule extends ReactContextBaseJavaModule {
27
+ static {
28
+ Log.d("WifiModule", "WifiModule class loaded by JVM");
29
+ }
30
+ public static final String MODULE_NAME = "WifiModule";
31
+ private static final String TAG = "WifiModule";
32
+
33
+ private final ReactApplicationContext reactContext;
34
+
35
+ public WifiModule(ReactApplicationContext reactContext) {
36
+ super(reactContext);
37
+ this.reactContext = reactContext;
38
+ }
39
+
40
+ @NonNull
41
+ @Override
42
+ public String getName() {
43
+ return MODULE_NAME;
44
+ }
45
+
46
+ @ReactMethod
47
+ public void getCurrentSSID(Promise promise) {
48
+ try {
49
+ WifiManager wifiManager = (WifiManager) reactContext.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
50
+ if (wifiManager == null) {
51
+ promise.resolve(null);
52
+ return;
53
+ }
54
+
55
+ WifiInfo info = wifiManager.getConnectionInfo();
56
+ if (info == null) {
57
+ promise.resolve(null);
58
+ return;
59
+ }
60
+
61
+ String ssid = info.getSSID();
62
+ // Android returns SSID with quotes, e.g. "MyNetwork", remove them
63
+ if (ssid != null && ssid.length() > 1 && ssid.startsWith("\"") && ssid.endsWith("\"")) {
64
+ ssid = ssid.substring(1, ssid.length() - 1);
65
+ }
66
+
67
+ // Handle "unknown ssid" case
68
+ if ("<unknown ssid>".equals(ssid)) {
69
+ promise.resolve(null);
70
+ } else {
71
+ promise.resolve(ssid);
72
+ }
73
+ } catch (Exception e) {
74
+ Log.e(TAG, "Failed to get SSID", e);
75
+ promise.resolve(null);
76
+ }
77
+ }
78
+
79
+ @ReactMethod
80
+ public void getCurrentBSSID(Promise promise) {
81
+ try {
82
+ WifiManager wifiManager = (WifiManager) reactContext.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
83
+ if (wifiManager == null) {
84
+ promise.resolve(null);
85
+ return;
86
+ }
87
+
88
+ WifiInfo info = wifiManager.getConnectionInfo();
89
+ if (info == null) {
90
+ promise.resolve(null);
91
+ return;
92
+ }
93
+
94
+ String bssid = info.getBSSID();
95
+ // BSSID is usually a MAC address like 00:00:00:00:00:00
96
+ // The O-KAM format expects it without colons, e.g., "aec9ea203129"
97
+ if (bssid != null) {
98
+ bssid = bssid.replace(":", "").toLowerCase();
99
+ }
100
+
101
+ promise.resolve(bssid);
102
+ } catch (Exception e) {
103
+ Log.e(TAG, "Failed to get BSSID", e);
104
+ promise.resolve(null);
105
+ }
106
+ }
107
+
108
+ @ReactMethod
109
+ public void getWifiList(Promise promise) {
110
+ try {
111
+ WifiManager wifiManager = (WifiManager) reactContext.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
112
+ if (wifiManager == null) {
113
+ promise.reject("WIFI_ERROR", "WifiManager not available");
114
+ return;
115
+ }
116
+
117
+ // Check location permission (required for scanning)
118
+ if (ActivityCompat.checkSelfPermission(reactContext, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
119
+ promise.reject("PERMISSION_ERROR", "Location permission not granted");
120
+ return;
121
+ }
122
+
123
+ // Start scan (deprecated in newer Android but often still works or triggers last known results)
124
+ boolean success = wifiManager.startScan();
125
+ if (!success) {
126
+ Log.w(TAG, "WifiManager.startScan() returned false - limits may apply");
127
+ // Attempt to get results anyway as they might be cached
128
+ }
129
+
130
+ List<ScanResult> results = wifiManager.getScanResults();
131
+ WritableArray jsonArray = Arguments.createArray();
132
+
133
+ for (ScanResult result : results) {
134
+ // Filter out empty SSIDs
135
+ if (result.SSID != null && !result.SSID.isEmpty()) {
136
+ WritableMap map = Arguments.createMap();
137
+ map.putString("SSID", result.SSID);
138
+ map.putString("BSSID", result.BSSID);
139
+ map.putInt("level", result.level); // Signal strength
140
+ map.putInt("frequency", result.frequency);
141
+ // Simple logic to guess capabilities partial string
142
+ map.putString("capabilities", result.capabilities);
143
+
144
+ jsonArray.pushMap(map);
145
+ }
146
+ }
147
+
148
+ promise.resolve(jsonArray);
149
+
150
+ } catch (Exception e) {
151
+ Log.e(TAG, "Failed to scan Wifi", e);
152
+ promise.reject("SCAN_ERROR", e.getMessage());
153
+ }
154
+ }
155
+ }
@@ -0,0 +1,28 @@
1
+ package com.reactnativevstarcam;
2
+
3
+ import androidx.annotation.NonNull;
4
+
5
+ import com.facebook.react.ReactPackage;
6
+ import com.facebook.react.bridge.NativeModule;
7
+ import com.facebook.react.bridge.ReactApplicationContext;
8
+ import com.facebook.react.uimanager.ViewManager;
9
+
10
+ import java.util.ArrayList;
11
+ import java.util.Collections;
12
+ import java.util.List;
13
+
14
+ public class WifiPackage implements ReactPackage {
15
+ @NonNull
16
+ @Override
17
+ public List<NativeModule> createNativeModules(@NonNull ReactApplicationContext reactContext) {
18
+ List<NativeModule> modules = new ArrayList<>();
19
+ modules.add(new WifiModule(reactContext));
20
+ return modules;
21
+ }
22
+
23
+ @NonNull
24
+ @Override
25
+ public List<ViewManager> createViewManagers(@NonNull ReactApplicationContext reactContext) {
26
+ return Collections.emptyList();
27
+ }
28
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bits-innovate/react-native-vstarcam",
3
- "version": "1.0.25",
3
+ "version": "1.0.27",
4
4
  "description": "React Native bridge for VStarCam P2P SDK",
5
5
  "main": "src/index.ts",
6
6
  "types": "src/index.ts",
package/src/index.ts CHANGED
@@ -50,10 +50,17 @@ export interface VStarCamVideoViewProps {
50
50
  * />
51
51
  * ```
52
52
  */
53
- export const VStarCamVideoView =
54
- Platform.OS === "android"
55
- ? requireNativeComponent<VStarCamVideoViewProps>("VStarCamVideoView")
56
- : () => null; // iOS not implemented yet
53
+ // Video View Component registration with safety check
54
+ let VStarCamVideoViewNative = null;
55
+ if (Platform.OS === "android") {
56
+ try {
57
+ VStarCamVideoViewNative = requireNativeComponent<VStarCamVideoViewProps>("VStarCamVideoView");
58
+ } catch (e) {
59
+ console.warn("VStarCamVideoView could not be registered:", e.message);
60
+ }
61
+ }
62
+
63
+ export const VStarCamVideoView = VStarCamVideoViewNative || (() => null);
57
64
 
58
65
  const LINKING_ERROR =
59
66
  `The package 'react-native-vstarcam' doesn't seem to be linked. Make sure: \n\n` +
@@ -61,16 +68,30 @@ const LINKING_ERROR =
61
68
  "- You rebuilt the app after installing the package\n" +
62
69
  "- You are not using Expo Go (requires development build)";
63
70
 
71
+ // Diagnostic log for native modules - using warn to make it stand out!
72
+ console.warn("[VStarCam] JS Initialization: Available NativeModules keys:", Object.keys(NativeModules));
73
+ console.warn("[VStarCam] Full NativeModules scan:", {
74
+ VStarCam: !!NativeModules.VStarCam,
75
+ WifiModule: !!NativeModules.WifiModule,
76
+ VStarCamModule: !!NativeModules.VStarCamModule
77
+ });
78
+
64
79
  const VStarCamModule = NativeModules.VStarCam
65
80
  ? NativeModules.VStarCam
66
81
  : new Proxy(
67
- {},
68
- {
69
- get() {
70
- throw new Error(LINKING_ERROR);
71
- },
72
- }
73
- );
82
+ {},
83
+ {
84
+ get(target, prop) {
85
+ // Don't throw for internal JS/React checks
86
+ if (prop === '$$typeof' || prop === 'constructor' || typeof prop === 'symbol') {
87
+ return undefined;
88
+ }
89
+ // Log exactly what's being accessed when it fails
90
+ console.error(`[VStarCam] Attempted to access property "${String(prop)}" but the native module is missing.`);
91
+ throw new Error(LINKING_ERROR);
92
+ },
93
+ }
94
+ );
74
95
 
75
96
  // Connection states
76
97
  export enum ConnectionState {
@@ -515,6 +536,21 @@ class VStarCamClient {
515
536
  this.videoListeners.delete(listener);
516
537
  }
517
538
 
539
+ /**
540
+ * Get the current Wi-Fi SSID from the phone (Android only)
541
+ */
542
+ async getPhoneSSID(): Promise<string | null> {
543
+ if (Platform.OS === 'android') {
544
+ try {
545
+ return await VStarCamModule.getWiFiSSID();
546
+ } catch (e) {
547
+ console.warn("Failed to get phone SSID:", e);
548
+ return null;
549
+ }
550
+ }
551
+ return null;
552
+ }
553
+
518
554
  get isConnected(): boolean {
519
555
  return this.clientPtr > 0;
520
556
  }