Vagabond 1.0 – Nearly Here

Yes that’s right. After much toil, and missing my self-imposed deadline for a release, I’m nearly complete with the program and can give it a 1.0 which means that it’ll go into General Availability.

I’m not posting Vagabond News on its website because I want that strictly to be a place to get the program from and a reference for information that developers would be interested in. Just wanted to get that out of the way as well. 🙂

Right now the program is about 98% done. All that remains is to test two additional features, push to the repository (assuming they work, which they will) and then build Debian, RPM and Source Taballs for deliverables. I haven’t built Debian packages for quite some time so I’m having to go through several refreshers to bring myself back up to speed on the workflow.

After this release, I have some additional features I want to work in so development will continue alongside general maintenance coding. I want to be able to add support for choosing to use either the official Android SDK or to use the Replicant SDK. This is more of an ethical decision as I feel like Replicant is a great choice for developing in an open-source manner but might not be the best idea if you’re writing Android to be published on Play. But the option should be there. I’m also considering the idea of implementing SDK Administrative Task Shortcuts. These are commands that can be passed to Vagabond that will inflate to more robust tasks passed to the VM that maintain the SDK.

If all goes as planned, and work and life leave me alone long enough, I can potentially have this ready to go by the end of the week.

Vagabond – Update

Aside from the getandroidsdkdl script that I was offering for people who wanted to get started with Android Development on Linux, another cool tool I wanted to throw out there was a script I call “Vagabond” which is a Vagrant deployable which automatically configures a development environment that you can use for Android Development on your Linux computer. In fact, it may prove far easier to use it instead of the getandroidsdkdl script (it actually builds off of it). The actual Vagabond script isn’t available yet but I’m letting a rather close circle of friends test it out first before I make it public which shouldn’t be too far off from now. I wanted to give an overview of what it does.

If you’re unfamiliar with Vagrant, follow the previous link to get a better understanding of what it is.

What is Vagabond?

Vagabond is little more than a bash script that you’ll download and execute. Once you execute it, all you’ll need to do is sit back and relax while it configures the VM, installs all of the requisite packages to both update the base VM and the required packages for the Android SDK, and then exposes the synced directory from the guest to the host via host’s PATH and that should take care of everything. The user can then install an IDE of their choice on the host and run the Android SDK tools from their host computer.

Got that? To further simplify, the purpose of the Vagrant image is to host and isolate the the Android SDK and to make it even more portable since it’ll exist exclusively in a VM. The Vagrant Provisioner Script, in tandem with the Vagabond Script, exposes the SDK hosted in the guest VM to the host machine. If it still doesn’t make any sense, you may need to read up on what Vagrant is so that it sinks in a little more.

Vagabond Usage

Vagabond is, and will continue to be, stupid simple to use. I’m planning on adding some additional features to it but for right now, it only requires that you provide it with a directory where you want Vagrant to install and configure the VM in. That’s it. The rest is up to the script.

vagabond.sh [vagrant-project-directory]

Vagabond Details

Vagabond relies on three different pieces of software – Vagrant, Git and Zenity. It will check for the existence of these three on the computer before attempting to do anything. If either one of these are missing from the computer, the script will fail and return an error code specific to whichever program was missing. These codes are detailed in the comments in the script.

Clearly, the reliance on Vagrant should be rather obvious. Git needs to be installed since Vagabond will pull down the Vagrantfile and bootstrap provisioning script from my GitHub. Zenity is used to display the output from Vagrant while it’s running the VM configuration and provisioning script. The choice to use Zenity was made since the output from the provisioning script couldn’t easily be piped back to the terminal that was running Vagabond. I’m still not really sure why this was the case but that’s what was happening. If I can figure it out, or if someone a bit more skilled at bash scripting than myself modifies the source, I’ll yank the Zenity dependency out of there. I can’t say I don’t entirely dislike it though.

Vagabond then attempts to make the directory that the user specified while launching the script. No real magic here. The only thing is that it will check to see if the directory exists prior to running mkdir. Some may see it as a redundant check since mkdir will cater to already existing directories but I wanted some conditionally verbose output. Sue me.

Next Vagabond will move into the new directory and use Git to clone from my GitHub repository that contains the Vagrantfile and bootstrap Provisioning Script. Details on the Vagrantfile can be found if you read the Vagrant documentation. The purpose of the bootstrap script will also become evident as well. At least what it does with regard to Vagrantfile. Cloning from the GitHub will make a vagabond directory inside the directory the user specified for the Vagrant Project and we don’t want that. Vagabond will move the cloned files out of the cloned vagabond directory into the Vagrant Project directory and then remove the cloned directory.

At this point, we’re ready to use Vagrant. Now that Vagrantfile and bootstrap are in place, a call to vagrant up will use the Vagrantfile to configure the VM. Vagrantfile will then rely on bootstrap to supply additional configurations and instructions to the VM. The Vagrant Box used is the hashicorp/precise32 (Ubuntu Precise 32-bit). All other Vagrant configurations are defaults. The bootstrap Provisioning Script does the following:

  • Update apt repositories
  • Upgrade the system as well as install base dependencies for the Android SDK
  • Use a modified version of my getandroidsdkdl script to download the Android SDK from Google. This script will also unpack the SDK into /opt in the VM and configure permissions on it.

Once this is done, Vagabond will expose the synced directory, which is linked to the directory in the VM that contains the SDK, to the host system via a modification to PATH. That’s it. After that, so long as the VM is running, the host will have access to the SDK. The user can download and use whatever tools they want. Since the SDK exists exclusively in the VM, you can port the VM to anywhere you want.

What’s Next?

As I mentioned before, I’m letting a few people test this before I give it GA. Once I get those test results back and make some modifications to the script based on those tests, the version will be locked as 1 and released for GA. Stay tuned!

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.

Sometimes, Silence is Bronze

I have officially gone under a rock.

Most of it was my fault. I gambled (in an ethereal sense), I lost (more than just money mind you) and now I’m paying for it. So-to-speak anyway.

So the things that I have been working on – LinuxInstall and WIPN for example, have been without my presence for some time and may continue that way for just a bit longer.

That doesn’t mean I haven’t been busy and working on things in abstentia.

All I’m going to leave here is this single image.

The Oily Cow

The Shopper – Questions, Questions

This morning I was able to complete another critical portion of the feature set: item deletion. It now works for either single or batched deletion. In other words, you can delete either single or multiple items in one fell swoop. Of course, there’s no way to undo this but I’m not too concerned about that right now.

Something struck me though. The original version of The Shopper had a visible dynamic calculator. As the user added, deleted, and edited items, the calculator would display the cost with and without sales tax applied. It also showed the total number of items in the list. More accurately, it showed the total of items that should be in your buggy (it counted item quantities rather than strictly the number of items in the list). I thought this was a really useful feature but for some reason or another, when I was drawing the initial UI design drafts for the current version, it never made it in. It still isn’t in there.

In fact, the degree to which it’s missing is evident in code as well. There are no accommodations for calculating a running total for the items currently existing in the list. None.

This might be a little bit of a problem. Adapting the code that calculates these values from the old code base isn’t a problem. I just need to figure out where the hell to put the calculator at. Originally, it was below the list of items (as shown below). I’m thinking that maybe it should go there again? Or maybe above the list? I’m not sure.

The Shopper v1.0 showing the dynamic calculator below the list contents

So here’s another screenshot showing the current iteration in landscape mode. Any thoughts?