Rexios80 / watch_connectivity

Wrapper for WatchConnectivity on iOS and Wearable APIs on Android
https://pub.dev/packages/watch_connectivity
BSD 3-Clause "New" or "Revised" License
27 stars 17 forks source link

Add information to readme for sending/receiving data in native android app #7

Open ciriousjoker opened 1 year ago

ciriousjoker commented 1 year ago

I'm sending data like this:

await watch.sendMessage({
  "type": "test",
  "data": "Hello from Flutter",
});

I'm trying to receive it like this:

class CommunicationService : WearableListenerService() {
    override fun onMessageReceived(messageEvent: MessageEvent) {
        super.onMessageReceived(messageEvent)
        Log.d(TAG, "onMessageReceived: ${messageEvent.path}")

        // Process the received message
        handleMessage(messageEvent.path, messageEvent.data)
    }

    private fun handleMessage(path: String, dataBytes: ByteArray) {
        val data = String(dataBytes, Charsets.UTF_8)
        val data2 = dataBytes.toString()
        Log.d(TAG, "data: $data")
        // Handle the message based on the path and data
    }

    companion object {
        private const val TAG = "CommunicationService"
    }
}

The result is something like this (from logcat):

data: ��??sr??java.util.HashMap���`�??F?? loadFactorI?? thresholdxp?@?????????? w????????????t??datat??Hello from Fluttert??typet??testx

ciriousjoker commented 1 year ago

Apparently you can write something like this to convert it:

/**
 * Interprets the byteArray as a Map<String, Any>.
 * If that's not possible, returns null.
 */
fun ByteArray.asMap(): Map<String, Any>? {
    val byteArrayInputStream = ByteArrayInputStream(this)
    val objectInputStream = ObjectInputStream(byteArrayInputStream)

    return try {
        val obj = objectInputStream.readObject()

        if(obj !is Map<*, *>) throw Exception()
        @Suppress("UNCHECKED_CAST")
        obj as Map<String, Any>;
    } catch (e: Exception) {
        e.printStackTrace()
        null
    } finally {
        objectInputStream.close()
    }
}

...

val data = messageEvent.data.asMap()
Rexios80 commented 1 year ago

The idea is you use flutter on both sides, but I should probably expose those conversion methods so people doing native android can use them without copy/paste

Rexios80 commented 1 year ago

Actually nevermind you wouldn't have access to the flutter plugin on the native android side 🙃. Maybe I should make a native android wrapper, but that's a task for another day.

ciriousjoker commented 1 year ago

Yeah, I found the conversion methods and after copypasting them the serialization and deserialization works.

Using flutter for the wear os app isn't really an option. Battery life is extremely limited and we want to use the native widgets due to their looks and performance.

It would be nice to have a section in the readme about how to send and receive data in a native wearOS app.