Projekt Vagabond Isn’t Dead. I Swear.

I’m starting to get back to a point where I can start working on this thing again and it’s like flipping through a kindergarten yearbook. Every now and then I’ll find something that makes me think I had a stroke of genius. Other times it’s like seeing a photo of that one kid you hated more than bees. Like you’d prefer taking nails hammered into your ears than listen to that twat for a single second more than you had to.

Tonight I had more of the latter instead of the former.

This thing has taken several forms starting out as a PoC Bash Script that was around sometime shortly before Ohio Linux Fest 2014 to a full-blown 15,000+ line C++ program which would have worked but I didn’t realize how insanely asinine packaging software has to be (I don’t have that kind of time, especially these days). But then I had the bright idea to simply make a Vagrant Box (I was already using Vagrant in the backend for handling a lot of things) and just distribute that instead of all this rigmarole. Funny thing here is that there are still quite a few snags.

As I’m typing this, the box is uploading to a cloud store that I’ll make available to the public tomorrow. I ran into some problems during this process.

  • I wanted to be a somewhat normal person and upload the Box to Atlas, HashiCorps repository of Base Boxes. I thought that would have been a great way to make this available to people. But nope! I don’t know if there’s a size restriction on the Box size or what but it just wouldn’t take it. FYI – the Box is about 780MB in size. The goal here is that someone would have simply been able to issue “vagrant up gregfmartin/vagabond” and get the VM. Man that would have been nice…
  • Google pisses me off to no end these days. Tonight was no exception. It still blows my mind that I can’t update or configure an Android SDK Installation from the terminal without either (A) getting bitched at for some ridiculous reason or (B) having to press ‘yes’ to accept fifty licenses for these libraries instead of just being able to use an option that will opt-in to any license requests that would come up. The former makes it literally impossible to automate an installation. Some people on GitHub have described a work around for this but it’s really hacky and I’m a little concerned about the platform portability of solutions like those so I’m avoiding them like the flu.
  • This all lead to my idea of just making the Box and distributing the Box that I’ve manually tweaked. This has issues in and of itself in that (A) the bundled software is static unless the user wants to manually update or (B) wait for me to to update and republish an updated Box (which I REALLY don’t want to do if I’m being honest). This leads into supplementary tutorial material that will be on the project’s website.

In case anyone is wondering, the reason why the Box is so huge is because it contains a fully updated Ubuntu 14.02 64-bit base image, required prerequisite software to use the Android SDK and associate tools/IDE, the Android SDK installation with all 5.0.1 components as well as all Support Libraries that are compatible with Linux (important to note), and the recent version of IntelliJ Community Edition. So yeah, it’s a little fat. That’s the size it would be on your disk anyway.

Tomorrow I’ll get all of the stuff up on the website like documentation and how to do things with it and what you can expect by using it as well.

Something tells me I’m going to have to make some changes to this before too long. 🙂

Development Journal – Smsr Update 001

I’d like to think that I started working on a rough draft with Smsr and then it evolved into something else.

This “rough draft” had a bit of code in it encapsulated in an entity called ConversationThread. A function of this class in particular was really nasty since what it did was take all of the SMS messages on the device and effectively organize them in a cohesive manner that didn’t rely on querying sub-providers like Sms.Inbox or Sms.Sent. The reasoning behind this was that when I would query some of the more specific Content Providers, like Sms.Conversations, the Cursor returned from that query would only contain three fields regardless of the applied projection. In other words, despite the fact that the contract class inherited from base interfaces that gave it the additional fields you’d want, this inheritance doesn’t apply to what’s returned from queries against the provider because these columns are missing from the Cursor. So it wouldn’t contain things like ADDRESS or _ID. And because these Content Providers weren’t designed with the ability to perform SQL Joins via queries (despite the fact that the documentation would lead you to believe so), the only other alternative, really, is to perform several separate queries against several different Content Providers and join them using either MatrixCursor or CursorJoiner. The issue there is (A) how to do this without blocking on the UI thread and (B) because subsequent queries would rely specifically on information that was contained in previous queries, how then to make sure that the queries had completed before attempting to use them?

I really tried to avoid the solution where multiple queries were involved because it just seemed so… lackluster. Not to mention that the idea of tossing back and forth between five or six Cursors seemed like an explosion in the works. But there was a major issue with the way I was doing it originally – real-time updates. Because the backing data was effectively abstracted into this seemingly convoluted construct that didn’t directly bind to the backing data, if something changed in the data (i.e. received a new text message), the structure would effectively have to be completely rebuilt. One pass on building that thing was expensive enough since it relied heavily on Collections. Doing it over and over again could lead to some really janky issues.

