Hi fellow Garmin developers,
I have been trying to develop a direct messaging communication setup over BLE between my Android App and my connectIQ app (on Garmin Forerunner 230, SDK version 1.3.x). The goal here is that the Android app is collecting some data, and then pushing it to the watch app.
Following the details on the developer site, I have managed to get this to work, but there are a lot of dropped messages that don't get sent, and the watch receives fewer values than what is being sent.
On Android, I get this status (ConnectIQ.IQMessageStatus) = FAILURE_DURING_TRANSFER in my debug statements. '240' is the data being sent.
D/GarminMessenger: onMessageStatus: Message: 240, device: Forerunner 230, FAILURE_DURING_TRANSFER
This is my app code on the garmin:
SampleApp.mc
using Toybox.Application as App;
using Toybox.Communications as Comm;
using Toybox.WatchUi as Ui;
using Toybox.System as Sys;
var mailMethod;
var crashOnMessage = false;
var msg;
class SampleApp extends App.AppBase {
function initialize() {
AppBase.initialize();
Sys.println("app-initialize()");
msg = "0";
mailMethod = method(:onMail);
Comm.setMailboxListener(mailMethod);
Sys.println("app-initialize(): mail box listener has been set");
}
// onStart() is called on application start up
function onStart(state) {
System.println("app-onStart()");
}
// Return the initial view of your application here
function getInitialView() {
Sys.println("app-getInitialView()");
return [ new SampleAppView() ];
}
function onMail(mailIter) {
var mail = mailIter.next();
while(mail!=null) {
Sys.println("app-onMail: received - "+mail);
message = mail.toString();
Ui.requestUpdate();
mail = mailIter.next();
}
Comm.emptyMailbox();
}
// onStop() is called when your application is exiting
function onStop(state) {
System.println("app-onStop()");
}
}
class CommListener extends Comm.ConnectionListener {
function initialize() {
Comm.ConnectionListener.initialize();
sys.println("commlistener-initialize");
}
function onComplete() {
Sys.println("commlistener-onComplete: Transmit Complete");
}
function onError() {
Sys.println("commlistener-onError: Transmit Failed");
}
}
Any ideas on what could be causing this issue? I am performing all the necessary checks on the Android side to verify if the Garmin watch is paired and connected (&the app is open).
One reason this could be happening is that I am trying to send 1-2 data values (each with a ConnectIQ.sendMessage()) every second, so perhaps the Garmin device/BLE module does not support communication at that rate?
Thanks in advance for solutions and suggestions.
I think that the Connect messaging system just gets into some broken state and then no messages will go through. What you could try is to set up the Mailbox listener in onStart method instead of initialize.
Also there is a new method to make the message reading a lot easier. It is still largely undocumented, but I got a word it will be documented with the next SDK release. However, it is already working on every ConnectIQ watch. The method is:
Comm.registerForPhoneAppMessages(method(:onMsg));
where in your callback method you do:
function onMsg(msg) {
handleIncomingMessage(msg.data.toString());
}
or something similar. The input object msg is of class
Toybox::Communications::Message
probably (this is not documented yet).