FLIR Atlas Android SDK 2.4.0

FLIR Atlas Android SDK documentation.

Your way through Thermal Imaging.

The FLIR Atlas Android SDK is an environment meant to simplify work with FLIR Thermal cameras, Test And Measurement instruments and Thermal images. It provides means to control FLIR devices and access data stored on them. It allows to manage Thermal images taken by FLIR Thermal cameras, view and edit them. It is a single library giving developers a way through Thermal Imagining World.

The FLIR Atlas Android SDK allows to manage all FLIR devices able to connect to the Android phone or tablet. It simplifies creating a process, where these devices are used in a daily work. Developers can build their own applications taking advantage of the FLIR Atlas Android SDK to control them. These personalized applications would have full access to the FLIR devices and provide only what is needed to the User. Moreover any image taken by FLIR Thermal camera can be processed by the FLIR Atlas Android SDK to achieve the best result for specific user scenario. The image can be displayed or modified depending on particular needs. The final images can be used to create any kind of report.

The FLIR Atlas Android SDK is provided in a form of a binary file (AAR library). The file has to be put in defined directory structure - see section "Usage of FLIR Atlas Android SDK". The AAR library provides actual functionality to handle Thermal cameras and images all encapsulated as Java classes for easy usage.

Quick Start Guide for FLIR Atlas Android SDK Developers

In order to support Developers new to FLIR Atlas Android SDK, we prepared a quick start guide document, which can be found here.

Migration from FLIR One Android SDK to FLIR Atlas Android SDK

In order to make migration from FLIR One Android SDK to it's successor FLIR Atlas Android SDK easier, we prepared a migration guide document, which can be found here.

Requirements of FLIR Atlas Android SDK

FLIR Atlas Android SDK was prepared for minimum Android version 9.0 (API 28). It is required to use this Android version as an Android min SDK version: android:minSdkVersion="28".

FLIR Atlas Android SDK internally wraps C++ libraries, which were compiled for ARM and x86 architectures using armeabi-v7a, arm64-v8a, x86_64 instruction sets. Other architectures are unsupported. Running it on unsupported devices will result in undefined behavior and likely crashes.

FLIR Atlas Android SDK uses OpenGL ES 3.0 to render the images. Make sure it is available on the target device. If the application using SDK is launched on unsupported device, it might not display any image or become unstable.

To ensure these requirements are met certain entries has to be added in your IDE project settings. Under Android Studio IDE:
a) AndroidManifest.xml file (see here):
- <uses-sdk> tag used to determine minimum and target Android SDK version; NOTE: it is overridden by the information from build.gradle file from "defaultConfig" section

        <uses-sdk
            android:minSdkVersion="28"
            android:targetSdkVersion="34" />
        
- <uses-feature> tag used to inform about OpenGL version required
        <uses-feature
            android:glEsVersion="0x00030000"
            android:required="true" />
        
- <uses-permission> tag allowing the FLIR Atlas Android SDK to use certain system features, see "Usage of FLIR Atlas Android SDK" section below for details. Example:
        <uses-permission
            android:name="android.permission.BLUETOOTH" />
        
b) build.gradle file (see here):
- defaultConfig section used to define basic project properties; NOTE: it overrides the information from AndroidManifest.xml file
    defaultConfig {
        applicationId "com.flir.thermalsdk.testapp.androidstudio"
        minSdkVersion 28
        targetSdkVersion 34
        versionCode 1
        versionName "1.0"
    }
    
- repositories section used to request library search in local 'libs' folder; without this section the gradle won't be able to find the AAR library even if it will be in place; NOTE: 'repositories' section should be put directly inside 'android' section
    repositories {
        flatDir {
            dirs 'libs'
        }
    }
    
- dependencies section describes libraries and other dependencies required for the project (should be added automatically by the IDE)
    dependencies {
        implementation fileTree(dir: 'libs', include: ['*.jar'])
        implementation(group: "", version: "", name: 'androidsdk-release', ext: 'aar')
        implementation(group: "", version: "", name: 'thermalsdk-release', ext: 'aar')
                // ... other dependencies
    }
    

Usage of FLIR Atlas Android SDK

In order to link the deliverables to the project, AAR files must be put in the right place in the project's structure.
It is suggested to use Android Studio IDE, but you can use any other IDE, provided that it allows to link AAR library to the project (i.e. IntelliJ IDEA, Eclipse, Visual Studio with appropriate plugins).

