Skip to content

Commit

Permalink
Add android code
Browse files Browse the repository at this point in the history
  • Loading branch information
lordspace74 committed Mar 25, 2024
1 parent 19f79a8 commit 85970cb
Show file tree
Hide file tree
Showing 17 changed files with 1,023 additions and 31 deletions.
10 changes: 8 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,6 @@ project.xcworkspace
.settings
local.properties
android.iml
android/app/libs
android/keystores/debug.keystore

# Cocoapods
#
Expand All @@ -53,5 +51,13 @@ npm-debug.log
yarn-debug.log
yarn-error.log

# BUCK
buck-out/
\.buckd/
android/app/libs
android/keystores/debug.keystore

# Expo
.expo/*

*.aab
37 changes: 37 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# expo-mds

Expo Module for Movesense

Please note that you need hermes as js engine for this lib to work on Android

# API documentation

- [Documentation for the main branch](https://github.com/expo/expo/blob/main/docs/pages/versions/unversioned/sdk/mds.md)
- [Documentation for the latest stable release](https://docs.expo.dev/versions/latest/sdk/mds/)

# Installation in managed Expo projects

For [managed](https://docs.expo.dev/versions/latest/introduction/managed-vs-bare/) Expo projects, please follow the installation instructions in the [API documentation for the latest stable release](#api-documentation). If you follow the link and there is no documentation available then this library is not yet usable within managed projects — it is likely to be included in an upcoming Expo SDK release.

# Installation in bare React Native projects

For bare React Native projects, you must ensure that you have [installed and configured the `expo` package](https://docs.expo.dev/bare/installing-expo-modules/) before continuing.

### Add the package to your npm dependencies

```
npm install expo-mds
```

### Configure for iOS

Run `npx pod-install` after installing the npm package.


### Configure for Android



# Contributing

Contributions are very welcome! Please refer to guidelines described in the [contributing guide]( https://github.com/expo/expo#contributing).
4 changes: 3 additions & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,6 @@ repositories {
dependencies {
implementation project(':expo-modules-core')
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${getKotlinVersion()}"
}
implementation files('./libs/mdslib-3.15.0(1)-release.aar')
implementation "com.polidea.rxandroidble2:rxandroidble:1.11.1"
}
Binary file added android/libs/mdslib-3.15.0(1)-release.aar
Binary file not shown.
9 changes: 8 additions & 1 deletion android/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,2 +1,9 @@
<manifest>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="expo.modules.mds">
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
</manifest>
7 changes: 7 additions & 0 deletions android/src/main/java/expo/modules/mds/BleScanListener.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package expo.modules.mds;

import androidx.annotation.NonNull;

public interface BleScanListener {
void onDeviceFound(@NonNull String name, @NonNull String address);
}
54 changes: 54 additions & 0 deletions android/src/main/java/expo/modules/mds/BleScanner.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package expo.modules.mds;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;

public class BleScanner {

private final BroadcastReceiver receiver;

private final BluetoothAdapter mBluetoothAdapter;

private final Context context;

BleScanner(Context context, final BleScanListener listener) {
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
this.context = context;
receiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
BluetoothDevice device = (BluetoothDevice) intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
var name = device.getName();
var alias = device.getAlias();
var address = device.getAddress();
if(address != null && name != null){
listener.onDeviceFound(name != null ? name : address, address);
}
}
}
};
}

public void scan() {
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothDevice.ACTION_FOUND);
context.registerReceiver(receiver, filter);
mBluetoothAdapter.startDiscovery();
}

public void stopScan() {
mBluetoothAdapter.cancelDiscovery();
try {
context.unregisterReceiver(receiver);
} catch (Throwable t) {

}
}


}
186 changes: 182 additions & 4 deletions android/src/main/java/expo/modules/mds/ExpoMdsModule.kt
Original file line number Diff line number Diff line change
@@ -1,13 +1,24 @@
package expo.modules.mds

import com.movesense.mds.*
import expo.modules.core.errors.CodedException
import expo.modules.kotlin.Promise
import com.movesense.mds.MdsNotificationListener as MdsNotificationListener
import com.movesense.mds.Mds.builder as Builder
import expo.modules.kotlin.modules.Module
import expo.modules.kotlin.modules.ModuleDefinition

lateinit var mds: Mds
lateinit var bleScanner: BleScanner
var subscriptionMap = mutableMapOf<String, MdsSubscription>()

class ExpoMdsModule : Module() {
// Each module class must implement the definition function. The definition consists of components
// that describes the module's functionality and behavior.
// See https://docs.expo.dev/modules/module-api for more details about available components.
override fun definition() = ModuleDefinition {


// Sets the name of the module that JavaScript code will use to refer to the module. Takes a string as an argument.
// Can be inferred from module's class name, but it's recommended to set it explicitly for clarity.
// The module will be accessible from `requireNativeModule('ExpoMds')` in JavaScript.
Expand All @@ -18,12 +29,164 @@ class ExpoMdsModule : Module() {
"PI" to Math.PI
)

// Defines event names that the module can send to JavaScript.
Events("onChange")
class PromiseListener: MdsResponseListener {
var promise: Promise
constructor(promise: Promise){
this.promise = promise;
}

override fun onError(p0: MdsException?) {
var exceptionMessage = p0?.message ?: "MdsError";
var error = expo.modules.kotlin.exception.CodedException(exceptionMessage)
this.promise.reject(error)
}

override fun onSuccess(data: String?, header: MdsHeader?) {
this.promise.resolve(data)
}
}

class NotificationListener: MdsNotificationListener {
var key: String
constructor(key: String){
this.key = key;
}

override fun onError(p0: MdsException?) {
var exceptionMessage = p0?.message ?: "MdsError";
var error = expo.modules.kotlin.exception.CodedException(exceptionMessage)
sendEvent("newNotificationError", hashMapOf(
"key" to key,
"error" to error
))
}

override fun onNotification(p0: String?) {
sendEvent("newNotification", hashMapOf(
"key" to key,
"notification" to p0
))
}
}

class ConnectionListener: MdsConnectionListener {
var promise: Promise
constructor(promise: Promise){
this.promise = promise;
}

override fun onConnect(p0: String?) {
print("onConnect: $p0")
}

override fun onConnectionComplete(p0: String?, p1: String?) {
print("onConnectionComplete $p0 $p1")
this.promise.resolve(p0)
}

override fun onError(p0: MdsException?) {
print("onError ${p0?.message}")

var exceptionMessage = p0?.message ?: "MdsError";
var error = expo.modules.kotlin.exception.CodedException(exceptionMessage)

this.promise.reject(error)
}

override fun onDisconnect(p0: String?) {
print("onDisconnect $p0")
}

}

class BleListener: BleScanListener {
override fun onDeviceFound(name: String, address: String) {
sendEvent("newScannedDevice", hashMapOf(
"name" to name,
"address" to address
))
}
}

Events("newScannedDevice", "newNotification", "newNotificationError")

fun initMds(): Mds{
if(::mds.isInitialized){
return mds;
}
mds = Builder().build(appContext.reactContext);
return mds;
}

fun initBleScanner(): BleScanner {
if(::bleScanner.isInitialized){
bleScanner
}
bleScanner = BleScanner(appContext.reactContext, BleListener());
return bleScanner
}

Function("scan") {
bleScanner = initBleScanner();
bleScanner.scan()
}

Function("stopScan") {
bleScanner = initBleScanner();
bleScanner.stopScan()
}


Function("unsubscribe") { key: String ->
var cb = subscriptionMap.get(key)
cb?.unsubscribe()
subscriptionMap.remove(key)
}


AsyncFunction("connect") { address: String, promise: Promise ->
// Send an event to JavaScript.
initMds().connect(address, null/*ConnectionListener(promise)*/)
}

