Skip to main content

Android SDK - API and Configuration

The SDK receives configuration remotely from Nodle servers as well as statically using API calls. The static configuration always takes precedence over the remote configuration.

Nodle SDK API

To interact with the SDK you need to call the Nodle() method that will give you an Instance of the INodle class. The following are all the public methods for the Nodle API.

Java

import static io.nodle.sdk.android.Nodle.Nodle;

INodle nodle = Nodle();

Kotlin

import io.nodle.sdk.android.Nodle.Nodle

val nodle = Nodle()

init

public fun init(context: Context)

Initialize the Nodle SDK

Parameters
contextA Context of the application. This value must never be null.

Example:

Java

Nodle.init(this);

Kotlin

Nodle.init(this)

start

public fun start(public_key: String)

Immediately starts the Nodle SDK

Parameters
public_keyThe application public_key created in Step 1

Example:

Java

Nodle().start("ss58:public_key");

Kotlin

Nodle().start("ss58:public_key")

isStarted

public fun isStarted(): Boolean

Checks if the Nodle SDK is started

Parameters
booleantrue if the Nodle SDK is started, false otherwise

Example:

Java

Boolean sdkStarted = Nodle().isStarted()

Kotlin

val sdkStarted = Nodle().isStarted()

isScanning

public fun isScanning(): Boolean

Checks if the Nodle SDK is currently scanning the BLE neighborhood. This is useful if you want to show that the SDK is working.

Parameters
booleantrue if the Nodle SDK is scanning, false otherwise

Example:

Java

Boolean sdkScanning = Nodle().isScanning()

Kotlin

val sdkScanning = Nodle().isScanning()

stop

`public fun stop()

Immediately stops the Nodle SDK

Example:

Java

Nodle().stop();

Kotlin

Nodle().stop()

clear

`public fun clear()

Clear any configs by Nodle SDK

Example:

Java

Nodle().clear();

Kotlin

Nodle().clear()

getVersion

public fun getVersion(): String

Get the version identifier of the Nodle SDK.

Parameters
Stringthe current version of the Nodle SDK

Example:

Java

String nodleSdkVersion = Nodle().getVersion();

Kotlin

val nodleSdkVersion = Nodle().getVersion()

getEvents

public fun getEvents(): NodleEvent

Get the raw bluetooth events from the Nodle SDK with the following type:

Returns
NodleEventType.BlePayloadEventReturns NodleBluetoothScanRecord
NodleEventType.BleStartSearchingReturns NodleBluetoothEvent
NodleEventType.BleStopSearchingReturns NodleBluetoothEvent

Example of available return event classes below:

Returns
NodleBluetoothScanRecordRaw Bluetooth Record from Nodle SDK
NodleBluetoothEventBluetooth Event when the SDK start/stop

Example:

Java

BuildersKt.launch(GlobalScope.INSTANCE, (CoroutineContext) Dispatchers.getMain(), CoroutineStart.DEFAULT,
(Function2<CoroutineScope, Continuation<? super Unit>, Unit>) (coroutineScope, continuation) -> {
// start collecting events
nodle.getEvents().collect(new NodleCollector(), new NodleContinuation());
return Unit.INSTANCE;
}
);

Example Nodle Collector for Java:

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import io.nodle.sdk.NodleEvent;
import io.nodle.sdk.core.actions.events.NodleBluetoothRecord;
import kotlin.Unit;
import kotlin.coroutines.Continuation;
import kotlinx.coroutines.flow.FlowCollector;

public class NodleCollector implements FlowCollector<NodleEvent> {
@Nullable
@Override
public Object emit(NodleEvent nodleEvent, @NonNull Continuation<? super Unit> continuation) {
switch (nodleEvent.getType()) {
case BlePayloadEvent:
NodleBluetoothRecord payload = (NodleBluetoothRecord) nodleEvent;
System.out.println("Bluetooth payload available: " + payload.getDevice());
break;
case BleStartSearching:
System.out.println("Bluetooth started searching");
break;
case BleStopSearching:
System.out.println("Bluetooth stop searching");
break;
}
return nodleEvent;
}
}

Example Nodle Continuation for Java:

import androidx.annotation.NonNull;
import kotlin.coroutines.Continuation;
import kotlin.coroutines.CoroutineContext;
import kotlin.coroutines.EmptyCoroutineContext;

public class NodleContinuation implements Continuation {
@NonNull
@Override
public CoroutineContext getContext() {
// pass an empty instance or one that you need
return EmptyCoroutineContext.INSTANCE;
}

@Override
public void resumeWith(@NonNull Object o) {
// provide a base implementation if you need
}
}

Kotlin

Nodle().getEvents().collect { event ->
// collect the NodleEvents events here by chosing a type
when (event.type) {
NodleEventType.BlePayloadEvent -> handlePayload(it)
NodleEventType.BleStartSearching -> println("Bluetooth started searching")
NodleEventType.BleStopSearching -> println("Bluetooth stopped searching")
}
}