So I went back to the drawing board. And what I came out with, after struggling for a bit to understand MatrixCursor, was a solution that does in fact query multiple Content Providers which will yield several Cursors and then combines them into a MatrixCursor which is then given to my custom CursorAdapter. The result here also adds to a modified layout for the Conversation Stubs which uses a LayerDrawable to get the contact’s image (default if none) and apply a gradient over top of it that leads to the other half of the list.

Unfortunately, this change has broken the Activity that will show the Conversation Thread because the data that’s now contained in the stubs is different than what that Activity was looking for in the first place. But the stub viewer looks nice! 😀

If you want to follow along, the branch that this work is being done on is the “rewrite” branch.

https://github.com/gregfmartin/smsdemo/tree/rewrite

Development Journal – Smsr

The SMS client that I’ve been working on for Android is now being renamed to Smsr (even though the root directory of the project will still say sms_demo).

I’ve uploaded the source code to Github so feel free to take a look at the source, fork or do whatever the hell you want with it. I’m going to be updating the contents of the wiki and the project landing page as major changes are made to the upstream build.

http://gregfmartin.github.io/smsdemo/

Development Journal – Android SMS App

For the longest time, I’ve been wanting to write a SMS app for Android. The issue originally (and still is unfortunately) was that if you’re running a device that has a version of Android less than KitKat (4.4.x), a programmer doesn’t have access to native public-facing APIs to get access to these Content Providers. Instead you have to rely on the Reflection APIs to poke around for them and, if they’re there, use them that way. It might not seem like it at first but Reflection can be a bit heavyweight on more resource-constrained devices (which can potentially toss ANRs or even cost battery cycles) and also makes for some really nasty looking code. I’ve worked on several projects where Reflection was the order of the day (especially for things like accessing Enterprise Configurations in WifiManager) but unless I really had no other choice, I tried to stay away from the Reflection solution as much as possible. Even going to the lengths of not writing this SMS app I wanted to do for so long because there wasn’t a public API for it. Enter KitKat with these packages and now I’m going to town.

Putting aside the fact that Google likes to arbitrarily break your code with new upstream versions, the package that contains the contract classes for these Content Providers, android.providers.Telephony, is actually quite solid. Unless they go ape-shit on this package like they did with ContactsContract (which is an absolute fucking nightmare to work with), we should be okay for the time being.

I’ll save the technical discussion for another post (or even a video) but what I wanted to do here was showcase the current state of the build that I have for the SMS app. Honestly I’ve spent more time trying to figure out the nuances of the contracts and how to use them and fucking around with 9-Patch than anything else (9-Patch is cool technically but why can’t someone at Google make decent documentation?) Additionally, I wanted to provide a tentative roadmap for where this is going.

A listing of all Conversation Stubs
A listing of all Conversation Stubs

Here’s a screen capture of the home screen which will display what I refer to as the “Conversation Stubs.” No, those aren’t native constructs in Android, it’s a custom object that I’ve built for this app. The goal here was simple – after doing all the magic necessary to sort the messages to have them make sense, grab the most recent one and from it derive the contact’s display name and a 45-character snippet of the message body. If the snippet length equals 45-characters, an ellipsis is appended to it to indicate that there’s more to the message than what’s visible. What’s missing here is an indication that the message was sent from you to the intended recipient (coming in the next nightly build). By the way, I swear I didn’t plan the colour of the ActionBar to match that of my site. 😉

Pressing on one of the Conversation Stubs will bring you to another screen which will display the entire Conversation Thread.

A Conversation Thread listing
A Conversation Thread listing

As with Conversation Stub, a Conversation Thread is not a native construct to Android. Now if you’ve done a little digging into the package yourself, you might be thinking why not just use the Conversation Contract? I’ll do more on that in the technical discussion.  Although there are no clear visual cues as to who said what, messages that have been sent from you to the recipient are on the right side and messages from the recipient to you are on the left. Each message is time-stamped currently using 24-hour format (this will be customisable in a later build). The thread recipient’s display name occupies the ActionBar in the top-left. The list of messages is sorted in descending order from the top and will automatically start from the bottom when opened which will display the most recent messages. Right now, there’s not much else here other than what you see.

 

Current, if short, Preferences
Current, if short, Preferences

The last point of interest here is the slowly building Preferences. One of my targets here is to have a decently high level of customisation while still retaining the overall look-and-feel of the app that I want. The bottom option is the more interesting one right now. As I mentioned before, KitKat will allow a user to specify an app to be the dedicated Messaging app. Of course I want the user to be able to choose this one as the default if they wish to do so. Pressing this brings up a dialogue that will allow you to choose the default app.

Overall, the goal here is quite simple. I prefer as vanilla of an experience on my Android devices and I like the Google Play Services and default apps but I have a serious beef with Hangouts. It just feels too clunky and I wanted something a little more back-to-basics. The current build cannot actually compose or send SMS yet (coming in two builds) nor can it determine or store draft messages (coming in a build after the previously mentioned one). MMS is also not yet handled but is coming shortly. I do not want to do anything fancy like integrate with Google Accounts like Hangouts does. I want this to be a pure unadulterated SMS/MMS experience. Nothing more.

