AguaClara / post.bluetooth-DEPRECATED

The bluetooth widget for connecting POST with the turbidimeter.
0 stars 0 forks source link

Guide to old code #3

Closed eak24 closed 8 years ago

eak24 commented 8 years ago

Hey there @danelimjoco last semester I came up with a simple bluetooth interface that also was able to parse the json correctly. It's actually all in this repo if you want to give it a looksy! feel free to use as much or as little of it as you like. Last year I had it working so it would be launched by an ODK test form I wrote, connect to the BT turbidimeter, parse the value, and I was at the point of trying to get it to return a value before I ran out of time on that. Hope it helps! Specifically, here's the code that does all the good stuff: https://github.com/AguaClara/post.bluetooth/blob/master/app/src/main/java/org/post/aguaclara/post_bt_turbidimeter_widget/MainActivity.java Feel free to post any Qs here and make sure to mention (@) me so I get an email!

danelimjoco commented 8 years ago

Hi @ethan92429 , thanks for the link! That's actually the same code Jay told me to edit, since it has most of the important stuff already.

I'm having trouble filling the rawWaterTurbidity field with a plain double. I have the following code in my java app:

Intent intent = getIntent(); if (intent.getAction() == "org.post.aguaclara.post_bt_turbidimeter_widget.COLLECT") { Double mAnswer = 10.0; intent.putExtra("rawWaterTurbidity", mAnswer); setResult(RESULT_OK, intent); finish(); }

And I believe my xml file is exactly as the ODK specifies it has to be. I think I was able to make a JSON object and I'd like to parse it using the methods you have. However, I need to be able to send a double that I specify first in order to move on to that step. Any help would be appreciated, thanks!

eak24 commented 8 years ago

@danelimjoco sorry for the late reply! I've been in Panama all week. What error message are you getting? You should be able to see them in the error message console in Android studio when you install your app. Then trace back the error. If it is in the ODK app, you can get the POST.collect repo locally (a fork of the ODK app) and connect to your comp to trace the ODK side of the error. Let me know if you have any questions about that and good luck!

danelimjoco commented 8 years ago

Hi @ethan92429, I recently revamped my ODK to try a different way of making the button for rawWaterTurbidity and it all worked out, but I got to the same issue as before. I think the problem isn't with ODK. I confirmed with print statements that I am filling the rawWaterTurbidity field with the value I want. So I think the issue is that when the finish() method is called at the end of my method and the app closes, the ODK page is refreshed and the Raw Water Turbidity field is not filled. Do you have any idea how I can close my external app and go back to ODK such that the field is filled, instead of it "refreshing"? I'm not getting any error messages.

eak24 commented 8 years ago

Hi @danelimjoco I'm not sure what the problem is, but I imagine it's something to do with how the ODK form calls the external app... What does the form definition that is calling the external app look like? Perhaps it doesn't properly save the double in the intent to the form data? I think @asm278 is working on the same challenge with defining the CDC module. Once y'all figure out how to do this, maybe we should start a guide for developing an external app in the POST wiki. And just in case you haven't seen it, here is the official documentation on onActivityResult() method. We need a good way to keep a record of all the forms we've used. I think we should be doing that in the POST repo, or a new post.odkForms repo.

danelimjoco commented 8 years ago

@ethan92429 I have this snippet from the form definition that calls the external app. Does it look right to you?

<input ref="/data/plantData/consented/rawWaterTurbidity" appearance="ex:org.post.aguaclara.post_bt_turbidimeter_widget.COLLECT()"> <label ref="jr:itext('/data/plantData/consented/rawWaterTurbidity:label')"/> </input>

rawWaterTurbidity is defined properly above within consented. I'm also pretty sure did the bind nodeset thing properly:

<bind nodeset="/data/plantData/consented"/> <bind nodeset="/data/plantData/consented/rawWaterTurbidity" type="decimal"/>

I'll try to get a new repo up soon as well.

eak24 commented 8 years ago

@danelimjoco when the odk collect app launches the BT app, do you see that an intent is available with preset fields? I'm looking at the ODK external apps documentation here that says

A text/decimal/integer field with an "ex:intentString" appearance can specify extra parameters that are passed to the external app, in addition to the "value" parameter that holds the current value for that field.

That suggests that the intent coming with the app has a "value" extra. Indeed, when looking at the breathcounter app code here it is clear that you need to use intent.putExtra("value", mAnswer) to change the passed value. I recommend looking carefully at that breathcounter app. It's very useful!

danelimjoco commented 8 years ago

@ethan92429 Thank you so much! I'm able to populate the field now.

eak24 commented 8 years ago

@danelimjoco did you just have to change the name of the extra field in the intent object? And I think this process is complicated enough to warrant a wiki page. Would you be interested in writing one about how to set up an external app with ODK? I find the ODK documentation extremely hard to follow.

danelimjoco commented 8 years ago

@ethan92429

Very annoying, small change. When you use the putExtra method, you have to write "value" instead of "rawWaterTurbidity." I thought you were supposed to use the name of the field you're filling, but I guess not.

Before: Intent intent = getIntent(); if (intent.getAction() == "org.post.aguaclara.post_bt_turbidimeter_widget.COLLECT") { incomingIntent = intent; Double mAnswer = 4598.0; incomingIntent.putExtra("rawWaterTurbidity", mAnswer); setResult(RESULT_OK, incomingIntent); finish();

After: Intent intent = getIntent(); if (intent.getAction() == "org.post.aguaclara.post_bt_turbidimeter_widget.COLLECT") { incomingIntent = intent; Double mAnswer = 4598.0; incomingIntent.putExtra("value", mAnswer); setResult(RESULT_OK, incomingIntent); finish();

I can write a wiki page. Agreed that ODK documentation is pretty hard to follow.

eak24 commented 8 years ago

Haha! That's what I figured. The world of coding seems to be full of such exacting requirements. It's the smallest details that take the longest to solve. Thanks for writing the wiki! I'm going to close this issue cause it's running a bit long and I think we've briefly covered how much the old code does. Please open another issue when another problem arises! @danelimjoco