Function("disconnect") { address: String ->
// Send an event to JavaScript.
initMds().disconnect(address)
}

AsyncFunction("get") { uri: String,
parameters: String, promise: Promise ->
// Send an event to JavaScript.
initMds().get(uri, parameters, PromiseListener(promise))
}

AsyncFunction("post") { uri: String,
parameters: String, promise: Promise ->
// Send an event to JavaScript.
initMds().post(uri, parameters, PromiseListener(promise))
}

AsyncFunction("put") { uri: String,
parameters: String, promise: Promise ->
// Send an event to JavaScript.
initMds().put(uri, parameters, PromiseListener(promise))
}

AsyncFunction("delete") { uri: String,
parameters: String, promise: Promise ->
// Send an event to JavaScript.
initMds().delete(uri, parameters, PromiseListener(promise))
}

// Defines a JavaScript synchronous function that runs the native code on the JavaScript thread.
Function("hello") {
"Hello world! 👋"
Function("subscribe") { uri: String, parameters: String, key: String ->
var subscription = initMds().subscribe(
uri,
parameters,
NotificationListener(key),
);

subscriptionMap[key] = subscription
}

// Defines a JavaScript function that always returns a Promise and whose native code
Expand All @@ -33,6 +196,21 @@ class ExpoMdsModule : Module() {
sendEvent("onChange", mapOf(
"value" to value
))


/*
self.mds.subscribe(uri, parameters: parameters, onNotify: { notification in
self.sendEvent("newNotification", [
"notification": notification,
"key": key
])
}, onError: { (uri, error) in
self.sendEvent("newNotificationError", [
"uri": uri,
"error": error,
"key": key])
})
*/
}

// Enables the module to be used as a native view. Definition components that are accepted as part of
Expand Down
Loading

0 comments on commit 85970cb

Please sign in to comment.