ilabs-flir 2.2.27 → 2.2.30
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.
|
@@ -133,20 +133,25 @@ public class FlirSdkManager {
|
|
|
133
133
|
}
|
|
134
134
|
|
|
135
135
|
public void stopScan() {
|
|
136
|
+
if (!isScanning) return;
|
|
137
|
+
|
|
138
|
+
// Use a temporary flag to prevent concurrent stop calls
|
|
139
|
+
isScanning = false;
|
|
140
|
+
|
|
136
141
|
executor.execute(() -> {
|
|
137
|
-
if (!isScanning)
|
|
138
|
-
return;
|
|
139
142
|
try {
|
|
143
|
+
Log.d(TAG, "Stopping discovery...");
|
|
140
144
|
DiscoveryFactory.getInstance().stop(
|
|
141
145
|
CommunicationInterface.EMULATOR,
|
|
142
146
|
CommunicationInterface.USB,
|
|
143
147
|
CommunicationInterface.NETWORK,
|
|
144
148
|
CommunicationInterface.FLIR_ONE_WIRELESS);
|
|
149
|
+
Log.d(TAG, "Discovery stopped successfully");
|
|
145
150
|
} catch (Exception e) {
|
|
146
|
-
|
|
151
|
+
// This is where the 'Receiver not registered' usually happens in SDK internals.
|
|
152
|
+
// We catch it silently as it means the SDK already cleaned up or is in a weird state.
|
|
153
|
+
Log.w(TAG, "Stop scan warning (internal SDK): " + e.getMessage());
|
|
147
154
|
}
|
|
148
|
-
isScanning = false;
|
|
149
|
-
Log.d(TAG, "Discovery stopped");
|
|
150
155
|
});
|
|
151
156
|
}
|
|
152
157
|
|
|
@@ -179,12 +184,13 @@ public class FlirSdkManager {
|
|
|
179
184
|
Log.d(TAG, "Connecting to: " + identity.deviceId);
|
|
180
185
|
camera = new Camera();
|
|
181
186
|
|
|
182
|
-
// ── Authenticate for NETWORK cameras (required by FLIR SDK) ──
|
|
187
|
+
// ── Authenticate for NETWORK/WIRELESS cameras (required by FLIR SDK) ──
|
|
183
188
|
// Matches the official NetworkCamera sample app pattern.
|
|
184
|
-
// The FLIR One Edge Pro is a network camera and will reject
|
|
189
|
+
// The FLIR One Edge Pro is a network/wireless camera and will reject
|
|
185
190
|
// connections without prior authentication + trust approval.
|
|
186
|
-
if (identity.communicationInterface == CommunicationInterface.NETWORK
|
|
187
|
-
|
|
191
|
+
if (identity.communicationInterface == CommunicationInterface.NETWORK ||
|
|
192
|
+
identity.communicationInterface == CommunicationInterface.FLIR_ONE_WIRELESS) {
|
|
193
|
+
Log.d(TAG, "Network/Wireless camera detected — authenticating...");
|
|
188
194
|
|
|
189
195
|
// Use a persistent application name (workaround for camera bug
|
|
190
196
|
// where re-auth with a different name conflicts). Same pattern
|
|
@@ -323,26 +329,28 @@ public class FlirSdkManager {
|
|
|
323
329
|
// Start stream with simple callback (matches sample app)
|
|
324
330
|
thermalStream.start(
|
|
325
331
|
unused -> {
|
|
326
|
-
//
|
|
332
|
+
// CRITICAL: Frame processing must happen in a controlled way.
|
|
333
|
+
// For Android, we perform streamer.update() on the callback thread
|
|
334
|
+
// to ensure the native frame reference remains valid.
|
|
327
335
|
if (isProcessingFrame.compareAndSet(false, true)) {
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
336
|
+
try {
|
|
337
|
+
if (streamer != null && activeStream != null) {
|
|
338
|
+
streamer.update();
|
|
339
|
+
|
|
340
|
+
// createBitmap is safe to do here or in executor
|
|
341
|
+
Bitmap bitmap = BitmapAndroid.createBitmap(streamer.getImage()).getBitMap();
|
|
342
|
+
if (bitmap != null) {
|
|
343
|
+
latestBitmap = bitmap;
|
|
344
|
+
if (listener != null) {
|
|
345
|
+
listener.onFrame(bitmap);
|
|
338
346
|
}
|
|
339
347
|
}
|
|
340
|
-
} catch (Exception e) {
|
|
341
|
-
Log.e(TAG, "Frame error", e);
|
|
342
|
-
} finally {
|
|
343
|
-
isProcessingFrame.set(false);
|
|
344
348
|
}
|
|
345
|
-
})
|
|
349
|
+
} catch (Exception e) {
|
|
350
|
+
Log.e(TAG, "Frame processing error", e);
|
|
351
|
+
} finally {
|
|
352
|
+
isProcessingFrame.set(false);
|
|
353
|
+
}
|
|
346
354
|
}
|
|
347
355
|
},
|
|
348
356
|
error -> {
|
package/app.plugin.js
CHANGED
|
@@ -178,11 +178,19 @@ const withFlirInfoPlist = (config, props = {}) => {
|
|
|
178
178
|
|
|
179
179
|
/**
|
|
180
180
|
* Adds FLIR-specific entitlements for iOS
|
|
181
|
+
* Required for FLIR One Edge Pro and network discovery
|
|
181
182
|
*/
|
|
182
183
|
const withFlirEntitlements = (config) => {
|
|
183
184
|
return withEntitlementsPlist(config, (config) => {
|
|
184
|
-
//
|
|
185
|
+
// 1. Access Wi-Fi Information
|
|
185
186
|
config.modResults['com.apple.developer.networking.wifi-info'] = true;
|
|
187
|
+
|
|
188
|
+
// 2. Hotspot Configuration (Required for FLIR Edge)
|
|
189
|
+
config.modResults['com.apple.developer.networking.HotspotConfiguration'] = true;
|
|
190
|
+
|
|
191
|
+
// 3. Wireless Accessory Configuration (Required for FLIR Edge)
|
|
192
|
+
config.modResults['com.apple.external-accessory.wireless-configuration'] = true;
|
|
193
|
+
|
|
186
194
|
return config;
|
|
187
195
|
});
|
|
188
196
|
};
|
|
@@ -247,6 +255,19 @@ const withFlirAndroidManifest = (config, props = {}) => {
|
|
|
247
255
|
|
|
248
256
|
// WiFi feature for network cameras
|
|
249
257
|
addFeature('android.hardware.wifi', false);
|
|
258
|
+
|
|
259
|
+
// OpenGL ES 3.0 requirement (mandatory for Atlas SDK rendering)
|
|
260
|
+
const hasOpenGL = mainApplication['uses-feature'].some(
|
|
261
|
+
(f) => f.$?.['android:glEsVersion'] === '0x00030000'
|
|
262
|
+
);
|
|
263
|
+
if (!hasOpenGL) {
|
|
264
|
+
mainApplication['uses-feature'].push({
|
|
265
|
+
$: {
|
|
266
|
+
'android:glEsVersion': '0x00030000',
|
|
267
|
+
'android:required': 'true',
|
|
268
|
+
},
|
|
269
|
+
});
|
|
270
|
+
}
|
|
250
271
|
|
|
251
272
|
// Network permissions (always added on Android)
|
|
252
273
|
addPermission('android.permission.INTERNET');
|
|
@@ -255,13 +276,49 @@ const withFlirAndroidManifest = (config, props = {}) => {
|
|
|
255
276
|
addPermission('android.permission.CHANGE_WIFI_STATE');
|
|
256
277
|
addPermission('android.permission.CHANGE_NETWORK_STATE');
|
|
257
278
|
addPermission('android.permission.CHANGE_WIFI_MULTICAST_STATE');
|
|
279
|
+
|
|
280
|
+
// Required for Wi-Fi discovery on Android 13+ (API 33)
|
|
258
281
|
addPermission('android.permission.NEARBY_WIFI_DEVICES');
|
|
282
|
+
|
|
259
283
|
addPermission('android.permission.BLUETOOTH');
|
|
260
284
|
addPermission('android.permission.BLUETOOTH_ADMIN');
|
|
261
285
|
addPermission('android.permission.BLUETOOTH_CONNECT');
|
|
262
286
|
addPermission('android.permission.BLUETOOTH_SCAN');
|
|
263
287
|
addPermission('android.permission.ACCESS_FINE_LOCATION'); // Required for BLE scanning
|
|
264
288
|
|
|
289
|
+
// =========================================================================
|
|
290
|
+
// USB AUTO-LAUNCH CONFIGURATION
|
|
291
|
+
// Allows the app to open automatically when a FLIR USB device is attached.
|
|
292
|
+
// =========================================================================
|
|
293
|
+
const activity = mainApplication.application[0].activity[0];
|
|
294
|
+
|
|
295
|
+
// 1. Add intent filter for USB_DEVICE_ATTACHED
|
|
296
|
+
if (!activity['intent-filter']) activity['intent-filter'] = [];
|
|
297
|
+
const hasUsbIntent = activity['intent-filter'].some(filter =>
|
|
298
|
+
filter.action?.some(action => action.$['android:name'] === 'android.hardware.usb.action.USB_DEVICE_ATTACHED')
|
|
299
|
+
);
|
|
300
|
+
|
|
301
|
+
if (!hasUsbIntent) {
|
|
302
|
+
activity['intent-filter'].push({
|
|
303
|
+
action: [{ $: { 'android:name': 'android.hardware.usb.action.USB_DEVICE_ATTACHED' } }]
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// 2. Add meta-data pointing to the flir_usb_device_filter.xml
|
|
308
|
+
if (!activity['meta-data']) activity['meta-data'] = [];
|
|
309
|
+
const hasUsbMetadata = activity['meta-data'].some(meta =>
|
|
310
|
+
meta.$['android:name'] === 'android.hardware.usb.action.USB_DEVICE_ATTACHED'
|
|
311
|
+
);
|
|
312
|
+
|
|
313
|
+
if (!hasUsbMetadata) {
|
|
314
|
+
activity['meta-data'].push({
|
|
315
|
+
$: {
|
|
316
|
+
'android:name': 'android.hardware.usb.action.USB_DEVICE_ATTACHED',
|
|
317
|
+
'android:resource': '@xml/flir_usb_device_filter'
|
|
318
|
+
}
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
|
|
265
322
|
return config;
|
|
266
323
|
});
|
|
267
324
|
};
|
|
@@ -284,18 +341,67 @@ const withFlirManifest = (config) => {
|
|
|
284
341
|
};
|
|
285
342
|
|
|
286
343
|
/**
|
|
287
|
-
* Copies sdk-manifest.json to Android assets
|
|
344
|
+
* Copies sdk-manifest.json to Android assets AND creates the USB filter XML
|
|
288
345
|
*/
|
|
289
346
|
const withFlirAndroidAssets = (config) => {
|
|
290
347
|
return withDangerousMod(config, [
|
|
291
348
|
'android',
|
|
292
349
|
async (config) => {
|
|
293
|
-
const
|
|
294
|
-
const
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
350
|
+
const projectRoot = config.modRequest.projectRoot;
|
|
351
|
+
const platformRoot = config.modRequest.platformProjectRoot;
|
|
352
|
+
|
|
353
|
+
// 1. Copy sdk-manifest.json
|
|
354
|
+
const manifestSrc = path.join(__dirname, 'sdk-manifest.json');
|
|
355
|
+
const manifestDst = path.join(platformRoot, 'app/src/main/assets/sdk-manifest.json');
|
|
356
|
+
if (fs.existsSync(manifestSrc)) {
|
|
357
|
+
fs.mkdirSync(path.dirname(manifestDst), { recursive: true });
|
|
358
|
+
fs.copyFileSync(manifestSrc, manifestDst);
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
// 2. Create flir_usb_device_filter.xml (Required for auto-launch)
|
|
362
|
+
const usbFilterXml = `<?xml version="1.0" encoding="utf-8"?>
|
|
363
|
+
<resources>
|
|
364
|
+
<!-- FLIR Vendor ID (2507) -->
|
|
365
|
+
<usb-device vendor-id="2507" />
|
|
366
|
+
</resources>`;
|
|
367
|
+
|
|
368
|
+
const xmlDst = path.join(platformRoot, 'app/src/main/res/xml/flir_usb_device_filter.xml');
|
|
369
|
+
fs.mkdirSync(path.dirname(xmlDst), { recursive: true });
|
|
370
|
+
fs.writeFileSync(xmlDst, usbFilterXml);
|
|
371
|
+
|
|
372
|
+
return config;
|
|
373
|
+
},
|
|
374
|
+
]);
|
|
375
|
+
};
|
|
376
|
+
|
|
377
|
+
/**
|
|
378
|
+
* Patch Xcode project settings (Bitcode, Linker Flags)
|
|
379
|
+
*/
|
|
380
|
+
const withFlirXcodeSettings = (config) => {
|
|
381
|
+
return withDangerousMod(config, [
|
|
382
|
+
'ios',
|
|
383
|
+
async (config) => {
|
|
384
|
+
const { modRequest } = config;
|
|
385
|
+
const xcodeProjectPath = path.join(modRequest.platformProjectRoot, 'ThermalCameraFx.xcodeproj/project.pbxproj');
|
|
386
|
+
|
|
387
|
+
if (!fs.existsSync(xcodeProjectPath)) return config;
|
|
388
|
+
|
|
389
|
+
let pbxproj = fs.readFileSync(xcodeProjectPath, 'utf8');
|
|
390
|
+
|
|
391
|
+
// 1. Disable Bitcode (Required for FLIR SDK)
|
|
392
|
+
// Matches: ENABLE_BITCODE = YES; -> ENABLE_BITCODE = NO;
|
|
393
|
+
pbxproj = pbxproj.replace(/ENABLE_BITCODE = YES/g, 'ENABLE_BITCODE = NO');
|
|
394
|
+
|
|
395
|
+
// 2. Add -ObjC to OTHER_LDFLAGS if not present
|
|
396
|
+
// This is a bit tricky with regex, so we look for the OTHER_LDFLAGS line
|
|
397
|
+
if (!pbxproj.includes('"-ObjC"') && !pbxproj.includes('-ObjC')) {
|
|
398
|
+
pbxproj = pbxproj.replace(
|
|
399
|
+
/OTHER_LDFLAGS = \(\n/g,
|
|
400
|
+
'OTHER_LDFLAGS = (\n\t\t\t\t"-ObjC",\n'
|
|
401
|
+
);
|
|
298
402
|
}
|
|
403
|
+
|
|
404
|
+
fs.writeFileSync(xcodeProjectPath, pbxproj, 'utf8');
|
|
299
405
|
return config;
|
|
300
406
|
},
|
|
301
407
|
]);
|
|
@@ -368,6 +474,7 @@ const withFlirThermalSDK = (config, props = {}) => {
|
|
|
368
474
|
// Apply iOS modifications
|
|
369
475
|
config = withFlirInfoPlist(config, props);
|
|
370
476
|
config = withFlirEntitlements(config);
|
|
477
|
+
config = withFlirXcodeSettings(config);
|
|
371
478
|
config = withFlirManifest(config);
|
|
372
479
|
|
|
373
480
|
// Apply Android modifications
|
|
@@ -170,8 +170,8 @@ import ThermalSDK
|
|
|
170
170
|
// ── AUTHENTICATE for network cameras ──
|
|
171
171
|
// Official FLIR CameraConnector sample checks .generic camera type,
|
|
172
172
|
// but FLIR One Edge Pro over network may report a different type.
|
|
173
|
-
// Check BOTH: camera type == .generic OR interface contains .network
|
|
174
|
-
let needsAuth = (camType == .generic) || iface.contains(.network)
|
|
173
|
+
// Check BOTH: camera type == .generic OR interface contains .network/.flirOneWireless
|
|
174
|
+
let needsAuth = (camType == .generic) || iface.contains(.network) || iface.contains(.flirOneWireless)
|
|
175
175
|
|
|
176
176
|
if needsAuth {
|
|
177
177
|
NSLog("[FlirManager] Network camera detected — authenticating...")
|
package/package.json
CHANGED
|
@@ -6,8 +6,8 @@ const fs = require('fs');
|
|
|
6
6
|
const path = require('path');
|
|
7
7
|
const { execSync } = require('child_process');
|
|
8
8
|
|
|
9
|
-
let IOS_URL = 'https://github.com/PraveenOjha/flir-sdk-binaries/releases/download/v1.0.
|
|
10
|
-
let ANDROID_URL = 'https://github.com/PraveenOjha/flir-sdk-binaries/releases/download/v1.0.
|
|
9
|
+
let IOS_URL = 'https://github.com/PraveenOjha/flir-sdk-binaries/releases/download/v1.0.2/ios.zip';
|
|
10
|
+
let ANDROID_URL = 'https://github.com/PraveenOjha/flir-sdk-binaries/releases/download/v1.0.2/android.zip';
|
|
11
11
|
// Manifest override
|
|
12
12
|
try {
|
|
13
13
|
const manifest = require(path.join(__dirname, '..', 'sdk-manifest.json'));
|
package/sdk-manifest.json
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": "2.0.0",
|
|
3
3
|
"sdkVersion": "5.0.0",
|
|
4
4
|
"ios": {
|
|
5
|
-
"downloadUrl": "https://github.com/PraveenOjha/flir-sdk-binaries/releases/download/v1.0.
|
|
5
|
+
"downloadUrl": "https://github.com/PraveenOjha/flir-sdk-binaries/releases/download/v1.0.2/ios.zip",
|
|
6
6
|
"directDownload": {
|
|
7
|
-
"downloadUrl": "https://github.com/PraveenOjha/flir-sdk-binaries/releases/download/v1.0.
|
|
7
|
+
"downloadUrl": "https://github.com/PraveenOjha/flir-sdk-binaries/releases/download/v1.0.2/ios.zip",
|
|
8
8
|
"sha256": "",
|
|
9
9
|
"sizeBytes": 0
|
|
10
10
|
},
|
|
@@ -14,14 +14,14 @@
|
|
|
14
14
|
"xcframeworks": [
|
|
15
15
|
"ThermalSDK.xcframework",
|
|
16
16
|
"MeterLink.xcframework",
|
|
17
|
-
"libavcodec.
|
|
18
|
-
"libavdevice.
|
|
19
|
-
"libavfilter.
|
|
20
|
-
"libavformat.
|
|
21
|
-
"libavutil.
|
|
17
|
+
"libavcodec.62.dylib.xcframework",
|
|
18
|
+
"libavdevice.62.dylib.xcframework",
|
|
19
|
+
"libavfilter.11.dylib.xcframework",
|
|
20
|
+
"libavformat.62.dylib.xcframework",
|
|
21
|
+
"libavutil.60.dylib.xcframework",
|
|
22
22
|
"liblive666.dylib.xcframework",
|
|
23
|
-
"libswresample.
|
|
24
|
-
"libswscale.
|
|
23
|
+
"libswresample.6.dylib.xcframework",
|
|
24
|
+
"libswscale.9.dylib.xcframework"
|
|
25
25
|
],
|
|
26
26
|
"minDeploymentTarget": "13.0",
|
|
27
27
|
"supportedArchitectures": [
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"android": {
|
|
33
33
|
|
|
34
34
|
"directDownload": {
|
|
35
|
-
"downloadUrl": "https://github.com/PraveenOjha/flir-sdk-binaries/releases/download/v1.0.
|
|
35
|
+
"downloadUrl": "https://github.com/PraveenOjha/flir-sdk-binaries/releases/download/v1.0.2/android.zip",
|
|
36
36
|
"sha256": "",
|
|
37
37
|
"sizeBytes": 0
|
|
38
38
|
}
|