fun handlePayload(payload: NodleEvent) {
val data = payload as NodleBluetoothScanRecord
println("Bluetooth payload available ${data.device} ")
}

The following data can be collected from the NodleEventType:

KeyDescriptionDefault Value
typereturns nodle bluetooth event typeNodleEventType

The following data can be collected from the NodleBluetoothScanRecord:

KeyDescriptionDefault Value
devicereturns device unique identifierString
rssireturns received signal strength indicatorInt
bytesreturns raw bytes of the recordByteArray
manufacturerSpecificDatareturns the manufacturer specific data associated with the manufacturer idMap<Int, ByteArray>
servicesUuidsreturns an array of services UUID's within the advertisementList<UUID>

The following data can be collected from the NodleBluetoothEvent:

KeyDescriptionDefault Value
scanningreturns bluetooth scanning stateBoolean

config

public fun config(resourceId: AndroidNodleResourceId)

public fun <T> config(key: String, value: T)

configure the SDK either by supplying a json file located in res/raw/config.json or by directly configuring a key. An example of a json configuration look like this:

{
"ble": {
"scan": {
"duration-msec": 10000,
"interval-msec": 90000,
"interval-x-factor": 1
}
},
"dtn": {
"use-cellular": false
}
}

the following are the table of all the keys available and their description:

KeyDescriptionDefault Value
ble.scan.duration-msecduration of a single ble pass in milliseconds. Longer scan increase battery consumption but gives more reward.10000
ble.scan.interval-msecwait time between two ble pass in milliseconds. Longer period reduce battery consumption but gives less reward90000
ble.scan.interval-x-factormultiplier for the ble scan interval above.1
dtn.use-cellularif true, the cellular connection will be used. if false, only wifi connection will be used.true
heartbeat.background-modeif true, the SDK will be able to continue to operate when in the background. If false the SDK will eventually stop after a while.false
ble.background-modeif true, the SDK will perform additional BLE scanning even when in the background. If false the SDK won't perform additional BLE scannning.false

Example:

Java

import io.nodle.sdk.android.common.config.AndroidNodleResourceId;

// load the json config located in res/raw/config.json
Nodle().config(AndroidNodleResourceId(R.raw.sdk_config));

// or you can manually set the entries, for instance
Nodle().config("dtn.use-cellular", false);

Kotlin

import io.nodle.sdk.android.common.config.AndroidNodleResourceId

// load the json config located in res/raw/config.json
Nodle().config(AndroidNodleResourceId(R.raw.sdk_config))

// or you can manually set the entries, for instance
Nodle().config("dtn.use-cellular", false)

// then proceed to start Nodle
Nodle().start()

Debug Logs API

This API enable the debug logs for the SDK and allows developer to debug on their own and have better visiblity on their application. The default value will be false which will output PRODUCTION level logs going forward. Here is a sample how to enable/disable the API:

Nodle.Nodle().config("core.debug-log.enable", true)

PRODUCTION

- Init of the SDK
- Coroutine event logs from the API
- SDKCore logs
- init of the core
- SDK ID
- Feature logs
- Bluetooth Scanner lifecycle logs
- enabled/disabled
- success scan log
- failed scan log
- Cell Scanner lifecycle logs
- enabled/disabled
- scan started
- scan failed
- Heartbeat feature logs
- enabled/disabled

DEBUG

- Init of the SDK
- Coroutine event logs from the API
- SDKCore logs
- init of the core
- current SDK setup dump
- bundles in the DB
- SDK ID
- Feature logs
- Bluetooth Scanner lifecycle logs
- enabled/disabled
- success scan log
- each scan item found
- transmission for bundle
- failed scan log
- Cell Scanner lifecycle logs
- enabled/disabled
- scan started
- scan failed
- transmission for bundle
- Network feature logs
- network status log
- resume bundles logs
- networking logs over CLA Http
- networking bundle transmission logs
- Heartbeat feature logs
- enabled/disabled
- transmission log
- error logs
- Location Provider logs
- waiting for location log
- saved location fetch log
- timeout on location log
- fresh location fetch log
- error logs

Heartbeat API

public fun getHeartbeats(): List<NodleHeartbeatRecord?>?

The following data can be collected from the NodleHeartbeatRecord each parameter is optional:

KeyDescriptionDefault Value
idreturns hb unique identifierLong?
timestampreturns the generated timestamp when createdInt?
timezonereturns the device timezoneString?
locationH3returns the device last known location in h3 format stringString?
geoHashreturns the device last known location in geohash formatString?
isBlePermissionsGrantedreturns the device ble permissions grantedBoolean?
isLocPermissionsGrantedreturns the device location permissions grantedBoolean?
isWifiEnabledreturns the device wifi module statusBoolean?
isCellEnabledreturns the device cell module statusBoolean?
isBluetoothEnabledreturns the device bluetooth module statusBoolean?
sdkVersionreturns the sdk versionString?
configVersionreturns the sdk config versionString?
osreturns the device osString?
phonereturns the device modelString?
releasereturns the device releaseString?
apireturns the device api levelString?
hardwarereturns the device hardware nameString?
appNamereturns the app nameString?
batteryreturns the device batteryInt?
chargingreturns the device charging statusBoolean?
appInForegroundreturns the app current statusBoolean?
phoneStorageTotalreturns the device total storageString?
phoneStorageAvailablereturns the device storage availableString?
sdkStoragereturns the device storage consumedString?
httpInreturns the sdk http inputString?
httpOutreturns the sdk http outputString?
bundleRxCountreturns the DTN RXInt?
bundleTxCountreturns the DTN TXInt?
bleScanSuccessreturns the BLE Scan success countInt?
bleScanFailedreturns the BLE Failed countInt?
blePayloadCountreturns the BLE payload foundInt?
developerModereturns the device developer mode statusBoolean?

The HB API will provide a history of the heartbeats being generated by the SDK. It will always add the latest HB on top of the list being sorted by the timestamp. When there is a new heartbeat it will take the 0 element in the array. Here is a sample how to increase/decrease the storage size and be able to fetch all the heartbeats:

Nodle.Nodle().config("core.heartbeat.history", 100f)

Java

Nodle.Nodle().getHeartbeats()?.forEach {
println("Nodle HB: $it")
}

Kotlin

Nodle.Nodle().heartbeats?.forEach {
println("Nodle HB: $it")
}

H3 API

public fun fun getH3(): H3?

Return the H3 instance exposing the H3 library methods to be used by the developer:

Returns
H3Returns H3Core

The H3 interface with all the methods that the developer can take advantage is defined below:

MethodDescriptionReturn Value
h3IsValid(h3: Long)Returns true if the h3 index is validBoolean
h3IsValid(h3Address: String)Returns true if the h3 index is validBoolean
h3GetBaseCell(h3: Long)Returns the base cell number for the indexInt
h3GetBaseCell(h3Address: String)Returns the base cell number for the indexInt
h3IsPentagon(h3: Long)Returns true if this index is one of the twelve pentagons per resolutionBoolean
h3IsPentagon(h3Address: String)Returns true if this index is one of the twelve pentagons per resolutionBoolean
geoToH3(lat: Double, lng: Double, res: Int)Find the H3 index of the resolution res cell containing the lat/lon (in degrees) returns h3 indexLong
geoToH3Address(lat: Double, lng: Double, res: Int)Find the H3 index of the resolution res cell containing the lat/lon (in degrees) returns H3 indexString
h3ToGeo(h3: Long)Find the latitude, longitude (both in degrees) center point of the cell.Pair<NodleLat, NodleLng>
h3ToGeo(h3Address: String)Find the latitude, longitude (degrees) center point of the cell.Pair<NodleLat, NodleLng>
h3ToGeoBoundary(h3: Long)Find the cell boundary in latitude, longitude (degrees) coordinates for the cellList<Pair<NodleLat, NodleLng>>
h3ToGeoBoundary(h3Address: String)Find the cell boundary in latitude, longitude (degrees) coordinates for the cellList<Pair<NodleLat, NodleLng>>
kRing(h3Address: String?, k: Int)Neighboring indexes in all directions h3Address – Origin index k – Number of rings around the originList<String?>?
kRing(h3: Long, k: Int)Neighboring indexes in all directions h3Address – Origin index k – Number of rings around the originList<Long>
kRings(h3Address: String, k: Int)Neighboring indexes in all directions h3Address – Origin index k – Number of rings around the originList<List<String?>?>?
h3Distance(a: String?, b: String?)Returns the distance between a and b. This is the grid distance, or distance expressed in number of H3 cells.Int
h3Distance(a: Long, b: Long)Returns the distance between a and b. This is the grid distance, or distance expressed in number of H3 cells.Int
h3Line(startAddress: String?, endAddress: String?)Given two H3 indexes, return the line of indexes between them (inclusive of endpoints).List<String?>?
h3Line(start: Long, end: Long)Given two H3 indexes, return the line of indexes between them (inclusive of endpoints).List<Long>
h3GetResolution(h3Address: String?)Returns the resolution of the provided indexInt
h3GetResolution(h3: Long)Returns the resolution of the provided indexInt
h3ToString(h3: Long)Converts from long representation of an index to String representation.String?
stringToH3(h3Address: String?)Converts from String representation of an index to long representation.Long
numHexagons(res: Int)Returns the number of unique H3 indexes at resolution res.Long

Java

Nodle.Nodle().h3?.h3ToGeo("8a1eebbb461ffff")

Kotlin

Nodle.Nodle().h3?.h3ToGeo("8a1eebbb461ffff")