20 April 2017
After implementing a class hierarchy and a unified point of database access via a Content Provider the core mechanisms of my app were in place: the ability to do basic CRUD (Create, Retrieve, Update, Delete) actions on the various types in my database. It was time to put the finishing touches, not all of which were trivial.
The first major task was to enable the user to create notifications
for the various data types, most of which had date fields attached.
However, in order to get the database functionality working, I had
skipped any attempt at verifying user entered dates, which were stored
in the SQLite database as plain strings. While a well intentioned user
would no doubt enter real dates instead of "next week", it
didn’t seem right to cause notifications to fail for incorrectly written
dates, either silently or explicitly.
Related was the question of the order of items on the lists of terms/courses/assessments. Keeping with “getting it done” I had sorted them simply by the name of the entry, knowing I would eventually want to “do it right”. That time was of course now.
First I enforced that user entered dates be in a specific format,
23 April 2017. But while simple to enter by text and
obvious to read, this type of data is not easily sortable. I needed to
translate dates into something more like a timestamp for storage in the
SQLite database. Thus was a class born DateFormatter, which
contained several static helper methods to translate dates from my
chosen human readable format, to a timestamp, and back again. I would
also add methods to translate dates into Unix epoch timestamps, since
this is how I would schedule notifications.
Actually getting notifications working wasn’t entirely trivial either, but not from a coding standpoint. This was the first time I ran into the stumbling block of the Internet: host to information about many different ways of working with Android apps, all from different APIs and few marked clearly.
I pressed on, found a strategy that worked and implemented it.
Testing it consisted of forcing the menu items to schedule notifications
not on the date specified, but some fixed amount of time, say 5 seconds,
after SystemClock.elapsedRealtime().
Next up was attaching camera photos to notes. I had kept putting this off because it felt like it would be complicated, but truly Android makes the simple things complicated and the complicated things simple. The actual code to call out to the camera to take a picture?
public void takePicture(View view) {
Intent takePictureIntent =
new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(
getPackageManager()) != null) {
startActivityForResult(
takePictureIntent,
REQUEST_IMAGE_CAPTURE);
}
}
Taking the image and forcing it into and out of the database was
somewhat more involved, but not very. SQL has a datatype
blob for a reason. (Though better practice would
probably have been to save a URI for the photo)
SMS was scarely more complicated:
private void sendSMS() {
Uri uri = Uri.parse("content://contacts");
Intent intent = new Intent(Intent.ACTION_PICK, uri);
intent.setType(
ContactsContract.
CommonDataKinds.
Phone.CONTENT_TYPE);
startActivityForResult(intent, 1);
}
There were a few other minor details to fulfill various requirements or my own sense of pride:
ArrayListInternalException that had not
disrupted anything but been hitting the logs since the beginning of the
projectContentProviderUltimately I learned a lot, including that working with XML is not my idea of fun and that mobile app development might not be either. You can certainly develop something rapidly if you know what you’re doing, but boilerplate is everywhere. Android Studio seems almost a necessity, just to keep track of the massive Android library. Discerning which information is from too far in the past to be of use, which information is for an API too far in the future to be of use, and which information is just right is a massive pain.
Making it all look good is certainly not as easy as it looks. It may be some time before I revisit Android development, but I’m glad I was pushed to do it.