IMPORTANT: It is mandatory to initialize the SDK in the application code before using any functionality.
To achieve that you have to call ThermalSdkAndroid.init(android.content.Context context) method before any other call to FLIR Atlas Android SDK methods. In example put that line of code in your Activity.onCreate() method.

See "Troubleshooting" section if you encounter any problem. Solution might be already there. Otherwise feel free to contact us.

Permissions required by FLIR Atlas Android SDK

Android permissions are required to use certain features of the SDK. Permissions should be put in your application's AndroidManifest.xml file and also granted in the runtime.
Some permissions are required above or below certain Android versions, so you may need to utilize additional conditional check against Build.VERSION.SDK_INT constant.
In AndroidManifest.xml you may need to use "android:maxSdkVersion" property in your "uses-permission" tag.
Example for requesting permissions in Kotlin:

class PermissionHandler(private val activity: Activity) {

    companion object {
        const val PERMISSIONS_REQUEST_CODE = 7 // use a random value, but keep in mind that we can only use lower 8 bits for requestCode (so this value must be less than 0xFF)
    }

    /**
     * Check if we have Bluetooth permission, if not it shows a dialog requesting the permission and "onRequestPermissionsResult(..)" is called with the result
     *
     * @return true if all permissions were granted otherwise false
     */
    fun checkForRequiredPermissions(): Boolean {
        val permissionsList: MutableList<String> = mutableListOf()
        // BLE discovery
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.R) {
            permissionsList.add(Manifest.permission.BLUETOOTH_SCAN)
        } else {
            permissionsList.add(Manifest.permission.BLUETOOTH)
            permissionsList.add(Manifest.permission.BLUETOOTH_ADMIN)
            permissionsList.add(Manifest.permission.ACCESS_COARSE_LOCATION)
            permissionsList.add(Manifest.permission.ACCESS_FINE_LOCATION)
        }
        // WIFI auto connect
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            permissionsList.add(Manifest.permission.NEARBY_WIFI_DEVICES)
        }
        // WIFI set preferred network
        permissionsList.add(Manifest.permission.CHANGE_WIFI_STATE)
        permissionsList.add(Manifest.permission.ACCESS_NETWORK_STATE)
        permissionsList.add(Manifest.permission.ACCESS_WIFI_STATE)
        // direct connect to camera based on IP address
        permissionsList.add(Manifest.permission.INTERNET)

        return checkForPermissions(permissionsList.toTypedArray())
    }

    /**
     * Check if we have permissions, if not it shows a dialog requesting the permission and "onRequestPermissionsResult(..)" is called with the result
     *
     * @return true if all permissions were granted otherwise false
     */
    private fun checkForPermissions(permissions: Array<String>): Boolean {
        var allGranted = true
        for (permission in permissions) {
            if (!checkPermission(permission)) {
                allGranted = false
            }
        }
        if (!allGranted) {
            requestPermissions(permissions)
        }
        return allGranted
    }

    /**
     * Request permission - show a dialog if the permission was not already granted
     */
    private fun requestPermissions(permissions: Array<String>) {
        if (permissions.isNotEmpty()) {
            val permissionRationale = ActivityCompat.shouldShowRequestPermissionRationale(
                activity, permissions[0]
            )
            if (!permissionRationale) {
                ActivityCompat.requestPermissions(activity, permissions, PERMISSIONS_REQUEST_CODE)
            }
        }
    }

    /**
     * Check whether specified permission was granted.
     */
    private fun checkPermission(permission: String): Boolean {
        return ActivityCompat.checkSelfPermission(activity, permission) == PackageManager.PERMISSION_GRANTED
    }
}
    
Example for AndroidManifest.xml:
    <uses-feature
        android:name="android.hardware.bluetooth_le"
        android:required="true" />

    <!-- Request legacy Bluetooth permissions on older devices. -->
    <uses-permission android:name="android.permission.BLUETOOTH"
                     android:maxSdkVersion="30"/>
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"
                     android:maxSdkVersion="30"/>
    <!-- Bluetooth discovery prior to API 31 require FINE location -->
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"
                     android:maxSdkVersion="30"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"
                     android:maxSdkVersion="30"/>

    <!-- Needed only if your app looks for Bluetooth devices.
        If your app doesn't use Bluetooth scan results to derive physical
        location information, you can strongly assert that your app
        doesn't derive physical location. -->
    <uses-permission android:name="android.permission.BLUETOOTH_SCAN"
        android:usesPermissionFlags="neverForLocation"
        tools:targetApi="S" />
    