Some tentative features that I have in mind though are sticky messages, cherry-pick deletion, hidden threads, export a conversation thread to a file (I’ve actually had a lot of interest in this from some clients for legal reasons) or print a conversation thread directly to a printer (relies on Android Print Services) or email a conversation thread to an email address, bulk messaging (one-to-many) and group messaging (many-to-many).

I’ll do a technical discussion on how to use the SMS Contracts and all of the nuances that I’ve discovered with them soon. Either way, I’m looking to have a first version published by the end of the month.

The Shopper Development Update – C

This morning was by far one of the most productive mornings I’ve had in quite a while. I posted on Google+ that I was definitely in workaholic mode and that certainly wasn’t a lie.

So where to begin with The Shopper…

As a developer, I have a really nasty habit of incorporating test code into production code. This particular type of injection is required sometimes when I’m testing out a portion of the API that I’m unsure of which is fine. However what isn’t fine is when that code sticks without any type of polish. It then sticks out like a sore thumb and begins to pollute the rest of the project.

I like to think of the theory of broken windows here which I first heard of reading The Pragmatic Programmer.

So I sat back and literally, on my dry erase, sketched out the workflow as it should be at this point and catered the code to match. The results were astounding. I was actually seeing a performance gain on certain methods. Importantly I didn’t feel like I wanted to rip my hair out thinking about the mess I’d made.

A very important feature was completed and that is contextually sensitive menu items in the ActionBar. Logically it doesn’t make sense for all of the icons in the ActionBar to be present all of the time. It makes even more sense to only have certain icons present when certain conditions are satisfied. The benefits here are batch operations and to prevent users from doing something that, at that time, doesn’t make any sense (also eliminating exceptional circumstances). For example, you should be able to add an item at any point in time so the add item icon is present at all times. You can’t edit an item without first selecting one so that icon is hidden until an item is selected. You should be able to delete any number of items so when at least one item is selected, the delete icon is present. However you can’t batch edit so when more than one item is selected, the edit icon disappears (this is something that I think would be nice but would be difficult to express cohesively via UI).

For the time being, all custom styling has been dropped and the theme reverted back to the default Android Holo Light theme. Styling is a little more involved than I’m willing to give time to right now so it’s going to have to wait until a later date when more important things are complete.

The last big thing that was finished was a bit more technical.

Google has openly admitted that using the findViewById API is a bit expensive. More importantly, it can become cumbersome and redundant. A while ago I devised my own fix to the problem: why not store single references to the Views that are relevant per Fragment and Activity and issue calls to findViewById just once post inflation? The references were wrapped in a static class that was unique to each Activity and Fragment and this worked for some time. However some things were painfully obvious about the design here. This was taking redundancy to an extreme. Each Activity and Fragment had their own class which had the same design and same interface just different members. Typing this thing out over and over again was tiring but more importantly it wasn’t very good practice.

A thought occurred to me this morning: why not parameterize the members of this class? Seeing as how that was the last “least common denominator” challenge yet to be tackled, overcoming that meant that a separate entity could be created that could be distributed to each Activity or Fragment that required it. More importantly, if designed properly, it could hold instance-based references to other things like MenuItems. Thus ReferencePool was born.

The details are simple really. ReferencePool contains a collection that stores a nested collection (more specifically a LinkedHashMap that stores a SparseArray). The key for the parent collection is a Class instance while the key for the nested collection is an integer ID which is expected to be the Android-generated ID found in R. The reason for this is that neither collection should be explicitly tied to any one particular descendant class (with the exception of SparseArray but it stores Objects). That being the case, it would be really easy to lose the meaning of the object in syntax if the interface were not designed properly. Using a Class as a key helps to enforce, logically, that one SparseArray is linked to a specific type while making sense syntactically (derived contextually from reading the source). The method that gets an object from the collection uses generics (actually the whole class does) to return an Object casted specifically to the Class used as the collection key.

Despite my efforts to keep the collections as type-agnostic as possible it would be a valid statement to say that to some degree they aren’t. SparseArrays store Objects thus regardless of the Class key used in LinkedHashMap, you realistically could dump anything in there so long as you remembered the integer key for the Object in SparseArray. The goal was more syntactic. Originally I left it up to the client to cast out to whatever they needed by simply returning Object from the get method. So you either had one of two client situations: declaration with casted assignment or anonymous classes with nested parentheses; neither of which I wanted in client code and didn’t really suit the intended nature of the class and its interface. What I got instead, after implementing generics for the get method, was an inline generics declaration before the method call which looks a lot nicer and does what you would expect it to do. An example is here:

referencePool.<EditText>getReference(...).someMethodFromEditText()

So far this is working out nicely.