I have mastered the first steps of Droid-Fu! Mobile Metagenomics will now blissfully continue working if a user hits the home key and does something else for a while before returning to see their results. There is a bit of awkwardness involved in testing this, because it only works correctly after I do a complete build of the .apk file and manually install to the emulator via command line. (Essentially what that means is I have to pretend I’m doing a code release each time I test a change…) Things that still need work/could be added include:
OTUs mode – currently doesn’t do anything. (Edited) Done!
Loading from Server – currently not implemented. (Edited) Done!
Notification Bar Message on results complete – not implemented, not looked into yet. Difficulty: Unkown (probably Medium)
Indeterminate progress indicator in title bar during downloads 2..n – not implemented, totally optional. (Edited) Not possible from what I can determine. It seems to be either-or with this and the progress bar. Though I could’ve sworn I used to have both…
From there it is just a matter of documentation, code cleanup, youtube videos, and publishing.
Here are some of the new features that are now included in OS Metagenomics:
Saving/Loading Your Data
This new feature is more of a developmental infrastructure change that gives the app a better use of persistent data and what we could do with it. Before, saving your data in orkut meant saving a JSON formatted object in the form of this:
This only allowed the application to later retrieve the titles of the data and nothing else. Later, an idea came about allowing the application to retrieve the actual data from this list of titles obtained in the Your Data section. So in order to do that I had to change the JSON formatted object to hold the phone number with its respective titles, like this:
What this does is allow the user to retrieve his/her data much quicker. Instead of filling in the input fields, if the user saved their data into orkut they can now view their previously saved data in the Your Data section as a drop-down list. After choosing a title to access, the app searches it’s internal application data for the “savedResults” object and parses the JSON string, searches for the chosen title and remembers the corresponding phone number associated with it. The app then sends a request to our server to retrieve the data, which is similar to “filling in” the form for you and loading the data for you.
The Friends section has been successfully added to the OS Metagenomics application. With this new section a user is now able to click the View Friends Data button to retrieve a list of drop-down lists. These drop-down lists are separated by the names of the user’s friends and contain the data the friends saved into orkut, not the data they saved onto the server. So, if someone would like their friends/colleagues to see which metagenomes they now have data for, they would just save it into orkut when viewing the data and their friends would see it in their Friends section. Also, a Request Data button is located next to the drop-down list. Clicking this would send a message to the friend asking them for the data that was chosen in the drop-down list. (orkut is actually not allowing me to send this message for some reason. Every time I try it a message at the top of the application screen shows saying “You have temporarily been disallowed from performing this action. Please try again after some time.” This may be disabled during the development phase of an application but it seems that orkut knows I’m trying to send an email which is a good thing ).
I’ve had a few minor breakthroughs on the Käppler code I wrote about yesterday. I now have a Droid-Fu / MM test application with a working function mode, including pretty progress dialogs and bars that actually behave correctly! (Those who were in the lab during the week that I spent getting those to work the first time know how much this success means to me…) I’ve begun migrating the new code I developed into the actual Mobile Metagenomics project and I’m having to make some adjustments.
The most drastic change I’m currently considering is abolishing the two-activity model that MM currently employs. What I mean by that is: MM currently has two major phases (actually Android activities) called MobileMetagenomics and ResultView. The first activity is the one where the user is presented with menu options to choose the type of annotation that they’d like to perform. The second is where the user goes as soon as they click the “upload” button; they are shown progress dialogs etc and eventually their results. This is all good, sensible, and very object-orientated.
Unfortunately, due to the nature of the application and the concurrency that I’m trying to implement, the two-activity model is proving problematic. My single-activity test case doesn’t have a ‘menu’ sort of activity loaded up in front of the results; consequently, it behaves just fine if I hit the home key and relaunch it a bunch of times while it does work for me. On the other hand, two-activity MobileMetagenomics is currently choking on the handoff between MobileMetagenomics and ResultView. There probably exists some clever way of making them get along, but I’m not sure it is worth the time investment to find this method.
The other solution that I’m considering involves hiding (or destroying, or something) pieces of the UI based on what the user is doing and making visible other parts of the UI as needed. ResultView already has some UI elements hiding that are only displayed when a graph is requested, so that part shouldn’t be an issue. What concerns me about this approach is how to handle the user doing one annotation and wanting to go back to the menu. Currently MM handles this just fine – the back button kills whatever work they were doing and returns from ResultView to MobileMetagenomics.
I’ve definitely got some thinking to do before I figure out the proper course of action. The good news is that the code to actually do the uploads asynchronously works. I just need to figure out how to slot that code into MM properly.
A few months back I wrote a few blog entries about some Android code written by Matthias Käppler, an Android developer from Germany. He has written several ‘helper’ classes for Android methods which he felt needed to be improved. While folks like myself and Käppler often complain about the features of certain Android methods, I want to make it clear that we actually really appreciate the fac that Android lets us write our own methods to replace theirs. The Android team has a lot on their plate, and if programmers like Käppler can help them along in certain areas, more power to them.
The real focus of my blog entry today is to talk about what is currently going on with MM. As I said in lab meeting recently, the realtime code broke and after a few days of trying, I still couldn’t figure out why. I was browsing Käppler’s page on his old concurrency code that I was using and I saw a little note informing me that he had better code to replace the old classes with. I made the executive decision to bite the bullet and learn a new way to write concurrent Android code.
Since then I’ve been struggling a bit with learning the new BetterAsyncTask, but I’m finally making some headway. I have a semi-working proof of concept, and I’ll probably comment on Käppler’s blog to get help with a few things I can’t figure out. Unfortunately he’s not been able to post any example code yet, so I’m left wandering through his code and javadoc to figure things out. So far, I have code that mimics the ‘Function mode’ annotations of MM, but doesn’t have any pretty dialogs or progress bars yet. Käppler says he’s made these things better, and I’m sure once I figure out how to use his code, I’ll have some sweet dialogs / bars.
Edit: I found a hidden gem of knowledge about the Android Manifest that should save a lot of headache in the future. I was having an issue where new instances of my application would be launched every time I clicked their launcher. My desired functionality was to resume the original instance which I’d moved away from by hitting the Home key. Apparently, this is not the default functionality. In order to get this functionality, one must add the following line to their activity tag in the android manifest: android:launchMode=”singleTask”
Hazzah! Display hook up and disconnect now works without hiccup, Compiz Fusion was indeed the culprit. Lots of ways to go about fixing it, some folks had command-line methods in the forums, but often those would require either running the command yourself each startup (or at least each startup when you’re planning on using an external display), or automating that code to run each boot. My method seems a bit easier, I just went into the package manager (System->Administration->Synaptic Package Manager) and searched Compiz, and marked all parts for complete removal. Metacity is probably already installed, so it will take over for Compiz as soon as the removal takes place, but while you’re in package manager, double check to be sure you have Metacity already installed, and if not, go grab it. I’m sure there are other alternatives, both in methodology and in which display driver you replace compiz with, but this fix worked for me!
I was comforted to see that Josh’s netbook locks up when an external display is connected too, and that I wasn’t the only one having that issue. A little forum hunting found that it has to do with compiz fusion. Disabling (and removing) compiz and instead using Metacity seems to have worked for others, I’m in the process of trying that fix right now, and I’ll write it up if it works. Fingers crossed…
I have a fun trick to share, but first I’d like to give a little background on why I needed it. The Eclipse debugger is great, however, Android doesn’t always let it see everything. Android likes to hide stuff from us programmers, and we can only see variables inside of a certain scope in the debugger. I was recently trying to debug a null error in this line:
and Eclipse was telling me that I had a null error at that line, but not giving me anything specific as to why. Furthermore, the debugger was able to see some pieces of data involved in this line, but not everything. Given the limitations in Android for seeing certain variables, I often will declare a dummy variable and stick whatever variable-from-another-scope I need inside of that to peek at it in the debugger. This is a nice trick that often helps, but I found another cool Eclipse ‘debugging hack’ that solved this issue really quickly for me.
I broke up the offending line of code into several lines such that it read:
resultListView.setAdapter (new ArrayAdapter (ResultView.this, android.R.layout.simple_list_item_1, task.getResult()));
and, sure enough, Eclipse spit out a different line than the one it previously had given me. It told me specifically which piece of the original ‘line’ of code was the problem. (I’d like to note that I tested this with an intentionally bad null statement before I trusted it for debugging purposes…) So, the next time Eclipse tells you that one of your lines of code is junk, remember that you can avoid all that gross thinking stuff by mashing the enter key a few times and running it through the debugger again. What a brain-saver!