Best practice is to refer to the sample app's AndroidManifest.xml and code in order to get familiar with the required permissions for certain SDK features.
In general, the permissions can be divided into a few groups (but refer to a particular sample app for details):

1. Initialize SDK, open, edit, save files - when using app-private space no additional permissions are needed.
1.1 However if you plan to access public storage, depending on the Android target API level, you may require READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE permissions and some extra code to safely access public space -
mostly because on Android 10, apps in the scoped storage environment cannot access files using the file path.
When targeting API level 33 the READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE permissions are ignored and not granted to the app. In consequence app will not see the content of these public dirs as it used to before targeting API 33.
Possible ways to access files may include usage of Storage Access Framework (SAF), Media Store API, Scoped Storage (Android 11 and above).
For details you may refer to documentation and learning resources:
Storage
Storage blog

2. Discover devices over Wifi network, connect to devices, import images, control device remotely:
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    
Runtime permissions:
    Manifest.permission.ACCESS_WIFI_STATE,
    Manifest.permission.CHANGE_WIFI_MULTICAST_STATE,
    Manifest.permission.CHANGE_WIFI_STATE,
    Manifest.permission.ACCESS_NETWORK_STATE,
    Manifest.permission.CHANGE_NETWORK_STATE,
    Manifest.permission.INTERNET,
    Manifest.permission.ACCESS_COARSE_LOCATION,
    Manifest.permission.NEARBY_WIFI_DEVICES // when targeting Android API level 33 or later
    
3. Discover and connect to devices via Bluetooth:
    <uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.BLUETOOTH_SCAN" /> // when targeting Android API level 31 or later
    
Runtime permissions:
    Manifest.permission.BLUETOOTH,
    Manifest.permission.BLUETOOTH_ADMIN,
    Manifest.permission.ACCESS_COARSE_LOCATION,
    Manifest.permission.ACCESS_FINE_LOCATION,
    Manifest.permission.BLUETOOTH_SCAN // when targeting Android API level 31 or later
    
4. Work with USB cameras:
    // adds support for USB OTG cameras (in particular FLIR ONE camera)
    <uses-feature android:name="android.hardware.usb.host" android:required="true" />
    
As an option for USB discovery you may register for specific intent filter in your Activity in Manifest.xml file. Adding this section to the Manifest.xml file will allow the user to open your application automatically when FLIR USB camera is attached to the Android phone/tablet using OTG cable.
    <activity android:name="com.flir.thermalsdk.discovery.SampleActivity">
    <intent-filter>
    <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
    </intent-filter>
    <meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
        android:resource="@xml/flir_usb_device_filter" />
    </activity>
    
Note the flir_usb_device_filter.xml mentioned in 'meta-data' tag file which defines the allowed FLIR devices. The vendor-id="2507" identifies a FLIR device. The file is located under 'res/xml' named flir_usb_device_filter.xml, but the name and location is up to you to decide.
    <?xml version="1.0" encoding="utf-8"?>
    <resources>
    <usb-device vendor-id="2507" />
    </resources>
    
5. Depending on your workflow dealing with FLIR ONE classic in addition to USB-related permissions you may require the following:
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    

Usage in Android Studio project

FLIR Atlas Android SDK binaries should be copied to the libs folder as the following structure shows:

        Project
        +-app
          +-libs
          | +-androidsdk-release.aar
          | +-thermalsdk-release.aar
          +-src
            +-main
              +-java
              +-res
              +-AndroidManifest.xml
        
The libraries are added to the project automatically when they are put in the structure described above and build.gradle is configured as described in previous sections.

Changelog - changes in this release

2.4.0 (2024-09-20)


Breaking changes

* Changed the doCompression parameter in ThermalSequenceRecorder to enableCompression.

New features

* Added support for sketch in ThermalImage.

Fixes

* Fixed a long loading/opening time of some thermal images.
* Fixed a problem with opening some compressed thermal sequence recordings.
* Fixed GPS latitude information read from thermal images.
* Fixed a problem with reading measurements from some thermal images.
* Fixed a problem with reading certain images created in FLIR Thermal Studio.
* Fixed ultramax conversion failing for some thermal images.

2.3.0 (2024-06-19)


Breaking changes

* Android version 9 and 10 are no longer supported and running on these versions may result in instabilities or crashes.
* Removed unimplemented 'getExtension()' interface in ThermalSequenceRecorder.

New features

