Cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

How to make a companion app?

Hi, I am new to Fitbit studio and i want to make an app running in fitbit ionic which can communicate to my android and ios app. From what i have heard is that we have companion api  for that purpose and i want to know that whether we can build our companion app in native languages (android, Swift) and communicate with the app in ionic if it so...How can i do that.....?

Best Answer
0 Votes
12 REPLIES 12

If you work with Fitbit Studio you can write code in JavaScript which will be run within the Fitbit Android/iOS app. From the references: "The Companion APIs are accessible by applications which run within the Fitbit mobile application only."

Here is an example project with communication between Fitbit device and the companion/phone app. The code for the companion/phone is in the companion directory. In the example there is simple (short) messaging from the companion/phone to the Fitbit device.

I hope this gives you an answer on how you can use the companion API and how to communicate. For more data or larger files I would recommend the file transfer API, you can find more info about that in this answer.

For your question on native languages (android, Swift). As far as I know, you need to use the companion API together with Fitbit studio and JavaScript as someone from the community. Surely the developers themselves need to use Java and Swift to program for Android and iOS respectively.

Best Answer

Hello,

 

I'm new here, but I've got my Versa after my Pebble Time (and Classic), and I'm still wondering how can I port my Android Pebble companion app to work with Versa, since there is no known way of interfacing native Android application with Fitbit App to communicate with Versa (two-way). I mean, PebbleKit-way, not some JS running in Fitbit app.

 

Basically my Fitbit watchapp wants to communicate with 3rd-party Android app that provides API for other apps, to access and control it. It was easily done in Pebble SDK, and now it's currently impossible (from what I read so far). We "could" use some hacky way like file-watcher with common file that Fitbit phone app can read/write, or opening some fishy localhost connection on in Android app and let Fitbit companion app talk to it (mostly, just read/write back, with no way of communicating back except of active polling).

 

Can you show us the better way, or introduce it soon? Many cool Pebble apps cannot be ported here because of that. I know Fitbit SDK is young (if we don't count Pebble legacy), but I would say it's high priority.

Best Answer
0 Votes

Hey, I think it's best to make a new question on that. I'm only used to work with the Versa (and a bit of Ionic through the simulator) and I'm just a free-time developer. I don't know straight away if there is a direct way of communication between the Versa and a 3rd party Android app (that used to work with a Pebble Time).

Also if you want to introduce that kind of communication as it was possible in the Pebble SDK as a feature in the SDK, I believe the best way to propose that is to make a topic at the Feature Suggestion forum.

Best Answer
0 Votes

Sorry, for some reason I mistook you for a Fitbit staff member 🙂

 

There is already a suggestion for this, created by somebody related to Sleep As Android app.

I really hope they provide us with at least some makeshift, hacky way to achieve it until the Fitbit API is a bit more advanced.

Best Answer
0 Votes

No problem 🙂
Hope they can make something like they suggested!

Best Answer
0 Votes

I think I'm not the first with that (tested and working) idea, but it's actually possible to communicate with what I would call Native Android Companion App.

As mentioned here, you can just create a local HTTP Server using Java API, emulate basic functionality to extract messages, and this way, send data from Fitbit to Native Android Companion App.

This solution is, however, very unreliable. Still, it's better than nothing. I hope that Fitbit won't lock out that way, at least until they provide us with better solution.

Best Answer
0 Votes
Thanks RavMahov. Let me try this and if possible go ahead with this.
Best Answer
0 Votes

Using nanohttpd works perfect for me.

 

Just define the dependecies:

implementation group: 'org.nanohttpd', name: 'nanohttpd', version: '2.3.1'

Create a derived class and add code to parse and create json data.

public class Nano extends NanoHTTPD {

private static final String TAG = "Nano";
MonitorActivity activity; // My Activity


public Nano(MonitorActivity activity, int port) throws IOException {
super(port);

this.activity = activity;

start(NanoHTTPD.SOCKET_READ_TIMEOUT, true);
System.out.println("\nRunning! Point your browsers to http://localhost:" + port + "/ \n");
}

@Override
public NanoHTTPD.Response serve(IHTTPSession session) {

JSONObject object = new JSONObject();
try {
Map<String, String> files = new HashMap<String, String>();
Method method = session.getMethod();
if (Method.PUT.equals(method) || Method.POST.equals(method)) {
try {
session.parseBody(files);
} catch (IOException ioe) {
ioe.printStackTrace();
} catch (ResponseException re) {
re.printStackTrace();
}
}

if (session.getParameters().get("MsgType").get(0) == null) {
object.put("Result", "Missing MsgType");
Log.v(TAG, "Missing MsgType");

} else {
if (session.getParameters().get("Msg").get(0) == null) {
object.put("Result", "Missing Msg");
Log.v(TAG, "Missing Msg");
} else {
Log.v(TAG, session.getParameters().get("Msg").get(0));
JSONObject result = ProcessClockface.Request(activity, session.getParameters().get("MsgType").get(0), session.getParameters().get("Msg").get(0));
if(result != null)
object.put("Result", result);
else
object.put("Result", "Errors processing data!");
}
}

} catch (JSONException e) {
e.printStackTrace();
}

return newFixedLengthResponse(object.toString());
}
}

In your activity start and stop the server

 


// onCreate:

try
{
nano = new Nano(this, port);
} catch (Exception e) {
e.printStackTrace();
}

// onDestroy:
nano.stop();

 

In the companion using fetch and submit data via post:

function sendData_via_POST(type, data) {

var formData = new FormData();
formData.append('MsgType', type);
formData.append('Msg', JSON.stringify(data));
    
fetch(CONST.END_POINT_LOCALHOST, {
  method: 'POST',
  body: formData
}).then(res => res.json())
.catch(error => console.error('Error: ' + error))
.then(response => console.log('Success: ' + JSON.stringify(response)));
};

This works for me, without any problems.

 

Best Answer

Thanks for your input! In your Code from your "derived class" you use:

ProcessClockface.Request( ... )

Is ProcessClockface your own class somewhere in your Project?

Best Answer

Yes, in this function i process the data from the device and construct a json-object with the resulting values, which will be send back to the device.

This is specific to the application.

 

Best Answer
0 Votes

hello, can anyone help me with my project? its related to this topic, i can pay. thanks

Best Answer
0 Votes

hello, can anyone help me with my project? its related to this topic, i can pay. thanks alot

Best Answer
0 Votes