* Added support for setting viewport X and Y coordinates when rendering to GLSurfaceView.
* Ensured compatibility with new FLIR One Edge firmware, 1.18.10 and later (earlier SDK versions will not work).

Fixes

* Fixed a problem with updating isotherm temperature value in a thermal image when image is saved and then reopened.
* Fixed a problem saving and loading ThermalImage description when using Unicode characters.
* Fixed a random crash during initialization of SDK OpenGL shaders.
* Fixed invalid links in HTML release page.
* Fixed crash when connecting to E8 camera using NetworkCamera sample.
* Adjusted and unified changelog entries.
* Improved connection stability for FLIR ONE Edge (and Edge Pro) cameras.

2.2.1 (2024-04-25)


* No changes in the FLIR Atlas Android SDK.

2.2.0 (2024-04-19)


New features

* Added a new option to obtain a password allowing to connect to FLIR Camera WiFi network: `WirelessCameraDetails.getPasswordForSerialNumber`. This is used for FLIR ONE Edge cameras. Note that `WirelessCameraDetails.password` field is now deprecated.
* Extended `DisplaySettings` class with `FlipType` enum.
* Added support for adding image voice annotations.
* Added support for sequence recording and playback. Only for FLIR One currently.

Fixes

* Fixed a memory leak when streaming the visual stream.
* Fixed streams being listed even though not supported by camera.
* Fixed authentication of visual stream.
* Fixed issue with discovering some cameras with newer firmware.
* Fixed issue connecting to C5 camera.

2.1.3 (2024-03-01)


New features

* Added option to turn off noise reduction in vividIR.

2.1.2 (2024-01-26)


Fixes

* Fixed a streaming quality issue when using FLIR ONE Edge on some devices.
* Fixed a streaming quality issue when using trilateral upscale mode.
* Fixed a crash when requesting USB permission on Android 14.

2.1.1 (2023-12-20)


Fixes

* Fixed a bug preventing streaming from FLIR One Edge.

2.1.0 (2023-12-15)


New features

* Renamed SDK to official FLIR Atlas Android SDK.
* New API for sequence playback allowing to play CSQ and SEQ files.
* New API allowing to setup parameters for the VividIR filter for live stream.

Fixes

* Fixed a crash on some Android 9 and Android 10 devices when initializing SDK.
* Fixed scale range not working when used with GLSurface.
* Fixed Picture in Picture rectangle size being reset to default for each frame during live streaming.

2.0.0 (2023-10-13)


New features

* Added `getTimeZoneTakenOffset()` to `ThermalImage` for retrieving time zone offset data in thermal images.
* Added information about SDK version and commit SHA to UI for each sample app.
* Added support for Gradle 8, Java 17, Android SDK API level 34 and latest stable Android Studio Giraffe, including support for version catalogs (toml) and Kotlin DSL compatibility.
* Added APIs to work with scale/span and "region of interest" when live streaming with GLSurfaceView.

Fixes

* Fixed random crashes when working with FLIR ONE cameras (gen 3 and later) during connection phrase and streaming.
* Improved FLIR ONE image quality during streaming on Samsung S22/S22 Ultra.
* Improved discovery phrase for FLIR ONE gen 3 cameras to correctly support both cases when user grants or denies USB permission.


1.17.0 (2023-09-20)


New features

* Added support for FLIR One Edge.

Fixes

* Fixed occasional crash in FLIR One.

1.16.1 (2023-06-14)


Fixes

* Fixed discovery for pre-series FLIR One Edge Pro cameras.
* Fixed missing Bluetooth permissions when discovering Meterlinks on Android 13.
* Fixed a problem with connecting FLIR One classic due to USB permission after a fresh install.
* Fixed a camera model name in EXIF when storing images with FLIR One classic or FLIR One Edge Pro.

1.16.0 (2023-05-31)


Breaking changes

* Removed unused blending parameter in PictureInPicture.

New features

* Added `getGasQuantificationInput()` and `getGasQuantificationResult()` to `ThermalImage` for retrieving gas quantification data in thermal images.

Fixes

* Fixed a problem when searching Javadoc documentation user was redirected to invalid URL.

Known issues

* `PermissionHandler.java` is not handling Bluetooth permissions correctly (workaround is to create own implementation).
* BLE is not working properly (workaround is to use Bluetooth classic mode).

1.15.0 (2023-05-11)


New features

* Added support for rendering live stream image to GLSurfaceView.
* Added a helper allowing to determine FLIR One type from live/CameraInformation.
* Added initial version of FLIR One Edge simulator.
* Added support for Java 17 for Java desktop on Windows, Linux and Mac platforms.
* Correctly support JNLP/OpenWebstart when using Java desktop SDK in a server/cloud/remote infrastructure.

Fixes

* Fixed inconsistent frequency of BLE packets coming in from FLIR One Edge camera.
* Fixed duplication of streams when calling Camera.getStreams() after reconnection.
* Fixed stream not displaying in Mobile sample app.
* Fixed an incomplete/truncated text when reading image description for some images.
* Fixed a crash when reading image text annotations for some images.
* Fixed an issue causing thermal images with unexpected extension to be considered as not valid.
* Updated documentation related with Android permissions handling and 3rd party licenses.

Breaking changes

* Reduced the size of AAR file by removing x86 32-bit support.
* Moved `Palette.java` and `PaletteManager.java` to package `com.flir.thermalsdk.image`.
* Replaced `PresetColor` with `CustomColor` for working with isotherms. Added helpers in `CustomColor` and `IsothermCollection` for making the transition easier.

1.14.4 (2023-03-27)


Fixes

* Fixed issues causing the temperature span/scale to behave incorrectly.

1.14.3 (2023-03-21)


* No changes in the Java SDK.

1.14.2 (2023-02-09)


Fixes

* Fixed an issue with unexpected id value in MeasurementDelta.
* Fixed a crash when reading image description for some images.

1.14.1 (2023-02-02)


Breaking changes

* Cleanup in Android CameraType and FlirOneType enums.

1.14.0 (2022-12-20)


Breaking changes

* Deprecated `DiscoveryEventListener.onCameraFound(Identity)` in favor of `DiscoveryEventListener.onCameraFound(DiscoveredCamera)`. The `DiscoveredCamera` wraps `Identity` and gives extra info about the found devices. `DiscoveryEventListener.onCameraFound(Identity)` is scheduled for removal in future release.
* Increased the minimum Android API level to Android 28 (Android 9.0).

New features

* Added support for FLIR ONE Edge camera - introduce new CommunicationInterface.FLIR_ONE_WIRELESS allowing to discover FLIR ONE Edge cameras, added new sample app SampleFlirOneWireless showing how to work with FLIR ONE Edge in terms of discovery, streaming.
* Added a snapshot to local storage feature allowing to locally capture images from remote cameras that have no internal or external storage support.

1.13.0 (2022-05-31)


Breaking changes

* Java SDK desktop initialization method changed to accept temporary files path instead of authentication files path.

New features

* Added support for oblique line (previously only vertical and horizontal lines were supported). See `MeasurementsShapeCollection.addLine(Point posStart, Point posEnd)` and `MeasurementLine.setLine(Point posStart, Point posEnd)`.
* Added support for settings level and span on remote camera temperature scale. See `ScaleController.min` and `ScaleController.max`.

Fixes

* Fixed a crash when invalid frame data is received during live streaming.
* Fixed a crash when opening an image with Java SDK desktop.

1.12.0 (2022-04-07)


New features

* Increased emulated camera resolution to 1024x768 and support lower streaming resolutions.
* Added `calcMask` property for remote shapes (`RemoteRectangle`, `RemoteCircle`, `RemoteLine`) allowing to set a calc mask directly for remote camera's measurements.
* Improved performance in thermal colorization.

Fixes

* Fixed various scale issues.
* Fixed issue when changing palette during streaming using the PlateauHistogramEqSettings.

1.11.0 (2022-02-07)


New features

* Migrated to Android SDK level 30, added support for AndroidX and view binding. In the same time removed old and deprecated dependencies.

Fixes

* Fixed a crash when connecting to FLIR ONE over USB and requesting USB access permission on Android 31+.

1.10.0 (2021-11-23)


Breaking changes

* Introduced new interface `ImageBuffer` in order to abstract `JavaImageBuffer`.
* Moved `Camera.Consumer` to package `com.flir.thermalsdk.utils`.
* Removed `com.flir.thermalsdk.live.remote.Request` and related methods in `Storage`. Class `com.flir.thermalsdk.live.importing.Importer` should be used instead.

New features

* Added `Renderer`, `Colorizer` and `ImageColorizer` API allowing to render colorized thermal images. In the same time `ImageBase.getImage()` method is being deprecated and scheduled for future removal.
* Added support for more `ColorDistribution` modes.
* `ColorDistribution` had been enhanced allowing to set additional parameters. New methods had been introduced: `get/setColorDistributionSettings` and old methods were deprecated and became a subject for future removal: `get/setColorDistribution`.
* Added support for Isotherms (below, above, interval, humidity, insulation).
* Added new API for streaming (`Streamer`, `VisualStreamer`, `ThermalStreamer`).
* Added support for Android x86_64 architecture.
* Added visual streaming support for network cameras.
* Added *experimental* thermal streaming support for network cameras.
* Added support for integrated FLIR IR camera (i.e. CAT S61, S62).

Fixes

* Fixed rendering crashes when running in an Android x86 emulator.

1.9.0 (2021-10-06)


* No changes in the Java SDK.

1.8.1 (2021-07-14)


* No changes in the Java SDK.

1.7.1 (2021-06-11)


Fixes

* Included debug symbols for internal builds.

1.8.0 (2021-06-10)


* No changes in the Java SDK.

1.7.0 (2021-04-22)


New features

* Added transformation API for still images, allowing to align IR and DC image panning.

Fixes

* Multiple stability improvements.
* Fixed memory leak when rotating `ThermalImage`.

1.6.0 (2021-03-22)


Breaking changes

* Reworked `Importer` API by replacing `FileObject` and URLs with `FileInfo` and `FileReference`.

1.5.0 (2021-02-22)


Breaking changes

* Moved the fusion distance property from Fusion class to remote FusionController class.
* Moving and offset functions were removed from MeasurementsShape class and MeasurementsShapeMovable interface was added to support measurement tools that can be repositioned.
* Changed type of `ImageStatistics.standardDeviation` to `ThermalDelta`.
* Automatic calculation of hotspot, coldspot, min, max, average and area measure for measurements added to the image no longer defaults to on. See: `MeasurementMarker`.

New features

* Added `MeasurementDelta` and `ThermalDelta` types allowing to calculate difference/delta between two measurement types.
* Added `MeasurementReference` allowing to store an arbitrary reference temperature - may be useful for `MeasurementDelta`.
* Added `DisplaySettings`, which expose a set of visual attributes, which specify how the image is displayed. It also specify how the image was displayed when it was initially taken by a camera. It allows a user to specify a "subsection" of interest, while still keeping the entire image available for a context.

1.4.0 (2020-11-13)


Breaking changes

* Removed the enum value `TemperatureUnit.SIGNAL` to retrieve a raw thermal signal values.
* Most functions working on temperatures now uses ThermalValue.
* Command API is now uses generics, in consequence NUC API is changed.
* Changed `FileObject`, `FolderObject`, and `LogItem` to use `LocalDateTime` instead of `Date` to avoid incorrect local time conversions.
* Changed `Channel` and `GpsInformation` to use `Date` instead of `long` for improved type safety.
* Changed API for automatic calculation of hotspot, coldspot, min, max and average for the measurements and additionally calculations no longer defaults to on - these must be explicitly enabled.

New features

* Extended Remote API to support more properties and commands giving a user more control over the remotely connected camera.
* Added API allowing to set GPS and compass information for the ThermalImage.
* Added API to get an image representing the full thermal range scale using a specified `Palette`.

1.3.0 (2020-06-26)


Breaking changes

* Renamed `CollisionOption.OVERRIDE` into [CollisionOption.OVERWRITE](@ref com.flir.thermalsdk.live.importing.CollisionOption).

Fixes

* Fixed ThermalImage.getDateTaken() to return time with millisecond resolution.

1.2.0 (2020-05-27)


Breaking changes

* Reworked `RemoteControl` related to `Calibration`, `Battery`, `Storage` to use Property API and Command API.

New features

* Introduced API for handling VoiceAnnotation stored within a ThermalImageFile.
* Extended Remote API in order to gain access to various remote camera properties and allow run commands on a remote camera.
* Reworked MSX fusion mode so it can take an alpha value in range of 0 to 100.

1.1.1 (2020-03-26)


* Fixed MSX misalignment for FLIR ONE gen 2 dongles.
* Fixed a crash happening when stopping devices discovery.

1.1.0 (2020-02-04)


Breaking changes

* Reworked ImageBase rotation. `setRotatation` is renamed to `rotate`, and will apply the new _relative_ rotation instantly. `getRotation` is removed.
* `Camera.connect` and `Camera.disconnect` are now blocking.

1.0.5 (2019-11-04)


* No changes in the Java SDK.

1.0.4 (2019-10-22)


* Changed how access to FLIR ONE is handled, add a help class to simplify asking for runtime permission before connect.

1.0.3 (2019-09-24)


* WiFi discovery stability fixes and improved error handling.

1.0.2 (2019-07-10)


* No changes in the Java SDK.

1.0.1 (2019-06-18)


* Added getPhotoWidth and getPhotoHeight for Photo image on Fusion.java and getWidth and getHeight on ImageBase.java, see documentation for further info.
* Bugfix in Android logging, now logging can be enabled and disabled.
* Set WiFi network as default when discovering for CommunicationInterface.NETWORK cameras using DiscoveryFactory.scan() method. Note that this remains valid for the whole running process - use ConnectivityManager.setProcessDefaultNetwork() (prior to API 23) or ConnectivityManager.bindProcessToNetwork() (API 23 and later) to change default to any other network.

1.0.0 (2019-05-23)


* More Importer API reliability improvements.
* Removed deprecated ImportService API and deprecated classes in sample applications.
* Embedded Developer Quick Start Guide in Javadoc overview page.
* Added Fusion.setFusionMode().
* Fixed Fusion setters to no longer change fusion mode, use setFusionMode instead.
* Removed parameterless Fusion setters.
* Removed enum FusionLevelSpanMode and values FusionMode.THERMAL_FUSION_ABOVE, FusionMode.THERMAL_FUSION_BELOW and FusionMode.THERMAL_FUSION_INTERVAL. Use FusionMode.THERMAL_FUSION together with Fusion.setThermalFusion(), Fusion.setThermalFusionAbove(), or Fusion.setThermalFusionBelow() instead.
* Changed camera's measurement range in image.CameraInformation to ThermalValue type instead of a plain double type.
* Changed Fusion.setThermalFusion(...) methods signature to accept ThermalValue instead of a plain double value.

0.17.0 (2019-05-03)


* No changes in the Java SDK.

0.16.0 (2019-04-23)


* Fixed ThermalImage.getDateTaken() to return correct date/time.
* WiFi discovery stability fixes and improvements.
* Added DiscoveryFactory API to stop discovery on a specified interface.
* Allowed text annotations to have non-unique titles by introducing Pair class and changing ThermalImage.getTextAnnotations() to return a list of pairs instead of a HashMap.
* Made text annotations within the ThermalImage mutable - allow to set them using ThermalImage.setTextAnnotations().
* Changed signature of Importer.importFile and Importer.importFiles to accept an "on completion" callback.
* Changed signature of callback OnFileError to receive a FileObject instead of a plain URL string.

0.15.0 (2019-03-27)


* Fixed a crash when applying Palette with an incorrect name to a ThermalImage.
* Refactored SDK packages to reflect updated SDK name (source code moved from "atlas" to the corresponding packages "com.flir.thermalsdk", "com.flir.thermalsdk.androidsdk", "com.flir.thermalsdk.javasdk").
* Added default implementation for DiscoveryEventListener.onCameraLost() and DiscoveryEventListener.onDiscoveryFinished() methods, making them optional to implement in client code.
* Fixed getting and applying color distribution to the image.
* Implemented palettes colors inverting.
* Unified sample apps: unify package name to "com.flir.thermalsdk.samples", rename "AndroidSpartacusSampleApplication" into "AndroidSampleJava", rename "AtlasKotlinSample" into "AndroidSampleKotlin".
* Stability improvements in sample apps.
* Switched to Gradle 5.+.
* Embedded SDK migration guide into Javadoc under "Migration from FLIR One Android SDK" section.

0.14.0 (2019-03-14)


* Moved saveAs() method from ThermalImageFile to ThermalImage, so it is now possible to take a snapshot during live streaming.
* Enabled support for all FLIR One models.
* Fixed import over WiFi network when no SD card is present in the camera.
* Fixed color space conversions on Android target platform.
* Fixed NUC command for FLIR One dongle.
* Switched to NDK 19b (for building native code for Android target).
* Added Camera API allowing to connect to specified IP address.
* Refactored Rect class to use x, y, width, height.
* Fixed importing a lot of files from WiFi cameras.
* Added "Changelog" section in Javadoc overview page.
* Replaced ThermalImage.rotate method with getRotation/setRotation and make documentation more descriptive.
* Prepared a getting started guide for the SDK users.
* Re-implemented WiFi Discovery for Android (improvement performance, reliability, no API changes).
* Implemented recursive listing for Import API.
* Removed RemoteControl heartbeat API.
* Added changelog file with information about important Android and Java desktop code/API changes and fixes.
* Injected common public API documentation into Android and Java documentation.
* Fixed issues with connection when camera is set to "Share WiFi" mode.
* Minor refactor in Camera class (removed parametrized constructor to avoid ambiguity).
* Fixed crashes in 'live' tests on Linux and Windows.
* Improved documentation for Android and Java desktop.
* Fixed issues with camera name over mobile hotspot.

0.13.0 (2019-01-31)


* Added temperature unit for ThermalValue class.
* Fixed 'getPhoto' implementation to return properly colorized visual (DC) image.
* Reused Java desktop tests in Android instrumentation tests run.
* Introduced common JSON data for 'image' tests to be used among all platforms.

0.12.0 (2019-01-15)


* Refactored Import API, deprecated old Import API.
* Implemented 'getValue' and 'getValues' methods.
* Moved most test cases under 'javasdk' (apart from Android specific).
* Added Remote API for Storage and Calibration.
* Added method to get visual (DC) photo from a ThermalImage.
* Replaced general SDK initialization method with a specific method for Java desktop and Android.
* Minor changes in public methods and fields names in 'image' package, more verbose Javadoc.
* Added subscription for last stored image.
* Live API refactoring, moved classes to common 'live' package.

3rd party dependencies

Common 3rd party dependencies within the SDK products can be found here.

Additional Android 3rd party dependencies:

Library name Version License
JmDns 3.5.9 Apache 2.0
slf4j 2.0.7 MIT
libaums 0.5.0 Apache 2.0

Troubleshooting

1. "Android Studio IDE can't see the FLIR Atlas Android SDK classes. Imports, classes are all in red. Gradle says it can't see the AAR library even though it is in correct place."
As mentioned in the "Requirements of FLIR Atlas Android SDK" chapter you have to add 'repositories' section under 'android' section in your build.gradle file.
Otherwise Gradle won't look in local filesystem for the AAR files and it will complain even when the file is in correct place.

2. "I get the java.lang.UnsatisfiedLinkError when trying to use any FLIR Atlas Android SDK method."
Make sure the AAR files are placed in correct structure as described in "Usage in Android Studio project" chapter.
Also make sure you call ThermalSdkAndroid.init(android.content.Context context) method before any other call to FLIR Atlas Android SDK methods. In example put that line of code in your Activity.onCreate() method.

3. "I get the error: More than one file was found with OS independent path 'lib/arm64-v8a/libc++_shared.so'"
Note that when working with other 3rd party libraries, a problem with multiple native libraries may emerge.
Example library that was observed to cause multiple libc++_shared.so libraries collision is OpenCV for Android.
Error might look like this:

    Execution failed for task ':app:transformNativeLibsWithMergeJniLibsForDebug'.
    More than one file was found with OS independent path 'lib/arm64-v8a/libc++_shared.so'
    
In order to solve the problem you should add the following to your app's build.gradle:
    android {
        packagingOptions {
            pickFirst 'lib/x86_64/libc++_shared.so'
            pickFirst 'lib/armeabi-v7a/libc++_shared.so'
            pickFirst 'lib/arm64-v8a/libc++_shared.so'
        }
    }
    



Packages
Package
Description
The main 'FLIR Atlas Android SDK' package.
The main 'FLIR Atlas Android SDK' for Android package [Android].
 
Allows to interpret the data stored in files or received from FLIR Thermal cameras as Visual or Thermal images [Android].
Allows to discover FLIR cameras available in the vicinity [Android].
Classes related with physical device to device connection [Android].
Classes related with devices discovery [Android].
 
Package related with handling and managing FLIR Test & Measurement (T&M) devices like Meterlinks [Android].
Allows to interpret the data stored in files or received from FLIR Thermal cameras as Visual or Thermal images.
Defines fusion modes possible to set for a Thermal image.
Classes allowing managing the collection of isotherms.
Defines a set of measurements for the thermal image and operations on them.
Provides a media player implementation allowing to play a thermal sequence files.
 
Different utility tools, converters, wrappers and other helper classes useful for images manipulation.
Allows to discover FLIR cameras available in the vicinity.
Classes related with physical device to device connection.
Classes related with devices discovery.
Classes and interfaces related with importing images and files from remote FLIR cameras.
 
Classes related with device remote control functionality.
Classes and interfaces related with device live streaming functionality.
Package related with customized logging.
Package related with handling and managing FLIR Test & Measurement (T&M) devices like Meterlinks.
Package contains classes with FLIR Meterlinks data model definitions.
Package contains useful utilities and custom annotations.