PB Developing Android On Android Nov 2013
PB Developing Android On Android Nov 2013
com>
Download from Wow! eBook <www.wowebook.com>
Developing Android on Android
Automate Your Device with Scripts and Tasks
Mike Riley
The Android robot is reproduced or modified from work created and shared by Google and
used according to terms described in the Creative Commons 3.0 Attribution License.
Introduction . . . . . . . . . . . . . xi
Part I — Customize
1. Getting Started . . . . . . . . . . . . 3
1.1 Analyzing Your Mobile Lifestyle 3
1.2 Mobile Personalization 6
1.3 Next Steps 8
Part II — Explore
4. Automating with Tasker . . . . . . . . . . 41
4.1 Introducing Tasker 41
4.2 Talking Clock 43
4.3 Train Station Alarm 53
Part IV — Appendixes
A1. Android Programming Tools . . . . . . . . 187
A1.1 Code Editors 187
A1.2 Source Version Control 193
A1.3 Miscellaneous Tools 198
Bibliography . . . . . . . . . . . . 203
Index . . . . . . . . . . . . . . 205
I would also like to thank all the wonderful technical editors and beta reader
participants who shared valuable feedback, caught typos and other errors,
and generally offered excellent suggestions on improving the quality of the
book. In particular, I would like to thank Mike Bengtson for his awesome
ingenuity, Corey Butler for his progressive technical edge, Ed Burnette for
his pragmatic expertise, John Cairns for his eagle-eye criticality, and Glen
Ferrel for his proofreading expertise and infectious enthusiasm. I also want
to give a big shout-out to Dr. James Withers and Simon Wood (two of the
geniuses behind the awesome SwiftKey Android soft keyboard replacement
program) for their eagle-eye analysis of the book’s content. And a special
thank-you goes to Jan Debiec and Cristina Zamora for their vigilant review
of the material, active participation in the beta, and unending encouragement
for my work. I am so blessed and humbled to be surrounded by such techni-
cally minded people as gifted, kind, and supportive as you.
No amount of thanks can match the sacrifice my family made to give me the
time to devote to another book. I promise to take a break from book writing
for a while so I can make up for lost time with you.
Lastly, a big high-five to publishers Andy Hunt and Dave Thomas for once
again entrusting me to deliver a book worthy of the Pragmatic Bookshelf
imprint. Thank you for giving me such a wonderfully rewarding opportunity
to do so.
The idea for this book was the result of a conversation I had with Pragmatic
Bookshelf publisher Dave Thomas. He had just acquired a Galaxy S3 Android
phone and wanted to know what kind of cool things he could do with it. Since
I have been an Android user since the release of the first commercial Android
phone, the G1, I had a few suggestions on where to start. As he became more
enthusiastic about the broad possibilities of customization and personalization
that the Android platform has to offer, a new book on the subject started to
crystallize.
The objectives of this book are simple. You will learn about how to apply and
codify your mobile automation needs in an Android program. Using both
scripting and native application development approaches, we will build several
programs that not only teach you how to quickly automate your mobile lifestyle
but also give you the skills to extend these programs beyond their tutorial
roots.
Obviously, the platform has matured considerably in that time. It has also
greatly benefited from its open source approach by fostering significantly
faster innovation compared to closed, proprietary operating systems. Take a
look at a first-generation iPhone compared to the iPhone 5. While the hardware
has vastly improved, the primary user interface is nearly identical. Consider
the differences between Android 1.0 running on a G1 phone and Android 4.2
running on a Nexus 4. The differences are striking. The user interface, hard-
ware support, design aesthetics, and everything but the original design prin-
ciples have rapidly evolved for the better. One benefit from this co-evolution
of hardware and software is that you can do things on a modern Android
device that was the stuff of fiction five years ago. To think that on your Android
device you can now do computing on a scale that was the exclusive domain
of desktop PCs for the last thirty years is awe-inspiring.
Let’s also not forget that, like a desktop computer, Android’s home screen
can be highly customized and extended via custom wallpapers, animations,
icons, folder actions, transition animations, and much more. This degree of
personalization allows you to make your Android device fit your aesthetic
values, daily workflow, and communication and notification preferences, not
the other way around. Third-party extensions and widgets also help push the
envelope of what is possible, further contributing to Android’s success and
dominant market position.
Requirements
This is a book about Android, so it should come as no surprise that a must-
have requirement is an Android phone or tablet running Android OS 4.2
(known by its friendly code name Jelly Bean) or newer. The screenshots used
throughout this book were taken on a Galaxy Nexus phone and Nexus 7
tablet.
In addition to the Android phone or tablet, you should have an active account
on the Google Play store, since a good portion of the software used in this
book is exclusively distributed via the Google Play service.
Lastly, while it’s not required, I strongly recommend you obtain a quality
Bluetooth keyboard known to be compatible with the Android OS. I have yet
to use a Bluetooth keyboard that could not be paired with Android, but key-
boards designed specifically with Android in mind are optimal since they often
have special keys associated with functions such as play/pause music, volume
control, toggle between applications, lock the screen, and so on. My current
favorite mobile Bluetooth keyboard is the Logitech Tablet Keyboard for
Win8/RT and Android, shown in the following figure.1 It is a full-size keyboard
and thus larger than other mobile Bluetooth keyboards that have a smaller
footprint or fold in half for greater portability. Plus, Logitech’s full-size key-
board combined with the protective cover doubles as a phone or tablet stand.
1. http://www.logitech.com/en-us/tablet-accessories/android/tablet-keyboard-android-win8-rt
While you are understandably not going to be able to use this keyboard in a
cramped moving vehicle such as a bus or train, it works perfectly fine sitting
on an airplane fold-down seat tray or desk. And since I’m usually bringing
along a backpack during my commutes, the Logitech keyboard adds practi-
cally no additional weight or bulk to the bag. Besides, you will find that the
keyboard is a sanity saver when editing code or documents on the Android
device.
So, that’s it—a phone or tablet, an active Google Play account, and maybe an
Android-compatible Bluetooth keyboard. For folks like me who have been
around since the dawn of the personal computer era, it is simply amazing to
think how far we have come in the past forty years and how much further
we’ll go in the next forty years.
to see how they work, there is no overwhelming reason for average users to
consider jailbreaking and rooting their Android devices.
In the first part of the book, we will look at the variety of options we have to
customize our Android experience. The home screen, lock screen, widgets,
backgrounds, icons, and touch behaviors can all be personalized to your liking.
Unlike some mobile operating systems that enforce a structured, inflexible
design aesthetic, Android offers desktop-like customization in a mobile
package. We will dive into specific examples for home screen renovation. We
will also take a look at extending our Android experience by calling upon a
variety of Android’s hardware capabilities, such as using the headphone jack
to transform our Android applications into better, more convenient, and
information-rich wearable-computing user experiences.
In Part II, we will dip our toe in the automation waters by taking a look at a
very powerful application called Tasker. We will use Tasker to automate sev-
eral personal workflow needs and get introduced to some basic conditional
programming and control flow while we’re at it. We will also delve further into
the programming landscape with the introduction of Scripting Layer for
Android (SL4A). SL4A will allow us to write scripts in Python, Ruby, and
other popular interpreted languages that will execute on Android and give us
access to most of the system-level calls exposed by the Android SDK. We will
conclude the Explore section of the book by actually programming Android
using the native SDK. But instead of using a personal computer loaded with
the Android SDK, emulator, and related development tools, we will write,
compile, test, and deploy these native applications entirely on our Android
phone or tablet.
In Part III of the book, we will apply what we learned in the first two parts by
first creating a custom Android widget entirely on the device—no PC required.
The final set of projects in the book will wrap these scripting and automation
technologies in friendly user interfaces. These projects will show the versatil-
ity and automation opportunities that Android has to offer. The book also
includes appendixes that review a variety of programming tools that run on
the Android platform, as well as offer additional web resources to further your
own project ideas.
By the end of the book, you should be well prepared to continue the journey
on your own to create an Android experience that perfectly complements your
information-interaction lifestyle.
Online Help
Many websites are devoted to the dissemination of Android news, reviews,
hacking, modding, and programming. Check out Appendix 1, Android Pro-
gramming Tools, on page 187, for a list of some of my favorites. It should go
without saying that for Android development, Google’s http://developer.android.com
website offers the official word on Android application development. This isn’t
just a repository of bland technical documentation but a wealth of useful and
well-written articles, tutorials, and tech notes from the folks responsible for
various portions of the operating system. It’s a resource that any serious
Android developer should have permanently bookmarked.
There are a number of footnotes in the book featuring web links to more online
resources. I also encourage you to post specific questions or comments about
the ideas presented in the book at the book’s web forum. Should you happen
to spot an error, feel free to mention it on the book’s website errata page.
You’re also welcome to contact me directly via my [email protected] email
address or follow me on Twitter @mriley. I look forward to hearing from you!
With that, we’re ready to take a look at all the things we can customize in a
nonrooted device running the stock Android 4.2 or newer operating system.
Mike Riley
[email protected]
November 2013
Customize
Getting Started
Today’s smartphones are amazing devices. They are such powerful and
capable computing devices that they have even replaced traditional desktop
personal computers for some people. And like traditional desktops, one of the
most exciting aspects of the Android platform, especially when compared to
other mobile operating systems, is its ability to be highly customized. This
customization goes beyond just wallpaper and icon replacements. You can
use Android to create custom tasks, scripts, workflows, and behaviors that
can’t be done easily on most other mobile platforms.
In this book we’re going to go beyond simply locating and installing commercial
Android applications that provide generic functionality to fulfill your needs.
But before we can start crafting scripts and applications that do what generic
Android applications cannot, we need to evaluate key features of what an
Android device has to offer. Then we can determine what to look for in the
Google Play market. If we can’t find what we’re looking for, we can build it
ourselves.
In this chapter, we will take a look at some of these key aspects before decking
out your phone or tablet with themes, widgets, and applications that might
not optimally suit your mobile lifestyle needs.
If your Android device is a phone, do you use it primarily for voice calls or
texting? If you use an Android tablet, is it used mostly for reading ebooks or
for surfing the Web? Deciding where you spend the most time with your device
will help narrow down what functionality can be enhanced to improve your
efficiency and satisfaction with the Android OS.
Think about how much time you spend with an application. Is it because it
is so helpful that you can’t imagine life without it? Or is it because the
application is so cumbersome and nonintuitive that it sucks up a substantial
amount of time while you’re fighting the interface? Do you find yourself run-
ning the same type of task over and over again?
If you had the chance to re-create your most frequently used applications,
what would you change about them? Do you have special needs that are not
addressed in these apps?
At first, I wrote a simple talking clock app using the Android SDK but found
it to be inflexible when it came to making tweaks to the routines. If I discovered
a bug or came up with an idea to extend the program’s functionality, I had
to wait until I got home to fire up my computer, run Eclipse, spin up an
Android emulator, load the project, make changes to the codebase, go through
a test/debug cycle in the emulator, and then push the compiled .apk file to
my Android phone via the Android Debug Bridge (ADB). All that work for a
few minor tweaks! Needless to say, there had to be a better way. Hence, the
journey I’ll take you through in this book mirrors my own iterations that best
suited my mobile lifestyle needs.
If you’re like me and you live in the post-PC era by deprecating your desktop
or laptop computer for a phone or tablet alternative most of the time, your
mobile lifestyle is all-encompassing. My phone is always by my side during
my waking hours and on my nightstand when I sleep. Likewise, my tablet is
with me during my commutes and anytime I’m driving somewhere where I
will be away from home longer than an hour. Just as noteworthy to-dos pop
into my head while on the go, ideas for enhancements to existing Android
apps I have written have to be captured at that moment before they are lost
into the ether of the day’s demands.
Having the flexibility to make these changes on the fly has been about as
game-changing for me as when I bought my first home computer in the 1980s
(an Atari 400 with its craptaculous membrane keyboard) and then could write
my own apps without having to wait for computer lab time at school. That
freedom and flexibility changed my life back then, and as the Android platform
matures with the ability to develop apps on the device rather than a hulking
piece of hardware, that life-changing experience is resurfacing.
To put yourself in a mobile lifestyle frame of mind, here are some questions
to ponder when considering how you use your Android device for your own
customization opportunities:
• What hours of the day do you use your phone or tablet? If you respond
“All the time,” what are the time ranges that you use the device the most?
• What applications do you spend the most time using? If you’re not sure,
Android’s Data Usage and Running apps (shown in the following figures)
are accessible via the Android Settings application.
Figure 2—An example of Android’s data Figure 3—A list of currently running
usage applications
While not a true reflection of time spent with each application, these two
measurements can help you to a certain degree by showing you which
programs consume the most bandwidth and power. These data collections
can help you become more aware of which applications are frequently
running (whether you’re aware of them doing so in the background or
not).
• What repetitive tasks do you perform with your device that would save
time if you could automate these efforts? For example, I used to make an
effort to turn on my phone every morning, turn on the WiFi radio, launch
my podcast application (I’m currently a fan of the DoggCatcher Podcast
Player1), and wait for the application to download whatever podcasts were
available. When done, I would then turn off the WiFi radio to conserve
battery. If I forgot or ran out of time, I wouldn’t have any new podcasts
to listen to on the way to work. By the way, I no longer do this manual
process since I’ve scripted the entire procedure to kick off thirty minutes
before I wake up. I’ve also created automated tasks to grab the latest news
and weather to read to me after the clock alarm awakens me. We’ll explore
how to write your own scripts and tasks later in the book.
• What dream applications or widgets do you wish you had but haven’t
seen in the Google Play store? Be as specific as possible. Do you want an
application that will wake you up, turn on the lights, and start brewing
a pot of coffee at the same time? After reading this book and another book
I wrote called Programming Your Home [Ril12], also published by Pragmatic
Bookshelf, you will have the knowledge necessary to bring an automation
example like this to fruition.
With these thoughts in mind, let’s take a closer look at some of the more
interesting personal automation ideas we could build upon.
1. https://play.google.com/store/apps/details?id=com.snoggdoggler.android.applications.doggcatcher.v1_0
• Parse SMS alerts for keywords and react accordingly. If you’re a system
administrator, you could parse SMS messages for the phrase “Server
down” and set off a klaxon-style alarm on your phone or tablet.
• Grab RSS news feeds and repackage them for your own personalized news
broadcast. Set your Android device to connect to the Internet at specific
times throughout the day to fetch RSS feeds, parse them, and convert
the text to speech. Then have it read the news stories to you during your
commute to and from work.
• Have your Android phone automatically turn off all radios except mobile
voice calls and set your display to night mode from the time you go to bed
to the time you wake up in the morning. To help you fall asleep, have
your phone play soothing music or sounds of nature (seashore, forest,
meadow, rain shower, and so on) for twenty minutes, giving you enough
time to peacefully fall asleep.
• Take a photo with your phone or tablet and have that image automatically
cropped, filtered, resized, and posted to your online photo album or blog.
Once you have a list of needs in mind, you can start to define what is neces-
sary to bring these ideas to fruition. If someone hasn’t already done the work
for you and posted the results of their efforts online or in the Google Play
store, you have a few more factors to consider before diving in and expending
the time and effort needed to bring your ideas to life.
certainly helps if you have some coding skills and are willing to learn new
things.
There are also times when writing automated tasks or scripts accomplishes
enough of the intended objective that writing a native application is no longer
necessary. This is particularly true if the script or workflow you are creating
is targeted for your specific mobile lifestyle need. But what I have often dis-
covered with my workflows is that as I show my creations to others, they
excitedly ask whether they can have something similar. That’s where this
book comes in. As the classic Chinese proverb says, “Give a man a fish, and
you feed him for a day. Teach a man to fish, and you feed him for a lifetime.”
Let’s go fishing.
In the next chapter, we will dive into our first layer of customization by mod-
ifying the look and feel of the Android home screen. With the help of a handful
of utilities available from the Google Play store, we can transform the default
Android user interface into a whole new experience.
Within the mobile space scenario, Google’s Android has replaced Apple as
the dominant operating system, in part because of the same openness to
customizing the user experience. A variety of home-screen shells, better known
as launchers, are available through the Google Play marketplace that can
swap out default home-screen graphics, icons, and behaviors. And in contrast
to Apple’s iOS platform, Android allows the placement of onscreen mini-
applications known as widgets to alter the stock Android UI. Pushing the
envelope a bit further are what I call floaters. These are Android applications
that run in a resizable desktop-like window that can multitask and hover on
top of the home screen or other full-screen Android programs.
2.1 Launchers
The stock home screen that comes on the standard Google Nexus devices
offers a crisp, clean interface. But if you don’t like how it looks or want to
remove the Google search bar widget that refuses to budge when you try, you
have several alternative approaches to choose from. These replacement home-
screen layout and theme applications, called launchers, are available for
download directly from the Google Play store. As the name implies, launchers
can be used to launch applications. But they can also be used to customize
everything from the look of icons to the transition animations that are dis-
played when moving between screens.
Most of the commercially available launchers offer a free version to play with
that are either ad-banner supported, restricted in features, or constrained to
a certain degree of customization. If customers like what they see, they are
encouraged to reward the launcher’s creator with a paid upgrade that will
remove ads and/or unlock additional features. The nice thing about these
commercial launchers is that they can easily be installed just like any other
program that can be obtained from the Google Play store. Once downloaded
and installed, the replacement launcher will ask for your permission to always
be used as the default launcher. You can also choose to run a launcher once
before making the launcher replacement a global change. At the time of this
writing, the most popular launchers on Google Play are ADWLauncher EX,3
Apex Launcher Pro,4 GO Launcher EX,5 and Nova Launcher Prime.6 Let’s take
a brief look at each of these to see what they have to offer and what differen-
tiates one from the other.
1. http://en.wikipedia.org/wiki/TouchWiz
2. http://en.wikipedia.org/wiki/HTC_Sense
3. https://play.google.com/store/apps/details?id=org.adwfreak.launcher
4. https://play.google.com/store/apps/details?id=com.anddoes.launcher.pro
5. https://play.google.com/store/apps/details?id=com.gau.go.launcherex
6. https://play.google.com/store/apps/details?id=com.teslacoilsw.launcher.prime
ADWLauncher EX
One of the most downloaded launchers on the market, ADWLauncher EX’s
main claim to fame is that it runs on platforms as far back as Android OS
version 1.6. Even on that early Android release, ADWLauncher EX offers the
same kind of eye candy and customization features found on later Android
releases. However, maintaining this visual compatibility comes at the price
of a slightly larger application installation size compared to other launchers.
Pros
• Runs on the Android operating systems as far back as version 1.6 (aka
Donut)
• Fair number of customization options and graphical flourishes, such as
page transitions, icon adjustments, and app organization styles
Cons
Pros
Cons
GO Launcher EX
With more than a million installations since its release into the Play market-
place, GO Launcher EX is by far the most popular on Google Play and has
Pros
• It’s free.
• This is the most popular launcher on the market, with a thriving add-on
and custom theme market (more than 5,000 and counting).
• It runs on Android 2.0 and newer.
Cons
Pros
Cons
• Comparatively expensive
Fortunately, it’s unlikely that the more popular launchers highlighted in this
book would be engaging in such practices since they are used by so many
people; the likelihood is small that security-conscious customers using these
products would be monitoring the application’s network interaction for any
funny business. Yet while companies that create these launchers are seeking
commercial gain through the sale of their application, the more popular a
launcher becomes, the more likely unscrupulous hackers could seek out and
exploit security flaws in the launcher by exploiting unintentional vulnerabilities
in the target launcher application.
The lesson to be learned with this array of launchers is that Google could
step up its game and bake launcher customization within the Android OS.
Not only will this alleviate security concerns (that these third-party launchers
have unfettered access to so many sensitive areas of the phone or tablet), but
it will also help to standardize on theme formats. Instead of being locked into
one vendor’s interpretation of what a launcher theme should consist of, Google
could help set a universal protocol that Android users and independent theme
designers could follow. Until then, we’re stuck with entrusting these third-
party providers with our device’s security.
Launchers can be combined with custom wallpaper images, icons, and screen
transitions to create a new level of personalized artistic expression among a
new generation of mobile connected users. Just as car exteriors were
customized during the mid-1960s through the ’70s by that generation’s youth,
this design trend has been reborn in the mobile generation. Even more levels
of customization can be realized using widgets. Let’s take a closer look at this
standout feature that is part of the Android OS experience.
2.2 Widgets
A major distinction between a desktop computer and a mobile OS such as
Android is the way people interact with information on the display. A desktop
offers considerably more screen real estate (even more so with multiple
monitors) than is typically offered on a mobile display. As such, running
dozens of windowed applications on a mobile device isn’t very practical. Yet
the power of a multitasking OS such as Android allows for many programs
to be running at the same time.
Android has solved this constraint somewhat with the creation of widgets.
Widgets are small graphical applications anchored to the home screen that
can display data in a space as small as a single icon or expand to take over
most of the screen. In this section, we’ll take a look at how to select and use
widgets, as well as sample a few of my favorite Android widgets.
When widgets were introduced in the early days of Android, they were one of
the most defining features of the OS when compared to competing mobile
platforms. Since then, widgets have found their niche as a collection of useful
albeit limited views often for larger host applications.
For example, many media players available for sale on the Google Play store
include widgets of various sizes that distill basic functions such as play/pause
and forward/rewind onto screen areas that span anywhere from one-by-two
to four-by-four tiles. Other widgets offer scrolling news-ticker-style updates
from RSS feeds, server status, and to-do list reminders, among other things.
In addition to the widgets available on the Google Play store, Android ships
with its own collection of widgets to support the variety of Google applications
on the phone.
Discovering the widgets installed on your Android device and adding a widget to
your home screen is easy. To view the widgets installed on your phone on a
standard Android 4.2 launcher configuration, select the Applications group icon
from the lower center of the screen. This will display icons of all the visible pro-
grams on your device. From this screen, select the Widget tab to view the installed
widgets as shown in Figure 5, Android widgets selection screen, on page 15.
Lock-Screen Widgets
While the original intent of the lock screen Figure 5—Android widgets
was to prevent the phone from accidentally selection screen
launching apps or dialing numbers while
jostling in your pocket, lock screens are increasingly important. Mobile devices
have become containers of personal information, and the content should be
protected with the same security applied in the physical world. But as secu-
rity increases, convenience decreases. So, something as simple as checking
your calendar can become a time-consuming dance of unlocking your phone,
scrolling to the calendar icon, launching the program, scrolling to the
appointment, and expanding the view for details.
To select a lock-screen widget, swipe to the left while the lock screen is
enabled. This will display a blank grid with a plus symbol in the center, as
shown in Figure 6, Adding widgets to the lock screen, on page 16. Select the
plus symbol, and a list of widgets that are lock screen–compliant will be dis-
played, as shown in Figure 7, A selection of lock-screen widgets, on page 16.
Scroll through the list to choose the one you want and place it on the lock
screen via the same procedure as placing a regular widget on the home screen.
7. https://play.google.com/store/apps/details?id=net.nurik.roman.dashclock
The other advantage that DashClock offers is a very easy way to hook into
its API so that third-party data sources can be displayed in DashClock’s
container.8 Roman released the DashClock source code under the open source
Apache License 2.0, making it a hit among developers who have rewarded
Roman’s efforts with a thriving number of add-ons. These range from battery
and dialing extensions to word-of-the-day and Facebook message counts.
Of course, with all these extensions, you have to be cautious about the type
of lock-screen enhancements you install. As is the case with something like
the Gmail or Calendar lock-screen widget, DashClock extensions might be
exposing data that you don’t want to display on a pocket billboard. DashClock
also has access to permissions such as contacts, email, and location that can
be polled by it and the extensions it hosts. So, unless you implicitly trust
whatever extension you host within DashClock, be wary of what you install.
My Favorite Widgets
I try to keep my widget count to a minimum
(see the figure here). Too many widgets,
especially those polling for frequent network
updates, can impact performance and battery
life. I also stay away from the widgets with
lots of graphical flourishes and large screen
footprints because I find them distracting and
overstepping their intention of quickly
assessing the data they are trying to convey.
That said, here are some of the widgets I pre-
fer.
• Calendar
8. http://code.google.com/p/dashclock/wiki/API
onto the surface of the moon has endeared me to all things space. Moon
Phase Pro9 created by developer Udell Enterprises keeps me in touch with
my fascination with celestial bodies. In addition to the main program that
displays the monthly phases of the moon along with other interesting
statistics, the program comes bundled with several widgets of various
sizes and levels of detail.
I use this application each time I press the button on my Android headset.
Created by Android developer Christoph Kober, Headset Button Controller
essentially allows you to assign different actions to each type of headset
button press.10 Those actions can span from running scripts and applica-
tions to reassigning behaviors to other button presses. The program
includes a widget that allows you to quickly switch between different
headset button profiles. We will explore in greater detail and make use
of this application in the next chapter.
• Python Interpreter
This is my second favorite widget and one I built myself. Touching this
widget activates a Pomodoro countdown timer. I will tell you more about
9. https://play.google.com/store/apps/details?id=com.daylightmap.moon.pro.android
10. https://play.google.com/store/apps/details?id=com.kober.headsetbutton
Pomodoro timers and walk you through the process of building this widget
in Chapter 7, Tasker Pomodoro Widget, on page 93.
This is my favorite widget and, like the Pomodoro Clock widget, is also
one I built myself. When tapped, the Check Mail widget will check for new
email and speak any new unread messages received. I find that this widget
and the corresponding script it executes is crucial for the hands-free
reporting of new mail messages. We will be building this widget and the
backend script that powers it in Chapter 8, Messaging Projects, on page
115.
Now you should have a pretty good idea of the types of custom application
launchers and widgets that Android has to offer. In the next section, we will
take a look at a special type of Android application that gives your Android
device a retro feel by harkening back to the days of traditional PC-based,
window-driven GUIs.
2.3 Floaters
There is another category of Android applica-
tions that can be displayed on the screen
within a movable window. I call these pro-
grams floaters. Floaters behave just like a
window in a modern desktop computing OS.
Most can be resized, minimized, and maxi-
mized, and some even support multiple
instances, allowing multiple windows on the
screen at the same time. See the figure here.
That said, there are a few benefits. Let’s say you’re watching a video and need
to check and respond to email. Normally you would have to pause the playback
to do so. Using a floater media player, you can just resize the window while
perusing your messages and then expand the playback to full screen without
missing a moment of content. There’s also the coolness and geek credibility
factors to be able to show colleagues something they might not have thought
possible on a mobile device. Lastly, floaters work rather nicely on a 10-inch
Android tablet thanks to the much larger screen size that gives you the ability
to effortlessly move and resize windows. I tend to use floaters most frequently
on these types of large-screen devices.
While quite a few floater-style applications are available in the Google Play
store, here are a few worthy of a closer look:
• AirCalc11
AirCalc is a simple yet free calculator for Android. It also provides a nice
introduction to floaters and is a great way to determine whether your
Android device supports the app screen overlay techniques employed by
most floater programs. AirCalc can be resized, minimized, and maximized
just as you would expect a traditional windowed application to behave.
• AirTerm12
11. https://play.google.com/store/apps/details?id=com.myboyfriendisageek.aircalc
12. https://play.google.com/store/apps/details?id=com.myboyfriendisageek.airterm
13. http://kevinboone.net/kbox.html
14. http://www.busybox.net
• DICE Player15
• Overskreen16
• Stick it!17
Stick it! is another Android media player that, like DICE Player, provides
video playback within a pop-up window. However, unlike DICE Player,
Stick it! offers a neat feature on higher-end Android devices called Multi-
View. This essentially allows for multiple windows to play back different
video content at the same time. It’s an awesome technology demo, but I
honestly haven’t used MultiView in many real-world scenarios. And as
you can imagine, playing several videos at the same time can be rather
taxing on your battery and system resources. But for a whiz-bang Android
showcase program, Stick it! is hard to beat.
Now that we have all the visual customization tools and applications that we
need to have Android’s home screen look and behave the way we want, let’s
apply these ideas to re-create two home screens. One will emulate a competing
15. https://play.google.com/store/apps/details?id=com.inisoft.mediaplayer.a
16. https://play.google.com/store/apps/details?id=com.myboyfriendisageek.airbrowser
17. https://play.google.com/store/apps/details?id=com.myboyfriendisageek.stickit
phone operating system, and another will re-create the look and feel of a
popular desktop operating system.
18. https://play.google.com/store/apps/details?id=com.gau.go.launcherex.theme.wpsevenstyle
With a backup made, select the Import label from the Backup and Import
screen. Nova Launcher Prime will remind you that your existing launcher
settings will be replaced by the theme being imported. You know, the one you
were supposed to make a backup of, right? Since you do have a backup of
your current configuration, return to the Nova Settings screen and select the
Look and Feel option. From there, choose the Icon Theme option. The list of
the various themes installed on your Android device will be displayed, as
shown in Figure 11, A selection of installed icon themes.
Now we’re going to use Nova Launcher Prime’s ability to import icons from
other launcher application themes. In this case, we will borrow some Windows
Phone–like icons from a Windows 7 GO Launcher theme. Choose the GO
Launcher EX Windows Phone 7 theme from the list. This will replace icons
for standard Android programs such as Browser, Email, and Settings with a
Windows Phone icon lookalike. Arrange your choice of applications on your
home screen accordingly. Press and hold on the home-screen background to
either change it to a solid color or incorporate a matching Android wallpaper.
I prefer the live wallpaper that is installed with the Moon Phase Pro program.
Tinker with the layout until you achieve the look and feel you’re comfortable
with. When you’re done, it may look similar to the one shown in Figure 12,
A Windows Phone theme.
Next, replace the home screen’s background wallpaper with a Mac desktop
wallpaper. Launch the default Android or Google Chrome browser, search
Google Images for “Mac desktop wallpaper,”20 and select any of the ones that
appeal to you. Set the image to your wallpaper by long-pressing the image of
choice. A pop-up menu will appear, as shown in Figure 13, Setting background
wallpaper using an image from the Web, on page 25.
Select the “Set as wallpaper” option. This will download the selected image,
save it locally to your Android file storage, and set the image as the default
home-screen background.
19. https://play.google.com/store/apps/details?id=akglo.themes.macos
20. https://images.google.com
Now that you have the knowledge and the tools to customize your Android
device the way you see fit, explore the numerous themes available for down-
load. If you’re using TeslaCoil’s Nova Launcher Prime, you will find that most
background and icon themes are compatible. However, most graphical
embellishment behaviors that accompany these themes, especially those
written for Go Launcher, don’t work as expected, if at all. Still, there are
hundreds of freely available themes to choose from, and that number is
expanding every day. If you don’t find one you like, you can create your own
by converting pictures you took with your Android’s camera into home-screen
backgrounds and icons. Your first attempts might not be works of art, but
they will most definitely express what you want your mobile computing
experience to look like!
In the next chapter, we will explore how to customize the other side of the
user experience by focusing on audio. Specifically, we will learn how to
leverage audio in Android to augment and in some cases even replace the
Android user interface. Get ready to listen up!
For example, did you know that your Android can speak to you? Ever since
the Android 1.6 OS release, Android has had built-in text-to-speech (TTS)
functionality that could convert text into spoken words. However, it wasn’t
until the release of Android 4.2 that this TTS technology was actually tolerable
to listen to for long stretches. Earlier releases were robotic and lifeless. The
4.2 release includes a far more natural and less obnoxious voice. And if this
default voice isn’t to your liking, third-party text-to-speech synthesis products
like those from SVOX offer a selection of more than forty voices in multiple
languages.1 Before 4.2 came along, I used SVOX for my TTS needs.
But before we get to hear our phone, we should optimize our listening envi-
ronment for on-the-go audio data consumption.
1. https://play.google.com/store/apps/details?id=com.svox.classic
without ever having to remove the phone from its case. Email, text messages,
meeting notifications, countdown timers, motivational reminders, and other
information are controlled and delivered via my audio headset.
This chapter will show you how to put the pieces into place to allow you to
do the same thing. The setup is simple and inexpensive. And unlike Google’s
much hyped and considerably more expensive Glass project, my Android
wearable configuration doesn’t obstruct or distract my vision in any way.
Many people prefer to put their smartphones in their pocket, but I find it far
easier to use a wired headset when the device is holstered in a case strapped
to my belt. I prefer the Case Logic TBC-412 model. Even though this product
is officially designated as a video camera case, I find that it snuggly fits my
Galaxy Nexus even with the added thickness of a 3850mAh extra-capacity
battery. It also protects the phone from the elements, whether that is a drizzle
of rain or a dusty biking trail. The price is also cheaper than custom-designed
slip cases made specifically for the phone.
With the phone safely enclosed, run a headphone wire from your shoulders
to the phone. You can run the wire between layers of clothing to keep it out
of the way. Some headsets come with a helpful plastic clip that allows you to
put some slack into the wire. That keeps the earphones from tugging at your
ears. I attach this clip to my shirt collar to keep the left and right earphone
wires from slipping as I walk. The headphones I use on a daily basis are a
cheap single-button design with a built-in mic that is compatible with most
Samsung Galaxy phone models. These can often be found on Amazon for as
low as a dollar plus shipping. Note that the headset you use must have a
headset button, since you will use that button to answer calls, start and stop
audio, and run applications.
You can opt for a more expensive headset or earphones tailored to your phone
hardware. You can also choose to go entirely wireless via a Bluetooth headset.
But I have found from years of using my wearable configuration that these
choices produce annoyances. For expensive wired headsets, I find that the
wire at the stem of the headphone jack becomes weak over time and eventu-
ally loses either the left or right ear connection. I have even tried shielding
the wire from this wear and tear by looping the wire at the stem of the head-
phone jack and tightly wrapping it with electrical tape to no avail.
As for Bluetooth headsets, I find that the sound quality still hasn’t quite
matched the frequency ranges offered by wired headsets. There is also the
hassle of having to recharge the Bluetooth headset’s battery before use. And
it can be a pain when that charge dies midway through the day without
having the means to recharge it until you’re home.
If you choose a wired approach, you need to manage the path of the wires
from your ears to your encased Android. Depending on the type of activity,
you can try running the wire in between your outer and undershirts, either
in front or back of you. Gadget-friendly clothing from progressive fashion
designers like ScottEVest includes shirts and jackets with dedicated enclosures
to run headphone wiring through so as not to flop around and get in your
way.2
With the headphones in place and the headphone button in a location that
is easy access, you can use this button to control the basic features of the
phone. Answer an incoming phone call as well as pause and play music with
a single short press of the center headphone button. The basic button press
behaviors are more or less universal across all Android phones that support
headset controls.
With your Android by your side and your audio headset on, let’s next turn
our focus to the software involved in voice recognition and spoken text inter-
action.
The default preferred speech engine in Android 4.2 is Google’s own TTS
technology. If you have SVOX or another third-party engine installed, it will
also be listed on this settings page. From this screen, you can also modify
the rate of speech playback, ranging from very slow to very fast. I prefer the
default normal speed, but try each setting to see which of the five playback
speeds works best for you. Select the “Listen to an example” option to hear
2. http://www.scottevest.com
Android speak at the playback speed you chose. And now that we know
Android can talk, let’s explore how we can talk back to Android.
• “Set an alarm for <time>” will set an alarm to sound at the requested
time.
• “Remind me to <task> at <time>” will convert your speech to text and add
the converted statement to your default calendar at the designated time
on the current day.
So, that’s pretty cool, but Google Now has two notable drawbacks. First, while
Google’s voice recognition and speech-to-text translation services are amazing,
3. http://www.google.com/landing/now/
they’re far from perfect. Try any of these phrases on a noisy bus or outside
on a windy day, and you’re not likely to see the results you expected.
You would think that’s because Google needs its server farm to chew through
your speech input, convert it to a text string, and figure out the meaning of
the submitted phrase. But that doesn’t explain why Google offers offline
speech-to-text translation in Android 4.2 and newer. Until Google creates an
API that allows developers to access this offline speech-to-text translation
service, developers need to continue submitting spoken phrases over the
Internet to Google’s servers.
The takeaway from all this is that if you live and commute in a well-connected
city where wireless Internet connectivity is trustworthy, fast, and ubiquitous
and you’re not concerned about the voiceprint data Google is collecting from
your audible queries, then Google Now can be mighty helpful at times. But
while Google Now does a good job of translating responses such as the time
and reminders into audio, most answers require looking at the screen to
review the replies.
When I’m on the go, whether walking crowded city streets to work or riding
my recumbent along winding bike trails, I really don’t want to pull my phone
out of my pocket to see who sent me a text message and what they said, view
any upcoming events on my calendar, or simply check the time.
4. https://play.google.com/store/apps/details?id=mahmed.net.spokencallername
Talking Calendar
One of my biggest frustrations with program
audio cues is that they provide only part of
the story. Let’s say you use a custom chime
whenever a calendar reminder is triggered.
Instead of knowing exactly what event is
coming up, you have to stop whatever you
were doing, dig out your phone, unlock the
screen, flick down the notification bar, and
parse through the various notifications just
to figure out what’s going on.
5. https://play.google.com/store/apps/details?id=com.pwnwithyourphone.talkingcalendar
6. https://play.google.com/store/apps/details?id=com.bulletproof.voicerec.avx
Once you have these hands-free utilities loaded and working, you’ll quickly
discover that they are great for incoming information and events, but they
either can’t send outbound messages or don’t do so very well. There are a
couple of reasons for this deficiency. The most obvious problem is lack of a
proven input mechanic like an onscreen keyboard. We have already discussed
the problems with speech-to-text conversion. Until Google opens up its offline
speech translation engine API to developers, this will continue to be an issue.
And even with access to this API, speech recognition degrades considerably
in a noisy environment. If you have an active lifestyle, you’re probably inter-
acting and commuting in a noisy environment most of the time. But all is not
lost. Button presses to the rescue!
The most notable reasons are centered around eyestrain, obstructed views,
and the uncomfortable feeling of a headband gradually making a dent into
my forehead. While I still fantasize for the day when I can walk around like
a futuristic superhero with total situational awareness, swirling graphics,
flagging call-outs, and an always-on voice assistant ready to immediately act
upon my lazy utterances, we still have a long way to go technologically before
those science-fiction visions are fully realized. But while it’s fun to dream of
the future, I need an unobtrusive working solution today without all the
annoyances I’ve already encountered.
Google intended to capture the long-press headset button event to offer a consistent
behavior across devices using Android 4.2 and newer. But forcing this upon all users
without the ability to disable or reassign to a different button combination seems a
tad heavy-handed. I hope Google will allow users to customize this choice in future
iterations of the operating system, but for now we have to accept this imposed con-
straint.
As odd as it sounds, I look forward to hearing the synthetic female voice used
as the default TTS engine in Android 4.2. It’s nice to know that she’s always
there, keeping me informed of appointments, messages, to-dos, and directions.
And like Aladdin rubbing a lamp to wake the genie, I use my assigned clicks
interpreted by Headset Button Controller to instantiate a variety of automated
workflows. Some of these workflows will be described in later chapters. But
for now, think of the variety of click combinations to launch applications as
a terse subset of Morse Code. One click to pause, two clicks to fast-forward,
three to report time and battery life, and four to check email. We’ll talk more
about the last two custom programs in that click list later in the book.
7. https://play.google.com/store/apps/details?id=com.kober.headsetbutton
For example, my Galaxy Nexus phone supports only a single button headset,
leaving me with a total of six actions I can assign to Headset Button Controller.
So, grab your Android phone, plug in a compatible headset, install the trial
edition of the button controller software, and let’s configure it to launch the
standard Android web browser when three headset button presses are
detected.
Keep in mind that we can still use other applications that react to headset
button presses while Headset Button Controller is running. You can have the
program send button presses to a specific application (such as an audio
player) or to whatever media player had been most recently used.
8. https://play.google.com/store/apps/details?id=ak.alizandro.smartaudiobookplayer
9. https://play.google.com/store/apps/details?id=com.snoggdoggler.android.applications.doggcatcher.v1_0
The idea is to take an inexpensive three-button inline remote designed for Apple
products like the iPod touch or iPhone (the article suggests the iLuv iEA15BLK). Open
the button casing, solder in two tiny resistors, and you can triple your Headset button
options as a result.
The procedure does require soldering skills, steady hands, and good eyesight to be
able to set the spec-sized resistors in place, but it worked like a charm for me and
gave me another sixteen actions to assign to running various programs and tasks. If
you enjoy tinkering with hardware and have the right equipment, try this approach.
Many thanks to my good friend and tech extraordinaire John Winans for use of his
top-notch soldering equipment and laser-eye soldering technique. I couldn’t have
verified that this Instructables technique worked without his help.
a. http://www.instructables.com/id/Galaxy-Nexus-and-others-headset-remote-with-medi/
Speaking of the headset button, take some time to explore your own applica-
tion assignments for Headset Button Controller. Couple its functionality with
the audio-oriented informational and productivity programs suggested in this
chapter. As you reorient yourself toward a more audio-centric mobile lifestyle,
consider the data that you would like to bring to your attention and have
spoken to you. You will be able to put those ideas into action because we will
soon learn how to automate workflow tasks and write custom scripts and
programs that help process and deliver this data.
In the next section, we will put the sonic configuration promoted in this
chapter to good use. We will construct a talking clock that will speak the time
every fifteen minutes or whenever a triple-click is received by an attached
headset button.
Explore
Tasker provides the ability to easily define and execute powerfully scripted
actions that can be triggered by application, time, location, state, and event
changes. With it, you could create a simple task that would automatically
change the screen orientation to landscape and turn on the GPS radio
whenever you launched a favorite navigation utility. You can also create more
complex programs by linking together dozens of tasks. Tasker even has the
ability to compile your programs so they can be freely executed on other
Android devices that don’t even have Tasker installed on them. Let’s take a
closer look at this popular and versatile workflow automation utility.
1. http://tasker.dinglisch.net
Of all the apps I use on a new Android device, Tasker is consistently the first
one I install. Tasker was written by developer Lee Wilmot during the early
days of Android. Google was enticing new developers to the platform via prize-
winning programming competitions called Android Developer Challenges, and
Tasker was one of the finalists in that competition.
Once installed, launch Tasker and take a look at the variety of parameters
that can be changed via the UI, Monitor, Action, and Misc Preference tabs.
For example, you can tweak the polling frequency of your current location
coordinates more frequently than the default thirty seconds by modifying the
value, as shown in the following figure. Note that all screenshots of Tasker
shown in this book are from Tasker 4.0 installed on a Galaxy Nexus or Nexus
7 running Android 4.2. Tasker 4.0 incorporates Google’s Holo theme. Prior
versions of Tasker can run on devices running older versions of Android.
However, since Holo is natively supported only on Android 4.x and newer
versions of the operating system, Tasker’s screens will look somewhat different
on those older platforms. The good news is that the placement of dialog ele-
ments and Tasker’s core functionality are mostly the same between platforms.
Launch Tasker and select the Tasks tab (as shown in Figure 23, Creating a
new task, on page 44) by selecting the center plus icon in the bottom toolbar.
Type in Say Time as the new task name and touch the check mark to accept
the name. Doing so will present you with an empty Task Edit screen that you
can add new discrete tasks to. Select the center plus icon in the lower toolbar
to add a new action to the task. This will display the dialog shown in Figure
24, Tasker's Select Action Category dialog, providing a list of more than
twenty action categories to choose from.
Select the Misc button, which features a question mark icon, and then select
the Say button from the Select Misc Action dialog. This will display the Say
form that allows us to manipulate a number of options, from what text to say
and the voice engine to use to the speed and pitch of the text-to-speech
playback. Select the gray tag icon to the upper right of the Text entry box.
This will pop up a list that allows you to select from both Tasker’s built-in
variables as well as ones you have created (Figure 25, Variable Select dialog,
on page 45).
Scroll down the list until you see the Time variable. Select it, and notice that
Tasker populates the Text textbox with a predefined built-in variable called
Tasker Variables
Tasker has three types of variables: local, global, and built-in. Local variables are
identified by all-lowercase variable names, such as %my_local_variable. Local variables
are accessible only within the scope of a single task, and their values cannot be read
by other tasks. Global variables are identified by the first letter in their names being
uppercase, such as %My_global_variable. These can be read by any task created in Tasker
and are useful for storing values that need to remain persistent and accessible across
multiple tasks. The last type of Tasker variable are the built-in variables, such as
%TIME, %GPS, %ROOT, and %WIFI. For a complete list of Tasker’s built-in variable names,
visit the Tasker website.a
a. http://tasker.dinglisch.net/userguide/en/variables.html
%TIME. Next, assign the voice engine you want to use to speak the time by
selecting the magnifying glass icon to the upper right of the Engine:Voice
label. This will display a list of the various speech engines installed on the
phone, such as Pico, SVOX,2 or Google’s own text-to-speech engine. Select
your engine of choice.
2. https://play.google.com/store/apps/details?id=com.svox.classic
The Stream field allows you to assign the audio output to Android’s Call,
System, Ringer, Media, Alarm, and Notification audio channels. Choose the
default “Media stream” option and leave Pitch and Speed at their midpoint
default values, as shown in Figure 26, Tasker Say options dialog, on page 45.
Now that the Say action has been defined with what we want our phone to
say and how to say it, select the Action Edit label located on the upper-left
toolbar. This will save the first step in our Say Time task. Test the results by
selecting the Play icon in the lower-right corner of the dialog box. You should
hear your Android phone or tablet speak the current time in 24-hour format.
As an example, if it’s 4:22 p.m. when you run the task, your phone will say
“Sixteen point two two.” Well, that’s literally the time but not the common
North American way of speaking it. Let’s fix that.
3. Determine whether it’s a.m. or p.m. If the current hour on the 24-hour
clock is greater than 11, it’s p.m. Otherwise, it’s a.m.
5. The same goes for any minutes announcements less than 10. For example,
if the time is 9:07 p.m., the Talking Clock task should say “Nine oh seven
P-M” and not “Nine zero seven P-M.”
The first thing we need to do is create and assign the value of the built-in
%TIME variable to a local variable (let’s call it %current_time) that we can manipu-
late. Select the Say Time task we created earlier. Delete the action we created
for the original Say Time task by long-selecting (i.e., holding your finger on
the selection for at least two seconds). Choose Cut from the Action Options
pop-up menu. Then create the new first step in the task list by selecting the
center plus icon from Tasker’s bottom toolbar. The Variable Select dialog will
once again be displayed. Select the Variable category from the Action Category
dialog, followed by the Variable Set action from this Variable pop-up dialog
box. This will pop up a Variable Set dialog. Set the name of one of the new
variables we will create for this task to %current_time and assign it to the built-
in %TIME variable that we called upon earlier. Save the step by selecting the
Action Edit label in the left of Tasker’s top toolbar.
Next, we need to split this captured %current_time value into hours and minutes.
This is done by creating a new step using Tasker’s Variable Split function.
Choose this function from the Variable action category like we did for the first
Variable Set step. The Variable Split task function works by splitting the
variable passed to it into two or more elements based on the delimiter chosen.
In the case of %current_time, this delimiter is a period, so enter that character
into the Splitter field. When Tasker executes a Variable Split task, it will
incrementally number the original variable name and assign the split values
accordingly. So, when the Variable Split function is applied to the %current_time
variable, Tasker separates it between the period character into hours and
minutes. Tasker will generate a %current_time1 and %current_time2 to hold the
newly split values of hours and minutes, respectively. Save this action and
continue.
We could leave the split variable names %current_time1 and %current_time2, but
that may be confusing should we need to revisit or modify the script later.
So, let’s give them the appropriate names of %current_hour and %current_minute,
respectively. Just as before, choose Tasker’s Variable Set action from the
Action Category -> Variable dialog. Once completed, you should have four
action steps created in your Say Time task.
Now let’s determine whether it’s a.m. or p.m. If the 24-hour value is less than
twelve, it’s a.m. If it’s greater than eleven, it’s p.m. Once again, call upon
Variable Set action, name the variable %am_pm, and then scroll down the
Variable Set form to the If field. Add the condition If %current_hour < 12. Since
this is a mathematical operation, select the Maths: Less Than choice from the
Select Conditional Operator menu accessed by tapping the gray tag icon in
the If row of the form. Once defined, the screen should look like Figure 27,
Variable Set form for the %am_pm variable, on page 48.
Do a similar type of operation for creating and setting the %am_pm variable to
p.m. if %current_hour is greater than eleven, as shown in Figure 28, Select Task
Action dialog, on page 48.
You may be wondering why I didn’t just create the %am_pm and use If and Else
actions from Tasker’s Task Action options. Simple—I’m lazy. My initial con-
struction accomplished the same objective in fewer steps.
We now have the current hour, minute, and a.m. or p.m. values, but if we
were to stop at this point, we would have a few problems. First, we want the
clock to read a 12-hour, not 24-hour, time clock. The existing version will
read midnight as “Zero A-M” and not the more appropriate “12 A-M.” If the
time is 11 p.m, we want our clock to say “Eleven o’clock P-M” and not
“Twenty three zero P-M.” And as the example error shows, we also need to
account for substituting a zero minute value with the more appropriate “oh”
sound. Lastly, we need to test for the condition when it is the top of the hour
so that we can append the word clock during the read.
Only a few more steps to go before our talking clock task is complete.
Let’s now take care of the “oh” sound by setting a new variable that we’ll call
%say_oh to the “oh” string. We will also need to add a step that will check to
see whether we need to include the “oh” in the time reading. You need to say
the “oh” word only when substituting for a zero in the second place of the
minutes field, such as 00 through 09. As such, we should omit an inserted
“oh” word for any minutes greater than nine minutes after the hour. To do
so, add another Variable Set step that sets the %say_oh variable to an empty
string If %current_minute is greater than nine.
Now let’s address the top of the hour by appending the word clock in the time
readout. Do so by setting the %current_minute variable to the word clock if the
%current_minute matches the value 00. Tasker uses the tilde (~) character to test
for matching conditions, as shown in Figure 29, Use the tilde character to test
for match equality.
Battery at %BATT %.
Adding the % symbol at the end of the string will make the read sound more
natural (for example, “Battery at 83 percent”). Just remember to put a space
between the %BATT variable and the percent symbol. Save and test the task
by selecting the task’s play button. Yep, all that information in just a single
line of instruction. That’s pretty cool, especially considering how much code
this would have taken to write if this were a native Android SDK application.
The final step we need to do before assigning a profile to our Talking Clock
task is to tell it to run our Battery Status task if the %current_minute value is
equal to the “clock” string (remember, we set that to “clock” earlier if %cur-
rent_minute matched 00). So, let’s add one last step to our Talking Clock task
by selecting Perform Task from the Select Task Action dialog. Save the step
and run the task to hear both the current time and current battery percentage
of your device. Now reopen the Perform Task step we just added and add an
If condition to check whether %current_minute matches the word clock. Now when
the clock time is at the top of the hour, the current time and remaining charge
will be read out loud. The steps of the full task should look like Figure 30,
The Complete Talking Clock Tasker task, on page 51.
There’s only one more requirement to address: have the time automatically
be spoken out loud every fifteen minutes during normal waking hours. To do
so, we will need to create a profile for our Talking Clock task.
Creating a Profile
Now that we have our Talking Clock task defined, we need to place it into
context by assigning it to a profile. Tasker profiles are triggers to run a task.
These triggers can be initiated by an application running on your Android
device, a starting and ending time that can also repeat at set intervals and
specific days (even weeks or months). This context can also be defined by a
location based on a predefined radius of GPS coordinates, the state of various
apps or hardware of your device (Tasker provides more than twenty states to
choose from), and events (more than forty events to choose from).
Since we want the Talking Clock task to run every fifteen minutes while we’re
awake, select the plus icon in the Profiles toolbar at the bottom of the screen.
Name the new profile Talking Clock and select the check icon to continue.
This will display a list of actions to associate the event with. Select the Time
menu option as our First Context. In the Time form, set the From time a half
hour before you wake up and the To time a half hour before you go to bed.
In my case, that’s 4:30 a.m. to 11 p.m. Check the Repeat check box and set
the Talking Clock Profile option to run every fifteen minutes, as shown in
Figure 31, The Talking Clock profile settings, on page 52.
When you’re satisfied with the start, end, and time intervals defined, select
the Time Edit label to save the settings. This will pop up a list of tasks you
defined. Select the Talking Clock task we created earlier. Once configured,
your profile should look like Figure 32, The Talking Clock profile.
Now that we have instructed Tasker to run our Talking Clock profile every
fifteen minutes during our waking hours, it should trigger your phone or
tablet to speak the time every quarter of the hour. If it doesn’t, make sure
your volume is turned up and your device isn’t on mute. Also, double-check
your profile to make sure it is enabled. Whew! We’re done!
clear the tasks you have compiled in Tasker. The backup will be stored in an
XML-formatted file called userbackup.xml and saved in the /sdcard/Tasker directory.
As you build more Tasker profiles and tasks, copy this backup file off the
device for safe keeping, just in case you need to restore the scripts or obtain
a new Android device that you want to run Tasker tasks on.
As you discovered with this project, Tasker might not have the expressive
scripting language of something like Ruby, but these constraints are a worthy
trade-off considering the power that Tasker has to offer. Play around with the
Talking Clock task by adding and subtracting steps. This will help you more
quickly understand how to affect the final output. You can use what you
learned in this example to create other talking alarm clock tasks, such as
creating a profile that executes at 6 p.m. with a task containing a Say action
reminding you that it is “Time to eat dinner.”
In the next Tasker example, we will build a much simpler but very powerful
task that will sound an alarm and hook that up to a profile that will trigger
the task when we reach a specified geographic location. Using it, you will
never fall asleep on a train or bus and accidentally miss your stop again.
Choose the Notify Sound action and for this example name the action Train
Stop Ahead. Tasker will display this name in Android’s notification bar area
when the action is triggered. If you prefer to display text other than the name
of the task we assigned, you can do so by entering it in the Notify Sound
optional Text field. Next, choose a sound file you prefer to play when this
action is triggered. This can be an audio file in any format that your Android
device can natively play back, such as a WAV or MP3 file. Select the file to be
played back by tapping the magnifying glass icon in the Sound File row and
navigating to and choosing the audio file you prefer. Once configured, your
configuration should look similar to the one in Figure 34, The Notify Sound
dialog.
Figure 33—The Select Alert Action dialog Figure 34—The Notify Sound dialog
Now that the Alarm task has been defined, we need to wrap it around a context
and create a profile that will sound the alarm when a radius within a defined
geographic location is entered.
Tasker sets the default geographic radius trigger to 30 meters and sets the
global GPS location sampling rate to 30 seconds. We could increase the
sampling rate value located on Tasker’s Monitor preference tab, as shown in
Figure 22, Network Location Check Seconds field on the Monitor tab, on page
43, but it would also burn up our battery charge. Instead, consider how much
distance a train might cover in thirty seconds and expand the trigger radius
accordingly. Change this value by selecting the Radius field (this will display
a list of distances in meters, as shown in Figure 35, GPS radius list of dis-
tances) and setting the GPS sampling radius.
Figure 35—GPS radius list of distances Figure 36—Map with GPS radius overlay
If you need additional time to wake up and gather your items, relocate the
trigger point a quarter mile (roughly 400 meters) or further from the station.
Also, expand the sampling radius to 600 or more meters depending on how
fast the train is traveling. I hope that Tasker’s developer allows users to enter
their own radius values in a future update, since I have found that the list
of radius choices can be limiting at times.
Once you have set your location marker and the desired sampling radius,
touch the Location Edit label to save your settings. Tasker will then ask you
to name the context that you just created. Call it Sound Alarm and assign
the Alarm task we created to this context. The completed profile screen should
look similar to the one shown in Figure 37, The Train Station Tasker profile.
Let’s increase the media playback volume before the Notify Sound event.
Select the Notify Sound step as before and select Notification Volume from
the Audio Settings Action category. The default level is 3, but we’ll bump that
all the way up to 7, the highest level. Assuming your sound file is normalized,
that sound level should definitely get your attention.
Now let’s add one more activity to get our attention after the Notify Sound
step. Select the plus toolbar icon in the Task Edit screen and add the Vibrate
action from the Alert Action category. The default vibrate duration is 200
milliseconds. Increase that to the full 1000 milliseconds (equal to 1 second).
If that isn’t a long enough duration, duplicate this step for as many seconds
as you need the phone to vibrate.
Test the revised profile to see how it performs, and tweak the audio levels,
GPS target location, and trigger radius until you consistently and reliably set
off the alarm at the time and location that works best for you. Once perfected,
remember to save your work!
Search for and install the Tasker App Factory from the Google Play market-
place.3 Once installed, the Tasker App Factory will add a new set of application
compilation features into Tasker that are easy to configure and use. Let’s find
out just how easy it is to create an Android app using Tasker by compiling
the Talking Clock task into a native TalkingClock.apk file.
3. https://play.google.com/store/apps/details?id=net.dinglisch.android.appfactory
Choose to export the task As App. This will display the Tasker App Factory
disclaimer, essentially reminding you that Tasker’s developer isn’t responsible
for anything bad that might happen as a result of running or distributing
your program. You take full responsibility for any damage that bugs in your
script, or even those of Tasker itself, might do to a user’s data or device.
After you accept the disclaimer, enter the package name (usually the
namespace of your domain plus the app name), the version of the program
you will build, and the name of the Tasker task you want to compile. Once
completed, your configuration screen should look similar to Figure 39,
Application package settings.
Once you have completed the required configuration details, select the Con-
figure Talking Clock label in the upper-left corner of the screen to export the
task to a compiled native Android package (.apk) file. Then you can install the
generated .apk directly on your device by selecting the Android robot icon
located in the lower right of the Export dialog box.
Note that during the application installation process, you will most likely
encounter a problem like the one shown in Figure 40, Blocked Installation
dialog when attempting to install the .apk file on your device for the first time.
This is because the Android OS by default prevents the installation of appli-
cations acquired from sources that are not directly obtained from the Google
Play store.
To allow Tasker to install the freshly compiled .apk file for you, you need to
give it permission to do so. This can be done by checking the “Unknown
sources” option in the Security section of the Android Settings screen (Figure
41, Allow app installations from unknown sources).
As one last security check, Android will alert you with an application display
screen (Figure 42, Talking Clock permissions alert dialog) to remind you what
permissions, if any, the application will be granted access to once it’s installed.
While you already know the reasons why your compiled Tasker app needs
the permissions it is asking for, others may not be aware of the data and
hardware your program will have access to. If you plan on distributing your
Tasker .apk files on Google Play, you had better make sure you have a good
reason for requesting the permissions you need. A rule of thumb that Android
users have learned over time is that any application that needs more than
three sensitive-level permissions is probably an application they won’t bother
installing.
4. http://tasker.dinglisch.net/userguide/en/appcreation.html
• Activate an automation Location profile when you arrive home that turns
on your indoor lights and your media center and sends a text message to
your family that you have arrived. For more home automation ideas using
a combination of Arduino and Android programs, check out my book
Programming Your Home [Ril12], published by Pragmatic Bookshelf.
• Create launcher toggles to turn on and off your most frequently used
hardware radios (Bluetooth, WiFi, GPS, and so on).
• Create a profile that turns off your phone’s radios at the time you go to
bed so you can get a good night of uninterrupted sleep.
• Capture and send a photo to your email account when the accelerometer
detects movement. Add audio playback of a scream or have your device
say “Put me down!” when the event is triggered.
• Detect incoming messages while driving and use the Say action to read
the text so you don’t have to take your eyes off the road.
• Develop your own Apple Siri or Google Now client using Tasker’s Get Voice
action combined with the HTTP Get action calling various web service
APIs.
Visit the Tasker wiki for dozens of preconstructed Tasker profiles to give you
a template to build your own Tasker scripts and applications.6
Next up, we’ll take a look at creating Android applications and services using
more traditional scripting languages like Python and Ruby. We’ll also discover
a couple more pleasant surprises along the way.
5. http://tasker.wikidot.com/plug-ins-and-3rd-party
6. http://tasker.wikidot.com/profile-index
While you won’t be compiling most of these scripts into native Android
applications, the sheer volume of code snippets and routines that have been
made public for these languages is huge. And because these scripting lan-
guages are accompanied by their own libraries that handle everything from
network protocols to regular expression parsing, you can accomplish a great
deal of data processing with a minimal amount of code. We’ll take advantage
of this fact as we revisit the Talking Clock script we previously created in
Tasker. We’ll rewrite it in Python and Ruby with help from a host application
called Scripting Layer for Android, better known as SL4A.
Because of the security model that Android enforces, applications must con-
form to and run within Android’s Dalvik virtual machine (VM). So unless you
have a rooted device and compile native system-level applications and drivers,
you have to stay within the Java-centric boundaries of Android’s VM.
differentiate Android from competitors like iOS because the early iPhone didn’t
allow such scripting languages to coexist on the platform. When it was first
introduced, it was called the Android Scripting Environment (ASE). SL4A
intended to become the host container for a variety of scripting languages.
SL4A can currently host seven languages:
• BeanShell 2.0b4
• Erlang
• JRuby
• Lua 5.1.4
• PHP 5.3.3
• Perl 5.10.1
• Python 2.6.2
• Rhino 1.7R2
Unlike most of the applications and utilities featured in this book, SL4A
oddly cannot be directly installed from the Google Play store. Instead, it has
to be side-loaded (installed by copying the Android program to the device via
a PC) or installed by downloading and installing it directly on the device. This
is perplexing, since the discoverability of public Android applications is almost
always made these days via a Google Play search. This is especially true for
newcomers to the platform. Perhaps this is one of the reasons why SL4A
continues to fly below the radar for many Android users.
You can download the sl4a_r6.apk file directly from its Google code repository.1
Your downloaded version may be a higher number from the Release 6 I used
in this book.
After the main SL4A container is installed, we will need to install both the
Python and Ruby interpreters for our code examples. Launch SL4A and select
View from the main menu. Then select Interpreters from the View pop-up
dialog box. This will list the SL4A-compliant interpreters currently installed
on your device. Select the Add icon from the Interpreters menu. A pop-up
dialog will display a list of available SL4A interpreters available for download.
1. https://code.google.com/p/android-scripting/downloads/
65) by opening the .apk file from your file system or via the “Download complete”
label in the notification tray.
Figure 43—Python for Android package Figure 44—Python for Android interpreter
and library bundles
Launch the downloaded Python installer to retrieve the interpreter files and
whatever additional Python modules you need to use in your Python scripts.
Do so by pressing the Install button on the screen when you load the Python
for Android program, as shown in Figure 44, Python for Android interpreter
and library bundles.
Besides the interpreter, you can also opt to install additional libraries that
have been compiled to work with Python for Android. At the time I wrote this
chapter, the prepackaged .egg modules freely available for download include
the following:2
2. https://code.google.com/p/python/python-for-android/wiki/Modules
• pyCrypto
• PyBluez
• pyEphem
• pySerial
• Twisted
• Zope
We won’t need any of these additional packages for our scripting needs, but
it’s pretty cool to know you can write a full-blown enterprise-class asyn-
chronous network application and dynamic web server running on an Android
phone.
Try running a few of the example scripts that came with Python for Android
by launching SL4A and selecting something like the say_weather.py or take_pic-
ture.py script. If these scripts execute successfully, we’re ready to do the same
for the Ruby interpreter.
Just a quick note before we start writing some code. While the built-in SL4A
editor can come in handy for quick scripts or minor edits to existing code,
using it to write programs spanning more than fifty lines of code is a stretch.
It’s much easier to do so on a tablet paired with a Bluetooth keyboard, and
it’s easier still to write and test scripts on a desktop PC. Part of the reason is
because of the desktop legacy these languages have inherited and partly
because of the additional screen real estate available on high-resolution
monitors.
But this is a temporary condition. As the rest of the world migrates to a mobile
device for the majority of their computing and communication needs and as
Joe asks:
Can I Compile a Ruby Script into a Native Android
Executable?
Yes, but you need a computer running Java, JRuby, the Android SDK, and a frame-
work called Ruboto to do so.
Ruboto has two components. The first is the Ruboto gem that allows for the coding
of real Android applications using a desktop computer and the Ruby syntax instead
of the Java syntax. Once the aforementioned software prerequisites are satisfied,
running the gem install ruboto command will install the Ruboto gem into the computer’s
Ruby gem collection. Then, generating a new Ruby-based Android program can be
done by typing ruboto gen app --package com.mydomain.myrubyapp at the terminal of your PC.
You can replace com.mydomain.myrubyapp with your domain and app name. Once the
basic app template has been generated, you can use Ruby syntax to call upon the
Android API for a native Android presentation experience.
The second component is called the Ruboto Core. This is the runtime library that is
installed on the Android device. It is required to execute Ruboto-generated Android
applications. One major benefit of installing the Ruboto Core over the standard
JRuby for Android runtime is that the Ruboto Core package is installed with an
Interactive Ruby Shell (IRB). It also installs a built-in editor and a cleaner user
interface. This makes Ruboto Core and Ruboto IRB useful not only for developing
Ruby scripts on Android but also for quickly testing Ruby code without having to
resort to a desktop to see the results. You can install the Ruboto IRB from Google
Play.a This will also prompt you to install the much larger Ruboto Core package.
If you would like to learn more about Ruboto, visit the http://ruboto.org website.
a. https://play.google.com/store/apps/details?id=org.ruboto.irb
Now that all the dependencies have been installed and tested, we can port
the Talking Clock Tasker script we created in the previous chapter to both a
Python and Ruby-scripted equivalent.
understand that you should be able to follow along. Let’s begin by considering
the Python port of the Talking Clock application.
❷ droid = android.Android()
❸ droid.ttsSpeak(time.strftime("The time is %_I:%M %p."))
❶ The first import statement imports the custom SL4A android library that
is used to access Android-specific hardware and software functions. You
will see this import statement in most Python SL4A scripts. The second
statement imports Python’s standard Time library, which we will use to
poll and format the current time.
❷ This line initializes the android object from the Android library we imported
earlier. We will use this object to pass a string value to Android’s text-to-
speech (TTS) parser.
❸ This line combines a few function calls. The first calls upon the time
library to poll the current time. This value is passed to the strftime() function
call that formats the current time into a preferred readable string. In this
case, we have reformatted the current hour string to a twelve-hour clock
(%_I), followed by a colon (:), followed by the current minutes (%M) and
whether it’s a.m. or p.m. (%p). This formatted string is then passed to the
android strftime() function, where the formatted time is read by Android’s
default TTS engine.
You can enter this code directly into your Android device using the rudimentary
text editor included in SL4A. To do so, select the Add icon from SL4A’s main
menu, and select Python 2.6.2 from the Add pop-up dialog. SL4A assists by giving
you a head start by generating the import android statement and creating the droid
object. However, as these scripts grow in length, it may be easier to either pair
To run the script, simply select talkingclock.py from the list of scripts on the
SL4A main scripts listing. Then select the sprocket icon on the toolbar that
pops up. As long as the code was typed in correctly and the volume is turned
up loud enough, you should hear your Android device speak the current time.
By the way, if you’re interested in learning more about programming in Python,
check out Practical Programming: An Introduction to Computer Science Using
Python 3 [CGMW13] by Jennifer Campbell, Paul Gries, Jason Montojo, and
Greg Wilson, available from Pragmatic Bookshelf.
That’s a pretty impressive feat to be able to speak the current time in three
lines of code, and it nicely shows off the power of the Ruby language.
If you’re new to programming and want to learn the fundamentals using Ruby
syntax, Chris Pine’s book Learn to Program [Pin09] uses the language to teach
programming essentials. If you want to delve deeper into understanding Ruby,
check out Pragmatic Bookshelf’s Programming Ruby 1.9 & 2.0: The Pragmatic
Programmer’s Guide [TFH13] by Dave Thomas, Chad Fowler, and Andy Hunt,
which is affectionately known as the Pick-Axe book.
4. http://tasker.wikidot.com/sl4a
If you don’t want to rely on Tasker to run the script at timed intervals, you
could wrap either the Python or Ruby script in an infinite loop. The loop’s
query condition would check the current time once a minute and see whether
the current minute string value is 00, 15, 30, or 45. If it is, then execute the
speech event. However, this ties up the resources required to run the script,
and SL4A already takes up a lot of system resources.
A third possibility would be to search the Google Play store for a utility that
acts like a cron job scheduler (a Unix term for a task triggered at a predefined
time). It just so happens that one exists. TaskBomb is a free (albeit ad-sup-
ported) service application that works like Tasker in that it executes applica-
tions at given times and/or time intervals.
By default, TaskBomb does not include built-in support for SL4A. So Ken
wrote a TaskBomb add-on called the SL4A Script Launcher.6 This extends
TaskBomb to kick off SL4A scripts the same way Tasker’s Run Script action
works. Installing the SL4A Script Launcher from the Google Play market will
add a “Select script” option to TaskBomb’s Task definition Data field. With
everything installed, we can build a scheduled task that will run the talking-
clock.py script every fifteen minutes.
Launch the Script Launcher program and touch through the welcome and
tutorial screens. If you plan on using TaskBomb beyond our simple talking
clock example, take advantage of the online documentation and tutorial videos
that Ken has created for the product. And if TaskBomb fulfills your needs,
consider paying for the ad-free version.
5. https://play.google.com/store/apps/details?id=org.androidideas.taskbomb
6. https://play.google.com/store/apps/details?id=org.androidideas.scriptlauncher
1. Select the Tasks icon (it looks like a stick of dynamite). This will take you
to the Tasks screen.
2. Select the + symbol in the upper-right corner of the Tasks screen to add
a new task. This will take you to the Task definition screen.
3. Assign a name to the task (for example, Talking Clock) and, in the case
of the Python version of the Talking Clock script, assign it the talkingclock.py
script by selecting the Data option. This will pop up with a “Select data
using” dialog. Choose the “Select script” option. This will display the files
in the default SL4A scripts directory.
4. Choose the talkingclock.py script. The task has been defined. Now all we have
to do is schedule it to run every fifteen minutes. To do so, return to
TaskBomb’s main screen and select the Schedule icon (it’s the one that
looks like a bundle of dynamite). Select the + icon to create a new schedule.
5. Give the name of this new schedule Talking Clock Every 15 Minutes. Next,
select the Item field and assign the Talking Clock task we created earlier
to the schedule. This will display the Item screen.
6. Leave the Start Time and End Time fields with their default settings, and
just change the Repeat Interval field to 15 minutes. Touch the back button
to save your changes.
7. The last step we need to take to get the task running is to assign the
schedule a Default duration. This is how long the task will run before
having to return to TaskBomb to restart the task. Since we want to run
the Talking Clock task for as long as possible, set this value to 99:59:59.
This will run the task every fifteen minutes for the next four days.
TaskBomb isn’t the best task-scheduling software available, but it’s certainly
cheap and, more importantly, it works.
support the shift to Unix, someone will no doubt crack the new language nut
that will become the baseline upon which future programming paradigms
will be constructed. In the meantime, we will contend with the advantages
and disadvantages of today’s popular languages during this postdesktop
transition phase.
So far, we have considered only the more popular languages that can be
hosted within the SL4A shell. While Perl, Python, and Ruby cover a major
segment of the programming market, more ported languages are showing up
in the Google Play market all the time. Here’s a look at some of the more
interesting additions:
• Clojure REPL7
• Haskell8
• Lisp9
• Scala10 (requires root access)
• Scheme REPL11
Keep in mind that no matter how elegantly we structure our scripts using
the approaches described in this chapter, the system resources (memory,
processor utilization, and so on) consumed by interpreted scripts running on
the phone are often considerably higher compared to a native Android appli-
cation counterpart.
7. https://play.google.com/store/apps/details?id=com.sattvik.clojure_repl
8. https://play.google.com/store/apps/details?id=nl.bneijt.tryhaskell
9. https://play.google.com/store/apps/details?id=info.gomi.android.lisp.islisp
10. https://play.google.com/store/apps/details?id=com.mobilemagic.scalainstaller
11. https://play.google.com/store/apps/details?id=com.folone.replscheme
Processing can do more than just pretty graphics. It has access to all the major APIs,
hardware sensors, radios, touch points, and just about everything else you may need
to create a native Android application. Processing’s syntax is also intuitive and easy
to learn, allowing anyone with basic computing skills to create useful Android pro-
grams at a vastly faster rate compared to using the standard Android SDK.
To learn more about Processing for Android, read Daniel Sauter’s Rapid Android
Development: Build Rich, Sensor-Based Applications with Processing [Sau12], published
by Pragmatic Bookshelf, or visit the Processing for Android wiki page on the Processing
website.a
a. http://wiki.processing.org/w/Android
Since most of the SL4A-supported languages offer access to the Android API
as well as the considerable number of libraries available for them, the potent
combination of scripted access to API calls allows for some really creative
uses. Here are a few ideas worthy of further exploration:
• Use the camera to take a snapshot of a bar code or QR code and perform
a Google lookup of the code along with a Google Images query. Pull down
the results and display them in a dialog box along with price and rating
details of the product in question.
• Use the respective APIs for popular web services like weather forecasts,
music searches, reviewing databases, or package delivery. Poll for
weather in your area based on your GPS coordinates, pull down the
results, and read them to you via Android’s text-to-speech engine.
• Submit song title and artist queries to a music search service based on
a scan of your MP3 library. Return results could be everything from images
of the artist to reviews of the songs or albums being searched.
• Create your own dynamic Android web server using the various web
microframeworks, like Bottle and Flask for Python or Camping and
Sinatra for Ruby.12
In the next chapter, we will put this concept into practice by creating a true,
native Android SDK–based application. What’s more, we will compile this
application entirely on an actual Android hardware device. That’s right. Unlike
other mobile platforms like iOS, BlackBerry, or Windows, you can compile
and deploy real, native Android applications using just your Android phone
or tablet—no other computer required.
Compared to the scripting approaches we took earlier using Tasker and SL4A,
native apps built with the Android software development kit (SDK) will typi-
cally consume far fewer system resources. They also often run faster than a
Tasker or SL4A script because no intermediary interpreter is required to
convert the scripted actions into executable code.
You will also be ahead of the class by having some familiarity with the Android
SDK,1 though this is not required. The calls that we will make to the Android
APIs are not difficult to follow. The API documentation is also just a click
away online for those who want to read about all the various parameters that
can be passed to the functions we will be calling.
For those who would feel more comfortable learning more about the Java
language before proceeding, there are numerous books, screencasts, and
online resources available, and many of them are free. And for those who
would like to learn more about traditional Android programming using a
desktop computer, check out Pragmatic Bookshelf’s Hello, Android: Introducing
Google’s Mobile Development Platform [Bur10] by Ed Burnette.
As you become more comfortable with Java and the various Android APIs,
you will be able to build upon simple programs like the one presented in this
chapter using more sophisticated API calls and programming logic. Like most
anything else in the computing field, the more you use, the more you learn.
The more you learn, the more you apply. The more you apply, the more you
use.
1. http://developer.android.com/sdk
2. https://play.google.com/store/apps/details?id=com.aide.ui
(albeit limited) version and a premium key (costing up to $10, though some-
times on sale for much less) that unlocks all the limitations imposed by the
free edition. While the limitations of the free edition won’t prevent you from
completing the Talking Clock project in this chapter, I recommend purchasing
the premium key. Not only will it give you unrestricted file counts and add
Git source code management support, doing so will also properly compensate
appfour GmbH for all that hard work.
The first thing we will do is install AIDE. Then we will create a new project
with it. We’ll then remove some of the template-generated code we don’t need
and add the code we do need. Then we will compile, install, and run our
Talking Clock conversion and discuss ways that we can take the project to
the next level.
worth checking out on your own, but we will stick with the Hello World tem-
plate. We will be making a few modifications and additions to the main class.
Select the Hello World project and press the Create button. AIDE will generate
all the necessary files and images required for a basic form-based Android
application and open the MainActivity.java file in AIDE’s code editor. The contents
of this file are pretty basic.
package com.mikeriley.talkingclock
import android.app.*;
import android.os.*;
import android.view.*;
import android.widget.*;
We will use this file as a starting point for our native Talking Clock project.
This will compile the app and attempt to install it on your phone. However,
as we saw with the Tasker App Creator, Android’s security model prevents
apps from arbitrarily installing on your device unless you give explicit permis-
sion to do so. As such, Android will display the error shown in Figure 47,
Block application installations from unknown sources is enabled by default on
Android, unless you set the security with the appropriate developer options
earlier.
If this security dialog does appear, select the Settings button and check the
Unknown Sources option on the Security settings screen to allow AIDE to
install and execute our program. However, note that when you are not using
AIDE to compile and launch applications, you should really disable the
“Unknown sources security” setting. Otherwise, your Android device will be
vulnerable to malicious applications installing bad things on your hardware.
With the “Unknown sources options” checked, return to AIDE and run the
program again. This time, Android will ask if you want to install the applica-
tion. If there are any permissions used by the app, it will list them. In the
case of this application, there are no special permissions. Go ahead and select
Install. When that’s done, select Open. This will display the main form of the
program, as shown in the following figure.
Next we need to replace the boilerplate code that the Hello World project
template generated in the MainActivity class with our own code. Once we declare
a unique package name for the app so that it won’t conflict with other pro-
grams on the device, we import the code libraries that we need to call the
battery status on the device and perform a text-to-speech conversion of the
time. Finally, we will close down any open resources and cleanly exit the
program after the time is spoken.
Use a Keyboard
If you plan on typing in this code on an Android phone via the onscreen keyboard,
you are far more patient than I am. Instead, you can use a paired Bluetooth keyboard
or, faster yet, download the code sample from the book’s website. You can also edit
MainActivity.java on a desktop computer, email your phone a copy, and then paste it to
the Talking Clock project directory on your Android device.
MainActivity.java
package com.mikeriley.talkingclock;
❶ import android.app.Activity;
import android.content.BroadcastReceiver;
import android.os.Bundle;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.speech.tts.TextToSpeech;
import android.speech.tts.TextToSpeech.OnInitListener;
import android.os.CountDownTimer;
import java.text.SimpleDateFormat;
import java.util.Date;
@Override
❻ public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
registerReceiver(mBatInfoReceiver,
new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
tts = new TextToSpeech(this, this);
}
@Override
❼ public void onInit(int status) {
if (status == TextToSpeech.SUCCESS)
{
Date todaysDate = new java.util.Date();
SimpleDateFormat hour = new SimpleDateFormat("h");
SimpleDateFormat minute = new SimpleDateFormat("m");
SimpleDateFormat ampm = new SimpleDateFormat("a");
String sHour = hour.format(todaysDate);
String sMinute = minute.format(todaysDate);
String sAMPM = ampm.format(todaysDate);
if (sAMPM.equals("AM")) {
sAMPM = "A M";
} else {
sAMPM = "P M";
}
String current_hour = sHour.concat(" ");
current_hour.replaceAll("00 ", "");
if (sMinute.contentEquals("0")) {
sMinute = "o clock";
} else {
if (sMinute.matches("\\d")) {
sMinute = "o ".concat(sMinute);
}
}
❶ Here we will import all the libraries we need to call upon for the program’s
functions. Note that we don’t need to import every class that the android.app.*
and android.os.* libraries offer, just the android.app.Activity, android.os.Bundle, and
android.os.CountDownTimer.
❷ To call upon the TTS engine, we have to implement the OnInitListener interface
with the MainActivity class. This will also enforce declarations of the onInit(),
onTick(), and onFinish() event handlers within the class, whether we use them
or not.
❸ We need to create two public variables, batlevel and charging. These will hold
the text string values of the current battery level and whether the battery
is charging.
❼ This is the heart of the program. Here we create variables to obtain the
current time by calling the standard java.util.Date() Java call and then break
that value down into its hour, minute, and a.m./p.m. components using
a series of SimpleDateFormat objects. And just like we did in the Tasker
Talking Clock script, we need to account for the twelve-hour clock, top of
the hour “o’clock,” and 01–09 minute “oh” designations. Then we concate-
nate the hour, minute, and a.m./p.m. strings together with the battery
level string we obtained earlier in order to have a complete sentence to
pass to the TTS engine for output.
❽ This is where we pass the compiled time and battery level string to the
TTS engine to speak the output. We also need to put in a three-second
CountDownTimer() to account for the reading of the string. If we don’t put this
delay into the program, we won’t hear anything spoken because the pro-
gram will exit before the speech has finished. While three seconds has
worked for me, you may need to extend this to four or five seconds (4,000
or 5,000 milliseconds) if you happen to hear the end of the sentence being
clipped when spoken.
❾ We don’t use the onTick() event in this program, but we have to declare it
to satisfy the OnInitListener implementation we used in the MainActivity class.
With the code out of the way, we’re ready to give the project a spin!
Now here’s the kicker. Remember when we used Tasker to generate the
Talking Clock app in the previous chapter? Well, take a look at the difference
in application size of the Tasker App Factor–compiled version vs. the native
AIDE-assisted one in Figure 49, Native applications make a difference, on
page 85.
The Talking Clock program with the generic Android icon is the native program
we just created, while the Tasker-generated program is the one with the clock
icon that we assigned to the Tasker task and compiled in Section 4.4, Tasker
App Factory, on page 57.
But there are alternatives we can consider. The most obvious is using Tasker’s
Load App task to launch our compiled Talking Clock program via a profile
that runs every fifteen minutes. Of course, this goes counter to the resource-
saving benefits of native apps that we just talked about. Besides, what’s the
point if we can just write everything we need in a Tasker script anyway?
We could also use a scheduling application like TaskBomb to kick off the app,
but that’s still a bit of a hassle to set up and run. And when it comes right
down to it, do we really want our phone or tablet announcing the time every
fifteen minutes regardless of where we’re at or what we’re doing? Wouldn’t it
3. http://xamarin.com/monoforandroid
4. www.adobe.com/go/HRTDI
We’re going to assign the Talking Clock program with a headset button click
action. I prefer using a triple-click assignment to make it more unique. When
the headset button is clicked three times in a row, Headset Button Controller
will launch our Talking Clock program. And because the Talking Clock app
has no user interface, we don’t have to worry about fiddling with a user
interface while driving or walking. It’s really convenient!
Compatibility Disclaimer
Note that the Headset Button Controller application works only with certain types of
Android devices and headsets. For example, my Samsung Galaxy Nexus phone works
perfectly with a Samsung single-button stereo headset, but my Asus Nexus 7 does
not support headset buttons and therefore responds only to headset plug-in/plug-
out actions.
Launch the Headset Button Controller application. Select the “Triple click”
action from the Easy menu and select Launch app from “Triple click” list of
options. The Headset Button Controller will then list all the applications
installed on your Android device. Choose the Talking Clock application we
compiled using the AIDE. Your screen should look similar to the one shown
in Figure 50, Assigning Talking Clock to a triple-click headset button action,
on page 87.
Let’s do one more assignment with Headset Button Controller and run our
Talking Clock application when we plug our headphones into our phone.
Select the program’s Advanced tab and scroll down to the “Plug in action”
option within the “Headset plug in/out” category. Choose “Plug in action”
followed by the “Launch app” option. Then select the Talking Clock application
from the list. When you’re done, your screen should look similar to Figure
51, Assigning Talking Clock to a headset plug insertion action, on page 87.
Test the assignments by plugging your headphones into your phone. You
should hear the time and current battery status through your headset. If you
don’t, check your settings and headset volume. Once you have confirmed that
the headset plug-in action works, test the triple-click assignment by triple-
clicking your headset button. You should hear the same results as the plug-in
test. Lastly, plug your phone into a charging cable while you have your
headset attached, and triple-click the headset button. You should hear the
time, the battery charge level, and the phrase “and charging” indicating that
your Android phone is currently charging. Pretty sweet! As you build more
native Android applications like the Talking Clock, you can expand your
headset control by assigning other available headset button actions to your
applications. Pretty soon you will be able to consume and react to many
activities on your Android device without even looking at your screen. You
could live a good portion of your mobile life with just a few clicks of a headset
button.
• Write an integrated file transfer utility that uses Android’s WiFi Direct
protocol,6 allowing you to quickly transfer files between devices without
having to be connected to a WiFi access point.
• Capture a series of audio notes, process them through the Google Translate
API,9 and send the output via email or SMS to a foreign language–speaking
recipient.
5. http://developer.android.com/guide/topics/providers/calendar-provider.html
6. http://developer.android.com/guide/topics/connectivity/wifip2p.html
7. http://developer.android.com/guide/google/gcm/index.html
8. https://developers.google.com/appengine/
9. https://developers.google.com/translate/
• Create a Near Field Communication (NFC) client that pairs with the door
lock to your home or office and unlocks it with a secret code.11
In the next part, we will create a fully functional Android widget. But instead
of relying on AIDE to build it, we’re going to create the widget entirely using
Tasker. By doing so, we will discover the advantages and trade-offs made
between native Android application development and scripted, task-driven
development.
10. http://developer.android.com/guide/topics/location/index.html
11. http://developer.android.com/guide/topics/connectivity/nfc/nfc.html
Build
The widget we will build is a countdown timer based on the Pomodoro Tech-
nique.1 The basic idea behind a Pomodoro is simple—work distraction free
for twenty-five minutes several times throughout a workday. There are a
number of other details that go into successfully implementing the Pomodoro
Technique into your own workflow, but our project widget will focus on
replicating the physical kitchen clock timer that Pomodoro masters have
popularized. If you’re interested in learning more about the various aspects
of the Pomodoro Technique, check out Staffan Nöteberg’s Pomodoro Technique
Illustrated: The Easy Way to Do More in Less Time [Nö09], available in both
print and audiobook formats.
For this project, we are going to leverage the rapid prototyping power of Tasker
to help visualize the behavior of the widget. Once we have embodied the basic
functionality using Tasker, fans of system optimization can consider converting
the Tasker version into a native Android widget using a programming tool
like the AIDE.
1. http://www.pomodorotechnique.com
our end product will morph based on how we end up using the widget. Using
this approach, we can quickly implement design modifications and see
immediately how these changes affect the experience. This is especially
important early in the development phase, where we still might not know
exactly what features we want to emphasize.
We will begin by first outlining the basic functionality of what we want the
application to do and then wire up this design in Tasker. We will encounter
a few unexpected issues along the way, not apparent before we began the
process, that will prompt us to make compromises in the app design as well
as take advantage of the operating system. By the end of this chapter, we will
have created a Tasker-based widget that fulfills a majority of our design goals.
By the sound of it, using Tasker’s Task Timer widget satisfies most of our
application’s requirements. Yet before we jump to placing this Tasker widget
on the home screen, we first need to construct the task that the widget will
run when the countdown is finished.
First Task
When the timer expires, we want to hear an audio cue and feel the phone
vibrate, so let’s build a task to do just that. Open Tasker and select the Tasks
tab. Create a new task by selecting the plus icon. Call the task Pomodoro in
the New Task textbox that pops up. Select the check icon to accept the name
and proceed to the task definition dialog. Add a task that plays a sound. We
will eventually have Tasker play a custom sound of our choice, but in the
interest of saving time in this initial design pass, select an existing ring tone
for the audio cue.
Next, select the plus icon in the lower toolbar to add a new task, and choose
the “Media action” category. From there, choose the Play Ringtone action.
Select your ring tone of choice by touching the magnifying glass icon to the
right of the Sound property. This will display a list of all the ring tones avail-
able on your phone. You can play back this sound via Android’s six sound
channels by selecting the list of Stream options. Let’s leave it on the default
Notification channel. Touch the Action Edit label in the upper-left corner of
the form to save this first step in the Pomodoro task.
Now let’s add the Vibrate step. Select the plus icon to add a second step to the
Pomodoro task, and choose the “Alert action” category. Then select Vibrate from
the grid of alert actions. The default duration of the Vibrate function is 200 mil-
liseconds. This brief burst may be too short to notice, so let’s triple this vibration
time to 600 milliseconds.
Finally, let’s assign a built-in icon to the task so that when it appears on the
home page in its widget trigger form, it looks more appropriate than Tasker’s
default sprocket icon. Select the Image Select icon on the far lower-right corner
of the Pomodoro task dialog. It looks like a gray checkerboard. By selecting
this icon, the Image Select pop-up will appear, allowing you to choose the
source of your icon. Select Built-In Icon. This will display a variety of icons
that are available to all Tasker profiles and tasks. One of those built-in icons
is a clock. Choose that, and Tasker will show that icon when the widget
associated with that task is displayed on the home page. If everything went
according to plan, your Pomodoro task should look like Figure 53, The
Pomodoro task in Tasker, on page 96.
With our task defined, we can now assign it to the Tasker countdown widget.
Countdown Widget
Return to Android’s home screen and select the Task Timer Tasker widget
from the Android Widget screen or via the selection dialog that pops up when
you press and hold your finger on the home screen. Place the Task Timer
widget on an open area on your home screen and assign the Pomodoro task
we just created to the timer. Before accepting the selection, press the timer
clock in the lower-right corner of the Widget/Pomodoro dialog that appears
and set the Minutes field to 25. Select the green check to approve the settings.
This will place the timer on your home screen and preset the clock timer to
twenty-five minutes, ready for action. The home page widget should look
similar to Figure 54, Setting the Pomodoro Timer widget.
Figure 53—The Pomodoro task in Tasker Figure 54—Setting the Pomodoro Timer
widget
Pomodoro dialog. If the ring tone isn’t loud enough or the vibration isn’t long
enough, tweak those settings until they work best for you. Then return to the
home screen where you placed the Task Timer widget and select the clock
icon associated with it. This will display a large timer dialog with Days, Hours,
Mins, and Secs preset for twenty-five minutes based on our earlier starting
timer value assignment. Select the OK button in the lower-right corner of the
dialog to start the countdown.
The timer readout text on the widget will turn green, indicating that the
countdown clock is running. You can pause the countdown by tapping this
green text readout, upon which the timer text will change from green to red.
Tapping the text again will start the countdown again where it left off. To reset
the timer, tap the clock icon we assigned the task to once again pop up the
timer dialog. The timer value will return to its original default of twenty-five
minutes. You can also change the value here as well, such as setting it for
two minutes to test the task trigger vs. waiting a full twenty-five minutes.
Select the green check icon to proceed with the countdown. When the Task
Timer widget text reads 00 00 00 00, the Pomodoro task we created should kick
off, playing the assigned ring tone and vibrating the phone for a little more
than half a second.
So, if the timer behaves erratically, force the task to keep your Android device
awake by editing the Pomodoro task in Tasker and selecting the Task Proper-
ties icon to the right of the clock icon we assigned earlier in the Task Edit
dialog. Then check the Keep Device Awake box and heed the warning that
Tasker reminds you about battery drain when selecting this option for
resource-intensive tasks.
How about playing a wind-up sound that emulates a real kitchen clock timer
and sounds a ding from that same kind of timer at the end of the Pomodoro?
Wouldn’t it also be nice for the Android network radio to turn off so we aren’t
interrupted with email notifications and Twitter tweets and turn back on
when the Pomodoro session has finished? To add these and other enhance-
ments, we need to take a different approach to our widget construction. Let’s
proceed to do just that.
1. Before the countdown begins, play an audio clip of a kitchen clock timer
being wound up.
2. Turn off the cellular and WiFi radios so we can minimize disruptions for
the duration of the Pomodoro.
4. When the countdown reaches zero, display the phrase “DONE!” in the
widget’s label area, play an audio clip of a kitchen clock timer’s ding
sound, and vibrate the device.
5. When the Pomodoro is done, stop the task and turn the cellular and WiFi
radios back on.
We could add other tasks as well with the start and stop events of the
Pomodoro, but these should give us enough to work with for now. But because
of the way the Task Timer widget works and displays the countdown clock,
we’re going to have to ditch it in favor of Tasker’s other widget, simply called
the Task widget.
Note that while these audio files can be freely downloaded as part of this book’s source
code bundle from the Pragmatic Bookshelf website and used in your own applications,
please be kind and attribute Andy’s work if you use the audio clips in any applications
that you distribute. Free is nice, and being courteous about it is nicer!
Once you have obtained an MP3 audio start clip of your choice (for the pur-
poses of this exercise, I’ll assume you chose the pomostart.mp3 file), copy the
file to the Ringtones folder on your Android device. You can do this either by
downloading the file from the Web and saving it directly in the /sdcard/Ringtones
folder or by mounting Android’s file system on your computer and copying it
via either File Explorer on Windows or the Android File Transfer program for
OS X.2 You might as well save some time and copy the sound clip for when
2. http://www.android.com/filetransfer/
the timer countdown expires, and I’ll assume you chose the pomostop.mp3 file
available from this book’s code download bundle.
With both MP3 audio clips now stored in the /sdcard/Ringtones folder, launch
Tasker and create a new task called PomoStart. Then create a step that plays
the pomostart.mp3 audio file. Do so by selecting the plus icon in the lower toolbar
of the Task Edit dialog. Then select the Media category followed by the Music
Play option. With the Music Play screen displayed, select the magnifying glass
icon to the right of the File label and navigate the File Select dialog to the
Ringtones folder. Then choose the pomostart.mp3 file. Upon doing so, the screen
should look like the figure shown here.
Joe asks:
Why Can’t I Automatically Turn On and Off
Android’s Airplane Mode or GPS Radio?
Prior to Android 4.2 (aka Jelly Bean), you could enable and disable Android’s airplane
mode or GPS radio from an Android application or Tasker task. Beginning with the
release of Jelly Bean, Google smartly decided that it wasn’t a good idea to give appli-
cations the ability to turn on and off Android’s cellular and GPS radios. For example,
consider a scenario of traveling overseas where cellular data rates are exorbitantly
expensive. You explicitly turn on airplane mode to block the phone from connecting
to the cell towers to exchange data.
Thinking that all is well, you discover midway through your trip that a demanding
application decided to override your settings and forcibly disable airplane mode and
allow your device’s cellular radio to chatter away. Worse yet, a malicious application
could decide to upload your screen activity captured from the previous day at 3 a.m.
when you’re likely asleep. You would expect to have the airplane mode protect your
device from these scenarios, and it would be quite an angry disappointment if the
phone took instructions from something other than you for such a critically important
setting.
If you still have a burning desire to activate and deactivate the airplane mode or GPS
radio within a Tasker task, you can do so by jailbreaking and rooting your Android
device. Doing so will not only provide Tasker with the elevated system privileges of
turning on and off airplane mode but also grant control to a number of other system-
level functions, including forcing the display to stay on regardless of power settings,
putting the WiFi radio to sleep, and rebooting the phone.
Add the WiFi Off action to the PomoStart task by selecting the plus icon, and
select the “Net action” category. When the Net Action Category dialog is dis-
played, choose the WiFi action and leave the default value set to Off. Do the
same thing for the Mobile Data action by choosing the plus icon to add a new
action. Select the Net action category and then the Mobile Data option. Like
the WiFi action, set the Mobile Data option to Off.
Return to the PomoStart task edit dialog. Before trying the expanded task,
check to see whether your WiFi and Mobile radios are turned on. Return to
the PomoStart task edit dialog and select the play icon to run the task. After
the clock winding sounds, your mobile and WiFi radios should turn off. Verify
this by opening Android’s web browser and attempt to load your favorite
website. The browser should complain that the web page you were trying to
reach is unavailable.
1. Create a new action in the PomoStart task via the task’s plus icon and
select Variable from the Select Action Category dialog. Then choose the
Variable Set action. Create a new global variable name called %COUNTDOWN
and set its initial value to 25 to represent the duration of the Pomodoro.
Now that we have initialized the clock to twenty-five minutes, we need to
actually start the countdown. But we won’t be able to do that until we
define a second task that manages the clock countdown behavior. Let’s
do that next.
2. Create a new task and call it PomoWidget. This is going to be the task
that is run when PomoStart calls on it to start running. After that, we
need to decrement the value of the %COUNTDOWN variable each time the
PomoWidget task is called. How do we run the PomoWidget task at a fixed,
repeating time duration? We will need to create a time-based profile that
triggers the PomoWidget task to run. But before we do that, we first need
to define a few more actions in the PomoWidget task.
Besides getting the PomoWidget task to run at a set interval, we also need to
stop the countdown once it reaches zero, play back the pomostop.mp3 audio
clip, vibrate our Android device, and turn the WiFi and Mobile Data radios
back on. Let’s work backward and address the latter requirements first.
We already know how to turn on and off the WiFi and Mobile Data radios
from the PomoStart task, so let’s repeat those actions in the PomoWidget task
with one small addition. Select the add action plus icon and then the Net
action category followed by the WiFi action. Set the WiFi option to On. Since
we don’t want the WiFi radio to turn on until the timer reaches zero, also
select the If check box in the WiFi action dialog to check whether %COUNTDOWN
is less than the value of 1. Once set, the WiFi action dialog should look like
Figure 56, Set WiFi On Action dialog, on page 103.
Save the changes and repeat these same steps for the Mobile Data action.
And just as we set the PomoStart task to play back the pomostart.mp3 audio
file, we will do the same by assigning a new action to play the pomostop.mp3
file.
Good work! But we still have a few more things to take care of, namely, setting
the Pomodoro task to execute at set intervals as well as show the remaining
Pomodoro Profile
To decrement the countdown value to eventually reach zero, we will create a
Tasker profile to run the PomoWidget task at a set timed interval. Create a
new profile by clicking the plus icon in Tasker’s Profile tab and call the new
profile Pomodoro.
When the First Context dialog pops up, select the Time option since we want
to run the PomoWidget task at a timed interval. In the screen that follows,
deselect the check marks for the From and To ranges and then select the
Repeat check box. Then set the repeat value to run the task every one minute
and select the green check icon in the lower-left corner of the dialog to accept
the value. But there’s a problem. Tasker won’t accept our value of running
the task every one minute, as you can see in the following figure.
the context when the countdown reaches zero. Lastly, it would be good user
feedback to see the current value of %COUNTDOWN on the widget’s icon text field
so we know how much time is remaining before the countdown clock expires.
1. To address starting the Pomodoro context upon the touch of the widget
icon, we can call upon a helpful task action in Tasker called Profile Status.
Open the PomoStart task for editing and add a task. Select the Tasker
action category, followed by the Profile Status action. Name the Profile
Status action Pomodoro and set the task to On. This means that when
the PomoStart task is run, it will turn on the normally disabled Pomodoro
profile containing the instruction to run the PomoWidget action every two
minutes.
Time Remaining
With the starting and stopping actions of the
Pomodoro profile interval timer in place, we’re
almost ready to test our widget. But before we
do, we still need to display the remaining time
on the widget. It would also be a nice touch if
Figure 58—Turning off the
we displayed “DONE!” in addition to the other
Pomodoro profile when the
concluding tasks we set up earlier (turning the
countdown ends
radios back on, playing the pomostop.mp3 audio
file, and so on). The “DONE!” label will also come in handy when testing for
the first time you touch the widget to start the clock.
1. Open the PomoWidget task for editing and add a Variable Set action via
the plus icon; then select the Variable Action category and then the
Variable Set action. In the Name field, enter the %COUNTDOWN variable we’ve
been tracking all this time. But instead of setting it to a number, we are
Finishing Touches
Let’s do one more thing and place the prover-
bial cherry on top of our creation. Let’s assign
an icon to the PomoWidget task so that when
we place the Tasker widget on our home
screen and assign it to the PomoWidget task,
Tasker knows to use the icon we assigned the
PomoWidget task rather than Tasker’s default
sprocket icon. Assign the icon by opening the
PomoWidget task for editing and selecting the
checkerboard icon in the lower-right corner.
This will display the Image Select dialog. You
can assign whatever image you like for the
icon. These include existing application icons,
bundled icons installed with Tasker, and
individual icon files. Icon sets for Tasker can
also be downloaded from the Play app store
or obtained from commercial websites like
Iconfinder.3
Verify that these screens look similar to yours, making sure to account for
the %COUNTDOWN variable assignments and conditional tests in the right order.
3. http://www.iconfinder.com
The big moment has finally arrived. It’s time to try our Tasker-constructed
Pomodoro widget and see whether it performs the way we expect it to perform.
Creating our widget on the home screen is similar to the way we did it earlier.
But this time, instead of selecting Tasker’s Task Timer widget, we’re going to
choose Tasker’s Task widget. Upon doing so, Tasker’s Task Selection dialog
will pop up onscreen. Locate and select the PomoWidget task. Tasker will
then display the PomoWidget task in case we want to do any further editing
before we accept the placement of the widget. Since we don’t have any addi-
tional editing to do at the moment, select the check mark to set the widget
on the home page. Note that the initial icon text of the widget partially displays
the PomoWidget label.
If you don’t disturb the widget, you will eventually notice that the label will
refresh and show the number 25. Two minutes later, it should read 23, and
so on. Or at least that’s what is supposed to happen. But that’s not what is
happening. Instead of decrementing the countdown by two units every two
minutes, it is decrementing the number by only one. Why is this happening?
Return to the home screen where you placed the PomoWidget task-assigned
widget. Now repeatedly touch the widget to more quickly advance the count-
down. Observe that with each touch, the countdown value will decrement the
displayed countdown value by 2. The reason for this behavior is because
when you touch the widget, you are executing the PomoWidget task again.
Doing so decrements the %COUNTDOWN variable accordingly.
Keep touching the widget until it displays the “DONE!” label. When “DONE!”
finally shows up, you should also hear the Ding! audio clip, feel the device
vibrate (if it’s an Android phone, since Android tablets usually don’t have a
vibrate function because they don’t usually fit in a pocket), and see your WiFi
and mobile radios turn back on. While you could have just let the Pomodoro
Tasker profile execute the PomoWidget task every two minutes, touching the
widget to execute the PomoWidget task allows us to more quickly test the
start and stop actions.
Now let’s start the timer again from the beginning. Touch the widget and take
notice of the starting time. You should have heard the winding clock audio
clip play and seen the WiFi and mobile radios turn off. But something still
isn’t quite right. The widget icon text shows a starting value of 23. If you
practice the Pomodoro Technique, Pomodoro durations are supposed to last
for twenty-five minutes, not twenty-three minutes. We have another bug, and
just like the last bug we fixed, this one is just as easy to spot and fix.
Remember when we set the starting value of %COUNTDOWN equal to 25 in the
PomoStart task? Well, that value didn’t take into account that PomoWidget
runs each time we touch the widget.
Since we have to touch the widget to start the clock, the PomoWidget task
ran and immediately decremented our starting value of 25 to 23, even though
two minutes didn’t pass yet. So, to fix this, simply edit the Variable Set action
in the PomoStart task and change the %COUNTDOWN variable from 25 to 27 so
that it looks like Figure 62, Starting %COUNTDOWN at 27 instead of 25.
With these two bugs eradicated, the PomoStart and PomoWidget tasks should
now look like the ones shown in Figure 63, The final PomoStart task, and
Figure 64, The final PomoWidget task, on page 110, respectively.
Head back to the home screen and repeatedly touch the widget until it decrements
to showing the “DONE!” label. Wait for the ending Ding! audio clip to play and
the radios to turn back on. Then touch the widget again to restart the timer. If
the changes were made correctly, you should see the icon text display a starting
value of 25 and properly decrement by two every two minutes. When the count-
down expires, the icon text will show “DONE!” and you should hear the concluding
Ding! audio effect, feel the vibration, and notice the radios turn back on.
Once you have confirmed that everything is working as expected, you can
take advantage of Android’s widget behaviors and move the Pomodoro widget
to any screen location that works for your layout needs. I prefer a dedicated
uncluttered screen for mine (as shown in Figure 65, The finished Tasker-built
Pomodoro widget) so that I’m not distracted by any other widgets while
working through my Pomodoro sessions.
Congratulations! You just built a very slick and especially handy Pomodoro
widget for your Android device. You also saved yourself a little money in the
process, since you no longer need to purchase one of several Pomodoro widgets
available in the Google Play market.
• The icon text label updates only every two minutes because of Tasker’s
two-minute profile execution limitation. It would be more intuitive to see
the time remaining reflected every minute, just as you would expect a
countdown to behave.
duration, but some individuals would likely appreciate the ability to easily
modify the duration for their own time-boxing practices. While you could
build a dialog box using Tasker’s scenes capability that allowed users to
modify the duration in a graphical way rather than directly editing the
PomoStart task, doing so would require time to learn how to use scenes
as well as to build the dialog and the task structure to support it. Again,
that time would probably be better spent investing in building a native
widget instead.
• Distributing this widget to other Android users who don’t own Tasker
isn’t possible, since the current version of Tasker App Factory does not
support widget generation (although Tasker’s developer has hinted that
this may be possible in a future release). Therefore, only those who have
already bought and are actively using Tasker can use this Pomodoro
widget prototype. Even if you sent these Tasker users the task list, they
would still need to wire up the profile and widget on their own. Considering
we spent a chunk of this chapter on that very subject, asking others to
set up this widget is nowhere near as intuitive as downloading and
installing a widget from the Google Play store.
• Most important is the fact that our Tasker-based Pomodoro widget is not
a real widget in the truest sense of the Android ecosystem. Yes, Tasker’s
own Task and Task Timer widgets are real widgets, but the Tasker Task
widget is simply a wrapper that needs to point to a task written in Tasker
to use. We can’t see our Tasker-based Pomodoro widget on Android’s
widget selection screen (along with a nice graphic indicating the widget
itself), and it can’t be resized like some other native Android widgets allow.
While some of these issues could be addressed in Tasker, the amount of time
and effort to do so would probably be better spent investing in programming
a native Pomodoro widget. But using a programming tool like the AIDE makes
this a possibility. AIDE even has a widget project template you can use to get
started. Those interested in taking Tasker widgets to the next level should
further explore the AIDE. You can use AIDE to code enhancements that would
be difficult if not impossible to do using Tasker alone.
Even with the option to pursue a native development path, Tasker has cer-
tainly served its purpose by helping us envision and bring to life a working
Pomodoro widget. It has also allowed us to create this working widget in
considerably less time than it would take to develop a native Android widget
that does more or less the same thing.
• Make a call to the Talking Clock Tasker project when the countdown ends
so you will know the current time without having to look at your phone
or tablet.
• Write the date and timestamp of the Pomodoros you practice to a text file
using Tasker’s Write File action. Create a Tasker scene to view the data,
send it as an email attachment, or post it to a website.
• If you enjoy listening to music but want to make sure the music stops
during the Pomodoro and starts back up again after the Pomodoro period
is completed, call upon Tasker’s Music Stop and Music Start Media
actions, respectively.
In the next chapter, we will combine the Tasker knowledge we’ve acquired
with the scripting power of Python to create several neat programs that send
and receive messages such as emails, instant messages, and even Twitter
postings in a distraction-free way.
Messaging Projects
We previously learned about how to create tasks with Tasker, scripts with
SL4A, and native applications with AIDE. In this chapter, we are going to
combine tasks and scripts so that we may benefit from the strengths of each.
That is because Tasker has the ability to pass values to and from SL4A scripts.
Both can be used for prototyping and refining apps that we choose to convert
to native programs with a tool like AIDE or keep in perpetual, iterative
development with the tasks and scripts being run.
Let’s begin with a project that leverages the power of an SL4A-hosted Python
script with the easy-to-use task management of Tasker. If you’re like me, this
simple project will also be one of the most used scripts throughout the day.
While this project won’t reduce spam, it will reduce the number of steps
necessary to discover whether you have received such a message. It will also
For example, Python bundles libraries for SQLite (a portable SQL-capable database),
built-in libraries for web protocols, email and instant messaging, and much more.
Lastly, Python is my personal favorite scripting language. Even though languages
like Ruby are beautiful, there is just something about the engineering practicality of
Python that appeals to my nuts-and-bolts tinkering mentality.
We will begin by writing and testing the Python script for checking and
reading email. Once the script is working, we will tie it into the Talking Clock
Tasker profile we created previously. We will also create a Task widget for
easy access to the script. This widget will allow us to execute the script with
a single touch vs. having to open SL4A, scroll through a list of scripts, select
the checkmail.py file, and then the run script sprocket icon.
If you’re able to access the Google Play market on your Android device, you
already have a Gmail account. You can use that account or create a new
account specifically for the purposes of testing and tweaking this script.
Secure IMAP is not normally enabled by default in Gmail. To do so, log into
your Gmail account via a web browser and select the Settings menu option
after clicking the sprocket icon. From there, choose the Forwarding and
POP/IMAP menu. Then select the Enable IMAP button. You can leave the
other options at their default values. Upon doing so, your screen should look
similar to Figure 66, Gmail IMAP-enabled settings, on page 117.
The script we write will work with any secure IMAP standards-based service,
not just Gmail. But for the purposes of our demonstration, Gmail should be
more than adequate. Regardless of which service you use, make sure you can
access it via an IMAP-capable email client first. The standard Mail client on
Android is IMAP-capable, and you can use it to verify that secure IMAP on
your email server of choice is properly configured.
To do so, open the Mail application on your Android device and choose the
Settings menu option. Then select the Add Account label. In the setup screen,
enter your username and password for the IMAP server of choice, and select
the Manual Setup button, followed by the IMAP button on the next screen.
The settings for Gmail secure IMAP are shown in Figure 67, Gmail secure
IMAP client settings, on page 118. While not required for our purposes, you
can also configure the Simple Mail Transport Protocol (SMTP) settings on the
next screen. For example, Gmail uses secure SMTP over port 465 (Gmail can
also use port 587), as shown in Figure 68, Gmail secure SMTP client settings,
on page 118.
Accept the settings, and accept the defaults for the next screen as well. Give
the account a name, such as IMAP Email Test. If you already had messages
in your Gmail inbox, they should show up in the Inbox on your Android device.
Figure 67—Gmail secure IMAP client Figure 68—Gmail secure SMTP client
settings settings
You can also send yourself a message to that Gmail address to see whether
it is received and displayed properly.
Once you have confirmed that the IMAP server and login settings are working,
we can create the Python script that will check for unread messages in the
Inbox. If any are located, the script will have our Android device speak the
subjects of each unread message identified.
Let’s begin by importing several Python libraries (that we will call upon) into
this file. These include the email, imaplib, re (regular expressions), and sys
droid = android.Android()
Next, let’s try connecting to the IMAP server (in our example, we’ll use Gmail)
and navigate to our email Inbox. Notice the use of the word try in the last
sentence. We will use Python’s try-except block to wrap around the server
connection logic. If we fail to connect to the server, we can catch the exception
and have Android tell us that there was a problem connecting to the server.
Messaging/checkmail.py
try:
server = imaplib.IMAP4_SSL('imap.gmail.com')
server.login('MY_GMAIL_USER_NAME', 'MY_GMAIL_PASSWORD')
mailboxes = server.list()
server.select("INBOX")
except:
droid.ttsSpeak("There was a problem connecting to the server.")
sys.exit()
Assuming that the connection to the server was successful and we were able
to locate and focus on the Inbox, we can scan the Inbox for unread messages.
The code we use will incorporate the power of regular expressions to efficiently
identify and parse any unread messages in our Inbox. If you are unfamiliar
with using regular expressions, Mastering Regular Expressions [Fri97] by
Jeffrey E. F. Friedl is a good resource to start reading about their practical
use. Let’s take a look at the code used to retrieve and read email messages.
Messaging/checkmail.py
try:
❶ unread_messages = server.search(None, "UNSEEN")[1][0].split()
❷ unread_count = len(unread_messages)
❸ if unread_count == 1:
droid.ttsSpeak(str(unread_count) + " unread message.")
elif unread_count == 0:
droid.ttsSpeak("No unread messages.")
else:
droid.ttsSpeak(str(unread_count) + "unread messages.")
if isinstance(response, tuple):
message = email.message_from_string(response[1])
❻ for header in ['FROM', 'SUBJECT']:
droid.ttsSpeak(str(header.upper()) + " " + \
str(re.sub(r'<.*>', "", message[header])))
❼ except:
droid.ttsSpeak("There was a problem parsing the messages.")
❶ Using the IMAP UNSEEN command, we search the server for new messages
by using the Python IMAP library’s search function. Then we use split() on
the results to separate each message independently.
❷ Here we capture the length of the unread_messages array so Android can tell
us how many unread messages there are in our Inbox.
❸ Since there can be zero, one, or more unread messages that have been
identified in our Inbox, we have Android tell us via SL4A’s ttsSpeak() function
in a grammatically correct way.
❹ The For loop iterates through our unread_messages array so that we can parse
who the message was from and what is contained within the subject of
the message. While we could also parse out the body of the message, I
have found that this is burdensome (especially when the email is spam).
If I know both the sender and the subject, I can often tell based on the
sender and subject if a message requires my immediate attention.
❺ After speaking the message number and retrieving the message from the
mail server via the Python IMAP fetch() function, we deconstruct the parts
of the message in order to parse it for the message subject and sender.
❻ Since we’re interested only in the email subject and sender, we need to
parse the email message header only. Note the use of the regular expres-
sion function re.sub(r'<.*>', "", message[header])). This searches for and replaces
the email address with a blank string. We do this so we don’t have to listen
to Android say both the sender’s name and email address. If you have
ever looked at the raw source of an email message, you will see that the
person sending the message is listed as Sender Name <sender_email_
[email protected]>. Since we often know people primarily by
their names, not their email addresses, it’s unnecessary and redundant
to have Android speak both their names and their email addresses to us.
Tasker Integration
Let’s create a new stand-alone task for the Check Mail script. This way, we’ll
have the flexibility to reuse the Check Mail routine in other tasks. We’ll also
be able to assign the Check Mail task to a widget, allowing us to check for
However, as we’ll see when we wire up this script to other tasks, we won’t have the
luxury of waiting around until the script finishes. That’s not a bad thing, since we
probably don’t want to listen to more than a minute or so of email senders and sub-
jects. Also, it’s not nice to tie up Android with background processes that don’t
quickly finish up their tasks.
unread messages whenever we want rather than waiting for the fifteen-minute
interval to run.
Create a new task and call it Check Email. This task will consist of a single
action, running the checkmail.py Python script. To add this action to the Check
Email task, select the plus icon in the middle of Tasker’s lower toolbar. Select
the Script action, and then choose Run SL4A Script. Touch the Edit button
and then choose the checkmail.py file. This will be the script that the SL4A action
will execute when the Check Email task runs.
We could stop here, but I prefer to add a conditional statement to this task.
If I know my Android phone is not connected to a network, then there is no
reason to attempt to run the script. Doing so will produce the same result,
with Android speaking, “There was a problem connecting to the server.” To
be even more specific, I chose to have the script run only when WiFi is turned
on.
We can also opt to check whether we have 3G connectivity using the same
technique, but let’s keep it simple for now and just check to see whether the
WiFi radio is on. To do so, check the If box in the SL4A Action Edit task and
test to see whether the %WIFI variable matches the On state. And even though
it’s not necessary in this single step task, I usually enable the Continue Task
After Error checkbox to keep the rest of the task running in case the SL4A
script execution fails. Your configured SL4A task should look like the one
shown in Figure 71, The checkmail.py SL4A action in Tasker, on page 123.
Save your changes by selecting the Action Edit label in the upper-left corner
of the screen. Then confirm that the task has been configured correctly by
selecting the Run icon on the left side of the lower toolbar in the Check Email
Task Edit screen. If it didn’t run, make sure your WiFi radio is turned on.
But as I mentioned earlier, I don’t mind that Tasker puts the brakes on the
running script. If I have a stack of unread emails waiting for me, I am going
to have to respond to some of them anyway. So, while the task doesn’t perform
exactly as intended, I honestly like the fact that Tasker takes command and
stops the script on my behalf. If this isn’t the kind of behavior you appreciate,
you can always consider going native and converting the Check Email task
to a native Android application like we did in Chapter 6, Programming with
AIDE, on page 75.
Another more annoying limitation of the Check Email script, as well as any
SL4A script in general, is that it stops video playback when it executes. If you
happen to be watching a YouTube or other media player video when the script
launches, video playback will halt and require you to manually unpause the
playback to continue. It’s literally a showstopper. Ideally this problem can be
fixed in a future SL4A update.
Before we move on to our next project, let’s make the Check Email function
accessible via a Tasker widget so we can easily run it from the Android home
screen.
screen. Now you can easily run the Check Email task at any time by touching
the Check Email widget envelope icon.
Another even cooler approach you can take with the Check Email task is to
assign it to a Headset Button Controller action. In my case, I have set a four-
button press on my middle headset hardware button to trigger the action to
run the Check Email script.
Enhancements
The aforementioned SL4A limitations notwithstanding, think about the kind
of improvements that could be made to the Check Email project. Here are
some ways to add upon the foundation we built:
There are two reasons why I prefer using the Tasker Task widget above the SL4A
script shortcut. First, Tasker allows you to assign an icon to the task that the widget
will run. SL4A uses the same language-specific icon for the shortcut, making it hard
to quickly identify by sight which shortcut launches which script. And while most
Android third-party launchers such as Nova Launcher allow you to swap out a home-
screen icon with an alternate of your choice, you lose these icon assignments if you
switch to a different launcher or revert to the stock Android home-screen settings.
The second and more important advantage of using Tasker to encapsulate each SL4A
script into a distinct task is so that they can be easily mixed and matched with other
Tasker tasks. For example, if you have already built an SL4A script that parses HTML
tags, you can easily reuse that in a future Tasker task that may require that function-
ality. As you amass a library of Tasker tasks and SL4A scripts, you will appreciate
how much easier it is to manage and organize these functional assets under a single
umbrella.
• Prioritize message reading based on the sender. Have two lists of names,
one for normal and one for high priority, and rearrange the subjects so
that those received from high-priority senders are read first.
• Add the option to read the message body, especially if the message sender
is on a high-priority list. If the subject is important or intriguing, Android
can ask “Would you like me to read the full message?” We will learn how
to interactively respond to scripted conditions using just our voice in the
next project.
project, we’re going to employ both SL4A and Tasker, with Tasker serving as
a container to let us call the SL4A Python script from a widget or headset
button press.
If you took the time to explore the contents of the Python libraries included
in the Python for Android distribution, you may have discovered that it
includes a Twitter library. Unfortunately, that library is outdated because it
uses an old username/password authentication scheme that Twitter has
since replaced with the OAuth authentication standard scheme. OAuth is far
more secure than the old username/password approach, but it is also far
more complex to configure. In fact, we will spend far more time creating and
configuring the OAuth credentials for this project than writing the speech-
translation and tweet-posting Python script.
Visit the Tweepy library page on GitHub and click the Download ZIP button.
Proceed to download and extract the Tweepy library from the project’s GitHub
repository. Since Tweepy (and many other third-party Python libraries) are
designed to be distributed via popular Python package deployment tools such
as easy_install or pip, there are a lot of extra setup files that don’t need to be
copied to the extras Python directory on our Android device. All we really need
is the extracted tweepy directory. Copy that directory to your Android device.
The easiest way to do this is to use Google’s Android File Transfer tool that
was mentioned in Choosing an Audio Clip, on page 99.
For the adventurous and determined Python and Android programmer, there exists
a way to create these natively compiled Python libraries packages for use on Android
that involves the Android Native Development Kit (NDK) and a fair amount of native
Android and C++ development expertise. That said, it’s easier to search for a pure
Python library than to attempt to compile one that relies on native system code. In
the case of our need for a pure Python OAuth-capable Twitter library, such a solution
exists in a project called Tweepy.d
a. http://fabfile.org
b. https://www.dlitz.net/software/pycrypto/
c. http://code.google.com/p/python-for-android/wiki/Modules
d. https://github.com/tweepy/tweepy
With these files in place, you’re ready to import the Tweepy library into your
own projects. But before we actually use the Tweepy library, we need a Twitter
developer account and the appropriate OAuth keys, tokens, and secret values
to authenticate an OAuth session with the Twitter service.
OAuth Credentials
To obtain the four keys to the Twitter application kingdom (the consumer
key, consumer secret, access token, and access secret), visit the Twitter
Developers apps website.1 You can sign in with your existing Twitter account
or create a new account specifically for your Twitter applications. Since this
project is intended for your own personal use rather than an application that
will be distributed in the Play store, feel free to log in with your own Twitter
account login credentials.
Select the “Create a new application” button. Fill out the form with the required
fields (unique name, app description at least ten characters long, and your
website URL), agree to the terms of use, supply the CAPTCHA values, and
select the “Create your Twitter application” button.
1. https://dev.twitter.com/apps
Assuming you entered the information correctly, you should see a page listing
the details of the Twitter application you just created, including the OAuth
settings. By default, new applications are created with a read-only access
level, as shown in the next figure.
We need to change this permission to read-write since our Python script will
be posting tweets to our timeline. To do so, select the Settings tab at the top
of the web page and scroll down to the application type. Change the value
from read-only to read-write, as shown in Figure 77, Setting the app type to
read-write. Then select the “Update this Twitter application’s settings” button
on the bottom of the page to update the access level.
Return to the application details screen by selecting the Details tab at the
top of the page. Confirm that the application access level has been set to read-
write, as shown in Figure 78, OAuth access set to read-write, on page 131.
will have to generate an access token and secret specific to that account. For
our script, we will use the access token and secret that Twitter generated for
us. Take a look at this example, keeping in mind that your token values will
be different from the ones shown in the screenshots.
Now that we have all four values required for OAuth authentication, we can
move on to writing our Tweepy-powered SL4A Python script.
We will also leverage Python for Android’s Android library to capture and
convert our speech to text for both tweet entry and posting confirmation.
Open SL4A, add a new Python script, name it speaktweet.py, and begin by
importing the required modules. In addition to the default Android module
that SL4A already included for us, we will import the sys, tweepy, and time
libraries. The reason for including the time library is because we will need
the script to wait for Android to stop talking before we can ask it to capture
our voice for translation.
Messaging/speaktweet.py
import time, tweepy, sys
import android
droid = android.Android()
response = str(droid.recognizeSpeech().result)
if response == "yes":
break
else:
droid.ttsSpeak("The post has been cancelled.")
sys.exit()
If we respond with a spoken “Yes” that Android recognized, the next step is
to authenticate to our Twitter account using our OAuth credentials. Set the
consumer key, consumer secret, access token, and access token secret values
and pass these to Tweepy’s OAuthHander function.
Messaging/speaktweet.py
consumer_key = "YOUR_CONSUMER_KEY_GOES_HERE"
consumer_secret = "YOUR_CONSUMER_KEY_SECRET_GOES_HERE"
access_token = "YOUR_ACCESS_TOKEN_GOES_HERE"
access_token_secret = "YOUR_ACCESS_TOKEN_SECRET_GOES_HERE"
Google’s speech-to-text service does a nice job in this case, but it doesn’t
make implicit assumptions about punctuation and sentence structure. If you
were to post the converted text as is, your post would be in lowercase and be
missing a period at the end of the sentence. We’ll fix that before the text gets
posted by making the first letter in the tweet string uppercase and adding a
period to the end of the string.
Messaging/speaktweet.py
tweet = tweet[0].upper() + tweet[1:] + '.'
Save the speaktweet.py file, make sure your Android device has a connection to
the Internet, and give the script a try. Select the file from the SL4A Scripts
screen; then select the sprocket icon to run the script. A chime will sound
indicating that Android is recording your voice. Speak a brief test phrase like
“Hello, world.” Android should respond with “I heard ‘Hello, world.’ Is this
what you want to post?” If that’s not the phrase that was spoken back to you,
a “No” response will cancel the post and exit the script. If Android did speak
the phrase correctly, responding with a “Yes” will allow the script to proceed.
Assuming you entered your OAuth values correctly into the script and the
Twitter service is network accessible, the next phrase you should hear spoken
from your Android device is “Hello, world has been posted to your Twitter
timeline.” Confirm this statement by visiting your Twitter page and reviewing
your most recent posts. There you should see a recently added “Hello world.”
entry on your Twitter timeline. Awesome!
Now let’s make the speaktweet.py script more easily accessible to Tasker tasks
and on the Android home screen by wrapping it in a Tasker task and widget,
just like we previously did for the Check Email project.
Tasker Wrapper
Following the same procedure we used for the Check Email Tasker integration,
open Tasker and create a new task called Speak Tweet. The task will host a
single action, running the speaktweet.py SL4A Python script. Add the action by
selecting the plus icon in the lower Task Edit toolbar. Select the Script Action
Category followed by the Run SL4A Script action. Touch the magnifying glass
icon in the Action Edit Name field and choose the speaktweet.py file from the
list. Save the action by selecting the Action Edit label in the upper left of the
screen.
While we’re in the Task Edit screen, let’s also assign an icon for the task so
we’ll be able to easily identify it when we create the Tasker widget for the
script. I chose a free Twitter .png-formatted icon from the IconFinder website.
To set the icon, select the checkerboard icon in the lower-right corner of the
Task Edit toolbar. In my case, the Twitter icon I used was a Local Media file.
Navigate to the file path of the icon and set it by selecting the icon file of
choice.
With the icon configured, we can save the Speak Tweet task by selecting the
Task Edit label in the upper-left corner of the Task Edit screen. Verify that
the script has been correctly configured by running the Speak Tweet task.
Your results should be the same as before when you ran the script within
the SL4A shell.
Now that the Tasker Task has been created, we can either call upon it within
a Tasker widget or assign it to a headset button action using the Headset
Button Controller program. To set up a widget, add a new widget on your
home screen and select the Tasker Task widget from the list. From there,
choose the Speak Tweet task from the Task Selection pop-up list. Verify that
the task you chose is correct and select the Task label in the upper-left corner
of the screen to set the Speak Tweet task widget on your home page. If you
used the free Twitter icon from the IconFinder website, your Speak Tweet
widget may look similar to mine, as shown in Figure 80, The Speak Tweet
widget, on page 135. Now you’ll be able to run the Speak Tweet task directly
from your home screen by selecting the Speak Tweet widget!
If you’re a frequent tweeter, imagine the convenience and ease by which you
can now post tweets to your timeline. Want to notify your followers of what
you’re thinking about while walking to work? Tap your headset button and
speak your mind.
Enhancements
We just built something straight out of a science-fiction story with a couple
of lines of code. To think that we can speak a phrase into our mobile device
and have it broadcast to the planet is just too cool. Here are a few ideas to
make it even better:
• Add the ability to replace or expand text phrases based on your own set
of keywords. So when you speak the word “smiley,” Speak Tweet will
replace the word with a :-) character string. Think of it as TextExpander
for voice input.2
• Add geolocation data to your tweets by enabling the GPS radio and cap-
turing and posting your coordinates. We will learn how to record and
transmit GPS data in our next project.
2. http://smilesoftware.com/TextExpander/index.html
3. https://github.com/tweepy/examples/blob/master/streamwatcher.py
One of the many libraries included in the Python for Android bundle is for
the Extensible Messaging and Presence instant messaging protocol (XMPP).4
Historically referred to as the Jabber protocol, XMPP is used in a number of
instant messaging clients for desktop and mobile devices. Apple Messages
(formerly known as iChat) and Google Hangouts (formerly known as Google
Talk) both use XMPP as a messaging protocol. In this project, we are going
to tap into this capability by creating our own Jabber client that will transmit
our location to a designated recipient as an instant message.
The task will run every ten minutes and embed a link prepopulated with the
device’s latitude and longitude to Google Maps. This will allow the message’s
recipient to click the link and see on a map exactly where the device is located
whenever the script is running. While we’re at it, we’ll also send the current
battery level so the recipient knows how much charge the Android device has
remaining. This is important because the GPS radio has a tendency to
aggressively deplete the battery. If the script stops sending an update, the
last message might show why if the battery level reported was less than 10
percent charge remaining.
We will start with writing the XMPP message transmission script, and that will
use a Jabber-aware instant messaging server to relay the message. Using valid
IM account credentials, we will associate the account used in the Jabber Tracker
with a recipient account that will receive the messages. Then we will create the
Tasker task that will supply the Python script with current latitude and longitude
values captured by the Android’s GPS radio. Finally, we will take our Android for
a test ride to see how well the tracking messages account for its location.
4. http://xmpp.org
XMPP server, the iChat (aka Messages in OS X 10.8) server included with
Apple’s OS X server works. If you prefer Linux, you can install and run the
open source Jabber server, which works perfectly with the client we will create
as well. To learn more about installing a Jabber server and creating user
accounts, check out the excellent ejabberd open source project.5
Let’s keep things simple for now. Since we already used a Gmail account for
the Check Mail project, we are going to use the Google Hangouts login asso-
ciated with the Gmail account you used for it. Assuming you have already
created a Gmail account, launch the Google Hangouts program on your
Android device and log in with the same credentials you use for Gmail. This
will be the instant messaging client that receives the inbound messages.
Now that you have two instant messaging accounts configured, one to send
the instant message and one to receive it, we can use the account credentials
for sending the message in our XMPP script.
5. http://www.ejabberd.im
Messaging/jabbertracker.py
❶ import android
import random
import xmpp
❷ droid = android.Android()
location = droid.getIntent().result[u'extras'][u'%LOC']
battery = droid.getIntent().result[u'extras'][u'%BATT']
date = droid.getIntent().result[u'extras'][u'%DATE']
time = droid.getIntent().result[u'extras'][u'%TIME']
❸ username = '[email protected]'
password = 'secondary_address_password'
recipient = '[email protected]'
❹ uid = xmpp.protocol.JID(username)
client = xmpp.Client(uid.getDomain(), debug=[])
client.connect(server=('talk.google.com',5223))
client.sendInitPresence()
❺
message = xmpp.Message(recipient,
'I am here: http://maps.google.com/maps?q='
+ location + ' at ' + time + ' on ' + date
+ '. Battery level at ' + battery + '%.')
message.setAttr('type', 'chat')
❻ message.setAttr('id', random.randrange(1,10000000))
❼ client.send(message)
client.disconnect()
recipient Google Hangouts account you want to send your instant mes-
sages to.
❹ This portion of the script creates the XMPP user identifier from the user-
name and instructs the XMPP results to be output in verbose debug mode.
That way, if we encounter problems with getting the script to run, we can
examine the SL4A console output to review any errors that were encoun-
tered. We also connect the client to the XMPP server (in this case,
talk.google.com) and the server’s port number (in the case of Google Hangouts,
which uses XMPP secure login, the port number is 5223). Once we’re
connected to the server, we authenticate our XMPP client login credentials
with the server and prepare to transmit our instant message.
❼ With our message formatted with the contents and message ID type and
attributes, we can finally send the message to the recipient. After the
message has been transmitted, we disconnect from the XMPP server.
Remember to update the script with the login credentials of your secondary
Gmail account and the address of your primary (message recipient) address.
Save the changes to a file called jabbertracker.py to the sl4a/scripts directory on
your Android device. But don’t try running the script just yet. If you do, it
will fail because it isn’t receiving the latitude, longitude, date, and battery
values being passed to it by Tasker. Let’s work on fixing that now.
Now that the Jabber Tracker task has captured the current latitude and
longitude location, we can pass those values to our jabbertracker.py script. Add
a new action and select the Script Action Category followed by the Run SL4A
Script item. In the Name field of the Run SL4A Script Action Edit screen, add
jabbertracker.py. In the Pass Variables field, we want to have Tasker pass the
four variables that jabbertracker.py expects to receive. These are %BATT, %LOC,
%TIME, and %DATE. Once these variable names have been entered, the screen
should look like Figure 81, The jabbertracker.py Script Tasker action.
Save this action. With the Jabber Tracker task complete, it should look like
Figure 82, The Complete Jabber Tracker Tasker task.
To verify that you are in an area that can receive GPS signals, turn on your
Android’s GPS radio by toggling it on in the Location page within the Android
Settings program. Then verify that your GPS radio is working correctly by
launching Google Maps. Wait for the GPS signal to be acquired, and then ask
Google Maps to determine your current location. Once confirmed, activate
the Jabber Tracker profile and take your Android along for a walk, bike ride,
or drive. You should see an instant message display on the recipient’s IM
application every ten minutes with the updated location, battery level, date,
and time.
If ten minutes is too long or too short between transmissions, you can vary
the frequency of executing the Jabber Tracker task by changing the Repeat
Every value in the Jabber Tracker profile we created earlier. If you’re using
the Google Hangouts application on an Android device and are logged into it
with the recipient’s account, then your results may look similar to the ones
shown in Figure 84, Jabber Tracker instant messages, on page 142.
When you select the URL, it will open whatever you have set as your default
map display application on your Android device and show the location when
the instant message was transmitted, as shown in Figure 85, Android location
as displayed in the Google Chrome Browser.
Enhancements
The combination of geolocation and messaging is pretty powerful, but there
are improvements we can add to make this project even more interesting.
Here are just a few ideas to get started with:
• Take a photo with the camera and attach it in the instant message along
with the geographic details.
• Create a Tasker profile that activates the Jabber Tracker task when
entering or leaving a particular geographic location.
• Combine the elements of the Jabber Tracker with the segments of the
Speak ’n’ Tweet project to allow you to send instant messages and post
Twitter tweets at the same time.
• Build your own Google Now or Apple Siri replacement using Android’s
speech-to-text and text-to-speech capabilities. Customize your intelligent
assistant with domain-specific knowledge such as querying sites like
Stack Overflow for answers to programming questions.6
• Create a geocache recording app that tracks your explorations and exports
the tagged map locations to a Keyhole Markup Language (KML)–formatted
file for viewing in geographic mapping applications like Google Earth.7
• Write a script that obtains your mobile account details, and set up a
Tasker task to execute once a day to keep track of your data usage and
alert you when you’re close to exceeding your mobile data plan.
• Control home automation projects by voice using Tasker tasks and Python
or Ruby scripts that send messages to electrified relays and servos con-
nected to Arduinos and Raspberry Pis.8
In the next chapter, we are going to take a look at another kind of Android
messaging. Specifically, we are going to see how Tasker not only can react to
Android notifications but also create them with eye-catching details.
6. http://www.stackoverflow.com
7. http://en.wikipedia.org/wiki/Keyhole_Markup_Language
8. http://arduino.cc and http://raspberrypi.org, respectively.
Notification Projects
One of the early innovations that made Android distinct among the various
mobile operating systems was its notification tray. Rather than annoy users
with modal alert boxes popping up whenever system messages are received,
Android neatly organizes these notices into a drop-down list that can be
accessed from the upper-left corner of the home screen with the flick of a
finger. This approach was so well designed that Apple incorporated the idea
into its own iOS mobile operating system.
In this chapter, we will see how we can take Android notifications to a new
level with three projects. The first will allow us to selectively convert any
notification to speech. This will allow us to continue along the earlier theme
of using a headset with Android to keep abreast of all sorts of messaging
inputs. The second project will leverage SL4A to grab a very innovative
weather-forecasting web service to selectively speak or display the forecast
data as a notification. The final project extends Tasker with a plug-in that
will allow us to tailor a variety of notification formats for our personal workflow
needs. Let’s get talking!
This project will essentially replicate entirely in Tasker what programs like
Voice Notify can do. We will also use Tasker’s built-in regular expression
1. https://play.google.com/store/apps/details?id=com.pilot51.voicenotify
Upon doing so, Android will display a warning that you are explicitly granting
Tasker access to any data being entered into the keyboard, screen, and other
means of input. Malicious Android applications hooking into this type of
service could capture passwords, credit card numbers, and login credentials
and send them off to the bad guys without your knowledge. As such, grant
access to such sensitive areas only to those programs that you trust with
absolute certainty.
Scroll down and select the Notification Title from the list. This will place the
Tasker built-in variable name %NTITLE in the Text field. The Action Edit form
should look like Figure 87, The Action Edit notification form.
Figure 87—The Action Edit notification Figure 88—The Notification Event profile
form
Save the changes by selecting the Action Edit Say label in the upper-left corner
of the screen. Now we need to tell Tasker to run the task whenever a notifica-
tion is received in Android’s notification area. To do so, we need to create a
new profile. Select the Profiles tab, followed by the plus icon. Call the new
profile Notification and save the name. When the pop-up menu appears, select
Event. Within the Event category, choose UI, followed by Notification. Save
the changes by selecting the Event Edit Notification label in the upper-left
corner. Doing so will display the Tasks pop-up menu. Choose the Read Noti-
fication task we created earlier. With the Notification Event profile configured,
the Profile screen should look similar to Figure 88, The Notification Event
profile.
That’s all there is to it. Now whenever you receive a text notification in
Android’s notification area, your device should speak the contents of that
message. This comes in handy when using programs such as instant messag-
ing, email, media players, meeting reminders, and news readers that post
message updates to the notifications area. If you’re already wearing a headset,
there’s no need to reach for your phone after hearing a notification chime,
since Android will read to you whatever message was received.
After the novelty wears off, having Android speak every notification event to
you might get annoying and downright aggravating. For instance, whenever
SL4A runs a script, it posts a started and exited notification. So if you use
the Check Mail script, you will hear not only the results of the script but also
that the checkmail.py file has started and exited. That’s a lot of chatter. It would
be nice if we could filter out unwanted messages from our talking notification
task. Thanks to the fact that Tasker supports regular expressions, we can do
so. Let’s find out how in the next section.
Notification Filter
Tasker’s support for regular expressions can be found mainly in its interpre-
tation of conditional statements. In the case of our Read Notification task, we
can add a condition to check for a matching pattern in the %NTITLE notification
title variable and act on it accordingly. Initially, we want to see whether any
part of the %NTITLE string contains a Python file (indicated by the .py extension)
followed by SL4A’s notification that the Python script has either started or
exited.
/.*\.py\s(started|exited)\.
Let’s deconstruct the meaning of this statement. The beginning forward slash
indicates this is a regular expression statement. The dot, asterisk, backslash,
and dot before the py Python file extension tells the parser to accept any
character or set of characters leading up to the extension. However, the string
being tested must contain the .py literal characters exactly in that order. The
\s sequence tells the parser to accept any whitespace character between the
.py and the next word in the string. Next, the (started|exited) sequence tells the
parser to match the word started or exited after the .py extension. Lastly, since
the . (dot) character has a different meaning than just a normal period in
Add the completed regular expression conditional test to the Read Notification
task by editing the Say task and scrolling down until you see the If option.
Check the box for the If statement to activate it. Add %NTITLE in the If state-
ment’s text edit field as the value to check. Select the conditional operator
icon next to it and choose Doesn’t Match Regex. This will replace the operator
icon with the characters !~R, Tasker’s shorthand for not matching a regular
expression. Finally, insert the /*.py\s(started|exited)\. expression to test the %NTITLE
string against and save the action. Once all the parameters have been set,
the Read Notification task assignment should look like the screen shown here:
Now that the notification filter is in place, you’re ready to give Tasker’s regular
expression parser a test-drive. Execute an SL4A-hosted Python script, such
as the checkmail.py script from the Section 8.1, Check Email, on page 115, project.
If the regular expression condition did its job, you should only hear the spoken
results of the checkmail.py script and nothing else. If you hear “checkmail.py
started” or “checkmail.py exited,” review the conditional regular expression
to verify that the syntax is correct.
Enhancements
With the regular expression filter, our spoken notification task has allowed
us to hear important events without having to look down at our phone or
tablet. This includes calendar reminders, instant messaging and SMS posts,
system-level notifications, and more. Here are a couple of ideas on how to
further enhance these notification events:
• As you become more familiar with the variety of notifications being read,
you can decide which ones to filter out and which ones to highlight. Tweak
the regular expression to filter out Ruby (*.rb) or Perl (*.pl) scripts if you
use those languages instead of Python.
• Check for high-priority events based on the notification text. For example,
if you have a critical meeting that you must be reminded about, add a
keyword of your choosing to the subject of the meeting. Then add a task
that compares that subject string for a keyword match. If a match occurs,
use Tasker’s Play Ringtone action to bring additional attention to the
event. You can further enhance the notification by adding the Notify
Vibrate and Notify LED to vibrate and turn on Android’s notification light
if your hardware supports those features.
In the next project, we will call upon a really helpful web service to determine
a precise near-term weather forecast for our immediate vicinity and post the
results to Android’s notification area.
9.2 Forecast.io
One of the most useful iPhone programs I’ve seen is a remarkably accurate
weather forecast utility called Dark Sky.2 Unfortunately, the developers of
that program have not ported it to Android. But what they have done is expose
their forecast engine as a commercial web service. To help entice developers
to incorporate this web service into programs for operating systems other
than iOS, the developers offer up to 1,000 free method calls to their Forecast.io
service.3 This is more than enough for our daily needs. Of course, if you plan
on using this service beyond this 1,000 method call limit, you can consider
additional payment options. But for our single-purpose notification needs,
their free limit should be more than enough for now.
Before you can write a script to call the Forecast.io web service, you need to
sign up for a free developer account.4 Upon doing so, you will receive a
developer key that you will need to append to your calls to the Forecast.io
service. You won’t get very far without a key.
2. http://www.darkskyapp.com
3. http://forecast.io
4. https://developer.forecast.io/register
the Jabber Tracker project. Then we will combine the latitude and longitude
values from the %LOC variable along with the developer key to call to the
forecast API. We will then format the response we received from Forecast.io
and post the results to Android’s notification bar.
While we could work directly with Python’s built-in urllib and json modules
to unpack the response we received from Forecast.io’s servers, there is an
easier way. Developer Ze’ev Gilovitz created an easy-to-use Python wrapper
for Forecast.io that we’ll use for this project. Download the python-forcast.io
module from GitHub,5 and place the uncompressed forecastio.py file (found
inside the forecastio folder) into the /sdcard/com.googlecode.pythonforandroid/extras/python
folder on your Android device.
With these prerequisites now satisfied, let’s take a look at the SL4A Python
script and describe each step in detail.
Notifications/forecast.py
❶ from forecastio import Forecastio
import android
import datetime
droid = android.Android()
❷ MY_API_KEY = "YOUR_FORECASTIO_DEVELOPER_API_KEY_GOES_HERE"
❸ forecast = Forecastio(MY_API_KEY)
location = droid.getIntent().result[u'extras'][u'%LOC']
❺ if response['success'] is True:
Current = forecast.getCurrently()
Hour = forecast.getHourly()
result = str(Current.temperature) +
"F and " + str(Current.summary) + ":" + str(Hour.summary)
# droid.ttsSpeak(result)
❻ droid.setClipboard(result)
else:
droid.setClipboard("There was a problem connecting to the server.")
5. https://github.com/ZeevG/python-forcast.io
❷ This is where you will add your Forecast.io developer API key that was
generated for you when you signed up for the service.
❹ Because the %LOC value combines the latitude and longitude values, we
need to separate these into two distinct values to be passed into the forecast
object we created earlier. Fortunately, these values are separated by a
comma, and Python has a function that makes it easy to assign such
known delimited values to distinct variables. In our case, we know that
the value of %LOC consists first of the latitude value followed by a comma
and then the longitude value. By using the split(',') function, we can separate
the two values and assign them to individual latitude and longitude vari-
ables accordingly.
Also note the call to the droid.ttsSpeak() function that has been commented
out. You can uncomment this if you want to hear the forecast summary
spoken to you right away, or you can use it in place of the notification
altogether. I found it helpful to uncomment while testing and then,
depending on my needs, comment it out if I choose to have the Talking
Notifications project we created earlier running. After all, if the Talking
Notifications is active and the droid.ttsSpeak() line is uncommented, we will
hear the current weather conditions spoken twice.
While you will see how this works when we create the Tasker task for this
project, you may have also correctly surmised that using the clipboard
for this purpose isn’t the most elegant way to handle the passing of vari-
ables from a script’s output to a Tasker variable. While its occurrence is
rare, you may see the forecast notification show the contents of the last
text copy operation if such an action was performed while the script was
running. But it’s what we have to work with until Tasker’s creator can
provide a more elegant format for accepting passed values.
After you have entered the script, save it to a file called localforecast.py by
selecting Android’s back button. Once the file is saved, we can configure
Tasker to call the localforecast.py Python script.
Tasker Integration
Just as we did earlier with the Jabber Tracker project, we will pass the latitude
and longitude values that Tasker captured and supply them to the localforecast.py
Python script for processing. After this script has executed, we will then have
Tasker incorporate the forecast results that were copied to Android’s clipboard
into the notification output.
We will start by creating a new task called Forecast.io. Normally, the first
action in this new task would have been to turn on the GPS radio so we could
capture the current latitude and longitude coordinates. But as we discovered
previously in the Section 8.3, Jabber Tracker, on page 136, project, the auto-
mated GPS On/Off functionality works only on older or rooted Android devices.
Therefore, to have this task execute properly, we will need to make sure to
manually turn on the GPS radio before the Forecast.io task is run.
With that in mind, the first step in our Forecast.io task will be to add a Get
Location action via Tasker’s Misc Action category. You can alter the GPS signal
acquisition timeout value, but the default setting of 100 seconds is typically
enough for most purposes. Leave everything else on this action to the default
values. This includes leaving the Continue Task Immediately and Continue
Task After Error settings both unchecked. After all, we need the current
location information to pass to the localforecast.py script. We also don’t want to
execute the rest of the task if we fail to obtain this vital GPS information.
Next, we have to assign the contents of the Android clipboard that contains
the copy of the script’s results to a Tasker variable. To do so, create a new
Tasker variable called %FORECASTIO and set it equal to the contents of the
clipboard. Tasker’s built-in variable name for the clipboard is %CLIP. Thus,
add a new action to the task and select the Variables action category followed
by the Variable Set action. In the Name field, enter the new %FORECASTIO variable
name. In the To field, enter the built-in %CLIP variable.
But there’s a problem. If we ran this action immediately following the Run
SL4A Script action, we wouldn’t see the correct results being assigned to the
%FORECASTIO variable. That’s because Tasker doesn’t wait for the localforecast.py
to finish executing. Instead, it runs the next action immediately, so whatever
happens to be in the Android clipboard at the time is what gets assigned to
the %FORECASTIO variable. To fix this, we need to tell Tasker to wait a few sec-
onds before running the next action to give enough time for the Forecast.io
server to respond.
In between the Run SL4A Script action and the Variable Set action, add a
new action that will tell Tasker to wait for several seconds. Five seconds seems
to work for me, but your delay needs may vary based on network speeds and
your device’s processing and resource constraints. Select the Wait action from
the Task action category. In the Wait Action Edit screen, set the Seconds
value to 5 or more, depending on your needs. Save the changes.
Recall how we added the colon character to the following line in our Python
script:
result = str(Current.temperature) +
"F and " + str(Current.summary) + ":" + str(Hour.summary)
It’s time to put that delimiting colon character to use. We are going to use
Tasker’s Variable Split action as we did earlier in the Talking Clock task, but
instead of splitting on a period, we’re going to split on the colon character
instead. Add the action via the Variables category followed by the Variable
Split action. In the Name field, add the %FORECASTIO variable. In the Splitter
field, add the colon (:) character. Recall from the Talking Clock task that the
Variable Split action will split the results of the task into consecutively named
variables from the root variable named in the Variable Split Name field. In
our case, this action will generate two new variables, %FORECASTIO1 and
%FORECASTIO2.
Now take these two newly generated variables and assign them to a new
notification notice. Add a Notify action from the Alert action category. In the
Title field, add the %FORECASTIO1 variable. In the Text field, add the %FORECASTIO2
variable. You can also add a custom icon to accompany the notification if you
want, just as I have done in Figure 91, The Action Edit dialog.
Figure 91—The Action Edit dialog Figure 92—The complete Forecast.io task
Save the Notify action. Your Forecast.io task is now complete, and the task
definition should look like the one shown in Figure 92, The complete Forecast.io
task, on page 156.
If your run was successful, you should see a notification appear. Pull the
notification tray down to view both the notification title and the body text. It
should look something like Figure 93, A Forecast.io notification. Depending
on the length of the body text, you may notice that the text doesn’t wrap if it
exceeds the length of the notification pull-down tray. See the example in
Figure 94, The notification text field length exceeded.
Enhancements
I have found in my projects that the most effective use of the notification area
is for semi-persistent messages, such as meeting reminders, instant messages,
and important system state changes. Be cautious with using notifications
too frequently, since you will quickly become desensitized to them and they
lose their effectiveness. With that in mind, here are a couple ideas that can
benefit from employing notifications:
• Revisit earlier projects in the book and retrofit them with an option to use
notifications. For example, adding notifiers to the Tasker Pomodoro widget
could enhance the widget’s end alarm, as well as provide a timestamp of
when the Pomodoro session began and ended.
• For more complex tasks that take a long time to complete, posting a
notification when the task is done will go a long way toward keeping you
informed of the status of automated processes on your device.
In the next project, we’re going to not only correct the text autowrap limitation
in the Forecast.io project but also learn how to incorporate Tasker plug-ins
to further enhance ease-of-use automation control over our devices.
9.3 AutoNotification
One of the best, most forward-thinking features of Tasker is its ability to be
extended via third-party plug-ins. These plug-ins are available in the Google
Play store as dedicated Tasker add-ons, or they can be occasionally incorpo-
rated into Android programs. The Headset Button Controller program, for
In the case of notifications, a really useful plug-in has been created by prolific
Tasker plug-in developer João Dias. His AutoNotification Tasker plug-in gives
you an easy way to access, format, and manipulate Android notifications.7
Let’s try it in Tasker by creating a new task called AutoNotify Test. Then add
a new action via the plus icon in the middle of the lower Tasker toolbar. Select
the Plugin Action Category followed by the AutoNotification action, as shown
in Figure 95, The Notify Action Edit dialog, on page 160.
Select the Edit button in the Configuration Action Edit setting. Doing so will
open AutoNotification’s Share Options dialog, as shown in Figure 96,
AutoNotification share options, on page 160. This is where the genius of this
plug-in shines. Nearly every facet of Android’s notification properties can be
configured in this screen. These include the usual title and text that we’re
7. https://play.google.com/store/apps/details?id=com.joaomgcd.autonotification
8. https://play.google.com/store/search?q=joaomgcd&c=apps
9. https://play.google.com/store/apps/details?id=com.joaomgcd.autoremote
Figure 95—The Notify Action Edit dialog Figure 96—AutoNotification share options
already familiar with in Tasker, as well as more exotic settings such as subtext,
ticker text, notification persistence, picture, vibration patterns, progress bars,
and more.
We will create a test notification to see how some of these custom settings
are rendered. Set the title of the notification to AutoNotification Test. Set the
text to “The AutoNotification plug-in is pretty cool and extends notifications
in many different ways.” Set SubText equal to “I need to learn more about
this plug-in.” Lastly, scroll down and check the Share option. This will allow
the content of the notification to be shared with other Android applications
via a Share option that will appear below the notification text. Save the
changes and run the task. Pull down the notification bar to reveal the gener-
ated notification, which should look similar to the one shown in Figure 97,
AutoNotification example, on page 161.
That looks much better than the standard notification text. It matches the
kind of feature-rich polish that you might see in high-end Android programs.
Using this newfound enhanced ability, we can revisit the notification feature
in the Forecast.io project to properly format overflowing text.
10. http://www.accuweather.com
served up a GIF image of the radar overview with the filename INMREIL_.gif.11
With these parameters set, the AutoNotification Action Edit screen should
look like the one in Figure 98, The revised AutoNotification action for Forecast.io,
on page 161.
Enhancements
We have scratched the surface of what AutoNotification can do and the degree
of customization it has to offer. Because there are so many ideas, layouts,
formats, and other options within this extensive plug-in, spend time exploring
it and tinkering with the settings. As you become more familiar with it, you
will quickly realize new possibilities of how to apply it to your own Android
notification needs. Here are just a few enhancements worth exploring further:
• Include a routine in the Forecast.io script that properly sets the weather
map URL for the appropriate region of the captured GPS coordinates.
• Include an image file fetching routine in the Forecast.io Python script for
the weather radar map. Reference the weather map image in AutoNotifi-
cation’s Picture field and display it along with the rest of the retrieved
forecast text.
• Create a Tasker profile that runs the modified Forecast.io task at set time
intervals or whenever you travel into or out of a defined geographic region.
11. http://sirocco.accuweather.com/nx_mosaic_400x300c/RE/INMREIL_.gif
• Make the Forecast.io notification persistent so that you don’t have to keep
clearing the notification each time you review the notification bar. This
advantage will become even more apparent after you set up the time-based
event profile for the task.
Using this approach, consider other uses for pouring the results of your own
programs, scripts, and tasks into the notification bar, such as the following:
• Enhance the Pomodoro widget with time-stamped start and stop notifica-
tions. When selecting the stop notification, open a Pomodoro log file that
prepopulates the entry with your start and stop time and allows you to
enter additional notes, completed tasks, or other measures of productivity
success completed within that duration.
In the next chapter, we are going to explore projects that incorporate graphic
user interface elements. Doing so will demonstrate how Tasker and SL4A can
be used to create applications that rival native graphic application function-
ality. We will also further extend Tasker with additional plug-ins to help us
realize these project possibilities faster than ever before.
Graphics Projects
Nearly all the projects in this book leading up to this chapter have been
focused on audio-oriented, hands-free operation. While that satisfies a great
deal of useful tasks, especially when you’re constantly on the go, sometimes
a picture truly speaks a thousand words.
In this chapter, we’re going to take a look at a couple of projects that work
best with a user interface. We will learn about the graphic user interface (GUI)
designer that is bundled with Tasker. We’ll create the interface elements and
wire those up with tasks that execute when those onscreen elements are
interacted with.
Let’s start with a simple yet essential visual application that will help us get
used to the GUI tools while at the same time producing a toolbar that can be
built upon with our own expanding library of Tasker tasks and GUI-based
programs.
To get started, we are going to use Tasker’s Scene Designer to build the user
interface and create a layout to place task-centric icons. Using the icons that
were assigned earlier to each task, we can first draw a rectangle that will
serve as the surface where the icons will be placed. Touching the appropriate
icon will launch the associated task or program.
Creating a Scene
Tasker scene elements essentially act as containers for other scene elements
or Tasker actions. For example, a button selection can be assigned to run a
task. In the case of our application launcher, we will use the Perform Task
function and assign various tasks to be run (such as running the Talking
Clock task for one of our app launcher buttons).
When you create a button for our app launcher toolbar, it will initially display
the UI tab for that element. This is where you can set the size, background
color, icon, and position. For example, let’s add the Talking Clock launch
action to our toolbar. Leave the default UI values and select an icon to visually
represent the task. For the Talking Clock, I chose the same icon as the one
I assigned previously to the Talking Clock task. (See Figure 102, Editing a
button element.)
With the look defined, we need to assign an action to perform when the button
is selected. Choose the TAP tab and add a new action by selecting the plus
icon. Since we want to run the Talking Clock task, choose the Task category
followed by the Perform Task action. In the Name field, select the magnifying
glass icon to select the Talking Clock task.
Continue populating the app launcher container with other buttons and
assign them the appropriate tasks. In my case, I chose to populate my app
launcher with the Talking Clock, Check Email, Forecast.io, Jabber Tracker,
and Speak ’n’ Tweet tasks, as shown in Figure 103, The fully populated app
launcher, on page 168.
You will also notice I created a button with an X character to represent a close
toolbar button action. I chose to create my own custom close button so that
I didn’t have to rely on Tasker’s built-in close scene button size.
Next, select the Display As drop-down list box and take a moment to review
the number of display combinations Tasker can apply to scenes. These range
from full windows to dialogs to overlays. Because we want to display our
application launcher as a toolbar that overlays on top of our home screen as
well as grab input focus to capture touch events, choose the Overlay, Blocking
display style.
Moving on to the Horizontal and Vertical position settings, you can choose
wherever you like to place the overlay toolbar on the screen. In my case, I
prefer the top center of the screen. So, that means setting the Horizontal
Position slider to Centre and the Vertical Position slider to Up. Finally, deselect
the Show Exit Button setting, since we previously created our own exit button
on the form. Note that when you do so, Tasker will warn you with a reminder
that you will have to manage the closing action and hiding of the forms
yourself (see Figure 104, Exit button warning for overlay scenes, on page 169).
Assigning a Gesture
Now that you have a working application
launcher task, we need an easy way to invoke
it. While we could create a widget icon to ref-
erence the task and launch our App Launcher
task when we select that widget, it would be Figure 104—Exit button warning
more elegant if we could instantiate it with a for overlay scenes
simple two-finger swipe up on the home
screen. Thanks to Nova Launcher Prime (Nova Launcher Prime, on page 12),
assigning gestures like this to tasks or programs is a simple affair.
Access the Nova Launcher Prime settings screen via the Nova Settings app
icon in the Android applications screen. From there, select the Gestures and
Buttons category. This screen allows you to reassign the gesture behaviors
for several popular home screen gestures, such as pinching in and out and
swiping up or down using one or two fingers, as you can see in Figure 106,
Nova Launcher Prime gesture settings, on page 170.
Select the Swipe up (Two Fingers) item. Nova Launcher will ask you to assign
an action to this gesture. Select the Shortcuts tab and scroll down to the Task
Shortcut. Selecting the Task Shortcut item will display a list of Tasker tasks.
Choose the App Launcher task and save the changes. If everything has been
correctly configured, you should be able to swipe up on the home screen with
two fingers, and the App Launcher should display in the top of the screen,
as shown in Figure 107, The final running Application Launcher, on page 170.
Figure 106—Nova Launcher Prime gesture Figure 107—The final running Application
settings Launcher
Feel free to alter the size of the icons to increase their touch target areas or
make them smaller to fit more icons in a single row. You can also enhance
the application launcher in several useful ways to make it more than just a
toolbar of shortcuts.
Enhancements
Since this is our first foray into the ability to construct graphic user interfaces
for our Tasker (and even SL4A) tasks, the App Launcher project offers a useful
starter template to build upon. It can also be used as a timesaving sandbox
to play with new ideas, since the basic interface and display rules have already
been created. You can extend the application launcher’s functionality with
the following ideas:
• Replace toolbar icons based on the current state. For example, if you have
a toggle to turn on and off the Bluetooth or WiFi radios, display the
appropriate icon to show whether the radio is active.
• Take a minimal clutter approach to the home screen by removing all icons
and widgets and place only your most popular apps on the App Launcher
toolbar. In addition to befuddling others with your strikingly empty screen,
there is also a mild “security through obscurity” benefit because only you
know the correct gesture to access the launch targets for your favorite
Android programs, scripts, and tasks.
• Turn the application launcher into a full-blown web browser that overlays
on top of the home screen whenever you need to quickly refer to a web
page. Extend the background frame to host a TextEdit Tasker component
along with a WebView Tasker component for the web URL entry and
browser window, respectively. Create a button with a globe icon and
instruct Tasker to visit whatever URL is in the TextEdit component when
the globe icon button is selected.
Creating GUIs with Tasker is a breeze once you get used to the basic drawing
and task assignment procedures. We will build upon these skills in the next
project that will check the online status of several Internet-accessible servers
and display their up or down status in a Tasker screen.
Twitch.tv released an Android client to log into and view its services (you can
obtain the free Twitch.tv application from the Play store2), but it’s not as fea-
ture-rich as its iOS counterpart. Besides lacking a built-in live chat client
1. http://twitch.tv
2. https://play.google.com/store/apps/details?id=tv.twitch.android.viewer
and having occasional bugs, Twitch.tv for Android lacks a key feature that
could make it stand out above any feature on other platforms. Specifically,
having a Twitch.tv widget that shows the current broadcast status of favorite
gaming broadcasters would be far more helpful than digging for that informa-
tion in the full application. Fortunately, using Tasker, JavaScript, the Twitch.tv
web API, and a widget-building toolkit called Zoom, we can create our own
Twitch.tv broadcast status widget.
Using JavaScript
Like the web service project in Section 9.2, Forecast.io, on page 151, the web
API for Twitch.tv returns JavaScript Object Notation (JSON)–formatted results.
And while we certainly could use the same Python-scripted SL4A approach
for this project that we used for the Forecast project, we’re going to use
Tasker’s built-in support for JavaScript instead. In addition to the features
available for Android’s browser-based JavaScript engine, Tasker has added
a number of JavaScript functions of its own to provide more extensive inter-
operability with Tasker’s capabilities.3
Tasker offers two options for working with JavaScript code. The first is similar
to SL4A by accessing, parsing, and interpreting an external script file. The
second more interesting option is embedding the script within a Tasker task.
Tasker calls this a JavaScriptlet, and that’s the approach we are going to take
with this project. While there’s no discernible performance improvement using
JavaScriptlets over external .js files, the benefit of packaging tasks into a
single dependency is to make it more manageable, since everything you need
is located in the same place within the same program. More importantly, the
JavaScript interpreter supported by Android includes a full JSON stack,
exactly what we will need to decode the results of the Twitch.tv web API call.
Create a new task in Tasker and name it Twitch Channel. Create a new
variable called %CHANNEL by selecting Variable Set from the Variables Action
3. http://tasker.dinglisch.net/userguide/en/javascript.html
category. In the NAME field, enter the variable name %CHANNEL. In the To field,
enter the username of a Twitch.tv user you enjoy following. For this example,
I am going to set the username to one of my favorite Twitch.tv broadcasters
known as Dan’s Gaming. Dan employs a clever green-screen effect on his
broadcasts that allows viewers to see him speak comments and see his reac-
tions to onscreen events. He is also a passionate gamer who makes clever,
often funny, and insightful comments about his entertaining gaming adven-
tures. His Twitch.tv username is dansgaming.
With the %CHANNEL variable assigned, our next step will be to create an HTTP
Get action from the Net action category. This is where we will call the Twitch.tv
API for user channel broadcast status and pass our %CHANNEL variable into
the URL request. For the Server:Port value, enter the URL https://api.twitch.tv/
kraken/streams/%CHANNEL. If you’re curious about learning what this and other
Twitch.tv web service URLs can provide, visit Twitch.tv’s GitHub page for
more details about the Twitch.tv web API.4
The default global variable that Tasker assigns to and stores the results of
an HTTP Get request is called HTTPD. This is the variable we will access in our
JavaScriptlet to retrieve channel details, such as the title of the stream being
broadcast as well as the number of people currently watching the stream.
Create a JavaScriptlet action from the Script action category. In the Code
field, enter the following JavaScript:
Graphics/twitch.js
❶ var channelDetails = JSON.parse(global('HTTPD'));
var info = "";
try {
❷ info = channelDetails['stream']['channel']['status'];
❸ info += " <b><font color='green'>(";
info += channelDetails['stream']['viewers'];
info += ")</font></b>";
❹ } catch(error) {
info = "<font color='red'>" + global('CHANNEL') + " unavailable.</font>";
}
❺ setGlobal('TWITCHRESULT', info);
4. https://github.com/justintv/Twitch-API
info that will be used to build the HTML-rich text string to be displayed in
our widget’s text area.
❸ We continue to build the info string with HTML formatting (setting the
name of the channel in the color green), since we will place the results of
info into a text area that interprets and renders HTML markup. This will
give our final text string more presentation polish and help us visually
identify different details being displayed in the combined info string. We
also query the value of channelDetails again, this time requesting the number
of people watching the currently broadcasting stream via the
['stream']['viewers'] value. Then we conclude the info string with closing font
and bold tags.
❹ In the event that we encounter an error retrieving the channel status and
stream viewers values, we need to alert the widget with an error. The most
likely reason for this error is that the chosen username is not broadcasting
and therefore does not return any values for those two fields. The other
possibility is a problem connecting to the network to query the Twitch.tv
web API. Either way, the channel status is unavailable and we need to
report it as such. Wrapping the results in a red font color will help it stand
out even more.
The last step we need to do to complete the task is place the contents of the
compiled %TWITCHRESULT global variable into a text field on a custom widget.
But before we can do that, we need to create the custom widget user interface
and name the elements of the user interface. It is via these names that we
will be able to access and assign the user interface elements text properties.
But unlike the application launcher project, we can’t use scenes to create a
widget. That is because a widget is a fixture on the home screen, and widgets
can be embedded in selected areas of individual home-screen pages. Converse-
ly, a Tasker scene is an overlay that stays in a fixed location on the screen.
It doesn’t give you the option of embedding the user interface the way a widget
Zooming Along
Zoom, developed by Crafty Apps EU (the same people who created Tasker),
is a free widget construction utility available from the Google Play store.5 It
can be used to make widgets with buttons, images, text, and other graphics.
Better yet, each of these elements can be accessed and modified by Tasker
actions. So in the case of our Twitch.tv channel widget, we can create a user
interface in Zoom and assign the main text field the contents of the
%TWITCHRESULT variable.
5. https://play.google.com/store/apps/details?id=net.dinglisch.android.zoom
can add various graphic items to the layout by long-touching the screen,
keeping the graphic items within the white margin of the widget. Doing so
will pop up the New Element Type dialog, where you can choose to add but-
tons, images, text elements, and more to the screen. For the Twitch widget,
we will need two text elements, one for the title and one for the body text of
the widget.
Create the first text element by long-pressing the design screen and selecting
Text from the New Element Type dialog. This will display the various properties
that can be set for the text element. Since this will be the element we will use
to show the title of our widget, call the element Broadcast Status. Set the
Text property to Broadcast Status as well. Text elements can be formatted
either as Standard Text or as HTML. HTML is useful when you want to alter
the various characters displayed in the text element with different font styles,
sizes, and colors. But since our title text is going to be consistently the same
color and size, we can keep the format in Standard Text. Then you can set
the Text Colour, Text Size, Text Scale Width, and Center attributes of the text.
You can set these attributes to whatever works for your screen size. For my
Galaxy Nexus, I chose the text size equal to 22 and the text scale width equal
to 0.75. For text color, either enter the HTML color code equivalent or select
the magnifying glass icon to choose the color from a color wheel and slider.
Lastly, the Click Action property represents the action that Zoom should take
when the text element is selected within the working widget. Select the mag-
nifying glass icon to display the Action Type dialog. Scroll down to find and
select the Tasker task. This will display the Task Selection dialog. Find the
Twitch Channel task we created earlier and select it. This way, we can man-
ually run the Twitch Channel task whenever we select the Broadcast Status
title text in the widget. When done, the Broadcast Status property screen
should look similar to Figure 110, Broadcast Text properties, on page 178.
Add a second text element as a container for the %TWITCHRESULT variable result
from running the Twitch Channel task. Set the Element Name and Text
property fields to Status. Because we want to render the HTML code in the
%TWITCHRESULT result, set the Format field to HTML. And like the Broadcast
Status text field, change the Text Colour, Size, and Scale Width to what best
suits your particular device. For my Galaxy Nexus, I set the text color to white
(#FFFFFFFF), size to 12, and scale width to 1.0. As for the Click Action setting,
select the magnifying glass icon and choose Launch App from the Action Type
dialog. Assuming you have already installed the Twitch.tv client for Android,
scroll down until you find and then select the Twitch program. Once set, your
Status property screen should look similar to the one in Figure 111, Status
text properties.
Returning to the design screen, you may need to resize and/or reposition the
widget margin and the Broadcast Status and Status elements to appear cor-
rectly on your display. You can select the magnifying glass icon in the lower
left of the design screen to get a sense of the final display size and visual
representation of the layout. However, I have found that this can be mislead-
ing. Instead, you will more likely have to run the widget, switching back and
forth between the runtime version and the design screen to tweak the size
and position of the various graphic elements. For my Galaxy Nexus, I settled
on the design shown in Figure 112, Twitch Widget Zoom layout.
Now that our Twitch Channel task knows where to send its results to be
displayed on the widget, we can create the widget by long-pressing the home
screen and selecting Widgets. Scroll down to select the Zoom widget. Then
choose the Zoom 2x1 option from the list. A pop-up dialog will ask you to
select the widget template you want to use. Select the Twitch Channel widget
template that we created.
Zoom will then display the Widget Properties dialog as a final design check
before placing the widget on the home screen.
But notice that Zoom appended an extra character to the Name property. I’m
not sure if this is a bug or a feature, but we need to change the Name field
back to the original name by removing whatever character Zoom added to
the field. If we don’t, the results of the Twitch Channel task won’t be able to
find our Twitch Channel/Status field. Once the Name property has been
corrected, select the green check mark in the lower-left corner to accept the
widget properties. Zoom will then display the design surface to allow you to
make any last-minute alterations. Select the green check mark to save the
changes and place the widget on your home screen.
Channel Surfing
With the widget on the home screen, we can see
whether all our work has been wired up correctly.
Select the Broadcast Status text in the widget.
What happened? Tasker displayed a brief message
on the screen stating External Access Denied -
See Prefs/Misc/Allow External Access. That’s
because Tasker needs to be granted explicit per-
mission to access and control other programs on
your Android device, including access to Zoom’s
widget properties. To grant such permission to
Tasker, follow the message’s instructions by
selecting Preferences from Tasker’s main menu.
Then select the MISC tab and locate and check
the Allow External Access checkbox, as shown in
the figure here.
should see the title of Dan’s active Twitch broadcast and the number of people
currently watching his show.
convenient for Tasker to run the Twitch Channel task at regular intervals.
That way, our Twitch widget will work the way most Internet-dependent
widgets work on Android, such that it polls for information changes and
updates automatically. Let’s create a new Tasker profile that automatically
runs the Twitch Channel task at regular intervals.
Now your custom Twitch widget will automatically check every fifteen minutes
to see whether users like Dan are actively broadcasting and update the wid-
get’s status text accordingly. If you want to query a status update immediately,
simply select the Broadcast Status title text on the widget. Monitoring Twitch
user broadcast status has never been so easy!
Enhancements
This window into the Twitch.tv web service provides a solid base to further
expand upon the possibilities of graphically displaying data from the Internet.
It also shows how you can build your own widgets based upon any JSON-
conforming web service. You can even combine Tasker scenes with Zoom
widgets to create some truly versatile Android programs. Here are a few ideas
to keep you Zoom’ing further along:
• Include additional details from the Twitch.tv JSON data, such as displaying
the user icon in the widget.
• Perform a character count on the info variable so you can concatenate the
string with ellipses before it exceeds the fixed text area you have defined
in your widget.
• Revisit the Forecast.io project and swap out SL4A script with a JavaScriptlet
to keep the entire project self-contained within Tasker.
While we have done quite a bit with Tasker and SL4A, we have only scratched
the surface of what this powerful combination has to offer. Play with the
numerous other categories and actions that Tasker exposes. Assemble
workflows that do simple tasks and build upon them. If the need arises for
more advanced text processing or networking, call upon SL4A to manage that
part of the workflow. Depending on the language runtime you configure with
SL4A, there are likely thousands of code samples waiting for you on the Web
to review and incorporate into your programs.
As you become more comfortable with Tasker and SL4A and want to step up
to native Android application development, use the AIDE to codify the work-
flows you have refined over weeks of iterative testing and tweaking. While the
AIDE allows you to quickly change, recompile, and reinstall native Android
programs on the device, nothing beats the speed of Tasker and SL4A for on-
the-fly task editing and implementation.
Visit the book’s online forum to keep the discussion going with me and other
Android personalization and automation enthusiasts. Share your experiences,
Tasker profiles, tasks, and ideas on what would be some awesome Android
workflows. Also take advantage of other communities and documentation on
the Web, listed in Appendix 2, Resources on the Web, on page 201. They helped
me with my own Android projects and will no doubt offer the same level of
service for you. Most of all, have fun. Unlike most other mobile operating
systems, Android encourages tinkering, tweaking, and out-of-the-box explo-
ration. It was this level of freedom and flexibility that drew me to the Android
platform in the first place, and it is bound to only get better with every
successive release.
Appendixes
Even though Android still has a way to go before its presentation layer
matches the rich and creamy user experience on iOS devices, Android benefits
from having an active and enthusiastic can-do coding community that often
offers up inexpensive or even free solutions to programming needs. Like air,
code editors are often taken for granted, but life without them becomes painful
rather quickly. Let’s take a look at some of the editors that many coders
running Android will have a hard time living without.
DroidEdit Pro
If there is one native code editing application that stands out among the rest
in the Android app market, it would have to be DroidEdit Pro.1 Created by
André Restivo, DroidEdit Pro offers the most comprehensive language syntax
highlighting and secure file copying combination code editor at the time of
this writing. The editor supports twenty-five languages, including Assembly,
C, C++, C#, Clojure and Scala to Delphi, Pascal and Perl, PHP, Python, and
Ruby. Files can be opened from and transferred to DroidEdit Pro via SFTP,
Dropbox, and local file system transports. Themes can be customized by
color and font size, and the app scales well between phone and tablet screen
sizes. An example of what DroidEdit Pro looks like running on an Android
phone is shown in the following figure.
1. https://play.google.com/store/apps/details?id=com.aor.droidedit.pro
can also remotely issue commands to the host server when files are trans-
ferred, such as build instructions, workflow direction, and such.
• Cons: Cannot extend the editor with plug-ins. You cannot define your own
behaviors or syntax highlighting based on file extension. It has harsh default
color schemes and an unattractive layout.
Terminal IDE
There is one Android Terminal program I consistently use above all others—Ter-
minal IDE.2 Created by hacker Spartucus Rex, the application’s GPLv2-licensed
source code and helpful, albeit minimal, documentation are freely available
for download from its Google Code project home page.3
One of the neatest things to see Terminal IDE do is run a split-screen tmux
session on an Android tablet, as shown in Figure 119, Terminal IDE running
tmux and Vim, on page 190.
2. https://play.google.com/store/apps/details?id=com.spartacusrex.spartacuside
3. http://code.google.com/p/terminal-ide/
Try doing that locally on a non-jailbroken iPad! By the way, for those unfamil-
iar with the joys of using tmux, check out Brian Hogan’s tmux: Productive
Mouse-Free Development [Hog12]. It’s an easy read that will make you vastly
more productive when operating within a terminal window.
Of course, the point of including Terminal IDE in the category of code editors
is because the system install includes one of my favorite terminal-based code
editors, Vim. (Incidentally, fellow Pragmatic Bookshelf author Drew Neil’s
Practical Vim: Edit Text at the Speed of Thought [Nei12] is an excellent book
to refer to if you’re learning Vim.) Terminal IDE’s version of Vim already has
a number of Vim extensions preconfigured for HTML and Java development.
Autocomplete, tag lookup, navigational key mapping, and more make you
immediately productive without having to start Vim with the usual bare-bones
minimum features. If you are a power Vim user with a favorite .vimrc file, just
copy it to the /data/data/com.spatacusrex.spartacuside/files path that serves as your
home directory, and Vim will behave exactly as you would expect.
You can even build Android .apk files using the Java kit installed by Terminal
IDE, though I still find working within AIDE, even with its less-than-Vim GUI-
based editor, easier thanks to the visual interface it provides. Still, it’s nice
to know that if you don’t want to spend the money for a fully operational AIDE
license, Terminal IDE provides all the tools you need to replicate the compiled
native Android application outcome.
One last killer feature available as a result of Terminal IDE’s system install
is the inclusion of Telnet and SSH daemons that you can run on your Android.
Doing so allows you to SSH into your Android device from another computer
on your network, all without having to even root your phone or tablet to do
so. Wireless file copying and editing on the device is not only possible, it’s
downright cool.
Terminal IDE runs on both Android phones and tablets, but as you can
imagine, the small screen on the phone makes a multipaned terminal session
(pardon the pun) multipained. Unless you have the eyesight of a hawk and
the patience of a saint, editing anything more than a simple script file in
Terminal IDE on a phone is a hassle. But given the much more expansive
screen real estate on a tablet, Terminal IDE is an ideal utility to have at the
ready. The app also includes an onscreen keyboard replacement that can be
swapped out via the Language & input panel within the Android Settings
application. The keyboard adds much-needed terminal keys that are not
included with the standard Android onscreen keyboard, such as the Escape,
function, special character, and arrow keys. Considering all that is bundled
with Terminal IDE, it’s a shining example of the open source ideology on the
Android platform.
• Cons: Some lesser used but useful command-line apps like Subversion
are not included. It has limited Java implementation. When using most
terminal applications, especially Vim and tmux, it requires a Bluetooth
keyboard to be useful and effective.
• Price: Free.
Emacs
For every Vi/Vim fan, there is an Emacs fan. Android coders are no exception,
which is why developer zielmicha ported GNU Emacs to the Android platform.4
The 1.33MB installer available in the Play Store requires an additional 22MB
4. https://play.google.com/store/apps/details?id=com.zielm.emacs
An editor like Emacs that was initially designed for a desktop-centric experi-
ence practically requires a Bluetooth keyboard (though you could also install
Klaus Weidner’s popular Hacker’s Keyboard onscreen keyboard replacement
if necessary5) and large tablet screen to work effectively on Android. Yet for
those with Emacs keystrokes embedded into their muscle memory, Emacs
for Android has arrived. See the following figure.
• Cons: Large install with large memory footprint for just one application
(albeit a powerful one). It really requires an Android tablet and Bluetooth
keyboard to do anything useful with the editor. It might not run on all
Android devices.
• Price: Free.
5. https://play.google.com/store/apps/details?id=org.pocketworkstation.pckeyboard
TextWarrior
While not optimized as a code editor per se, TextWarrior by MyopicMobile is
a text editor that nevertheless has basic syntax support for several languages,
including C, C++, Objective-C, C#, Java, JavaScript, PHP, Python, and Ruby.6
It’s also a native Android application, with its own unique spin on the usual
Android user interface in order to better facilitate the text-editing experience
on a small touchscreen. Perhaps the best feature that TextWarrior has above
less industrial-strength editors is its ability to load large files, as shown in
the following figure.
• Price: Free.
6. https://play.google.com/store/apps/details?id=com.myopicmobile.textwarrior.android
Git
Git is bundled in two products we have already evaluated: AIDE and Terminal
IDE. AIDE’s version of Git is unlocked when the AIDE Premium key is pur-
chased. Terminal IDE is included for free as part of the system installation
option. Both offer full Git pull/merge/commit/push functionality that you
can perform from desktop versions of the source control utility. However,
neither offers a graphical interface showing diffs across commits. For that,
Android developer Roberto Tyler has created a read-only paid Git client called
Agit.7 When this application is combined with either AIDE’s or Terminal IDE’s
version of Git, you will have the full Git desktop experience on your Android
device, as shown in Figure 122, Running Git via Terminal IDE, on page 195.
If you’re already an experienced Git user, the Terminal IDE version works
exactly as you would expect. In addition to managing code, you could use
this onboard version management system for more than just code. Combine
it with Vim’s Git extensions (vim-fugitive is awesome,8 though git.vim will do
the job as well9), and you can version manage just about anything you create.
You could host your own internal Git server to sync and back up all your
work, or you can rely on external providers such as GitHub to manage the
backend for you.
7. https://play.google.com/store/apps/details?id=com.madgag.agit
8. https://github.com/tpope/vim-fugitive
9. https://github.com/motemen/git-vim
If you’re not already familiar with Git and would like to learn how to use it
and quickly understand why it has taken the developer world by storm, check
out Travis Swicegood’s book Pragmatic Guide to Git [Swi10], published by
Pragmatic Bookshelf.
• Price: Free.
Mercurial
Even though Mercurial never really gained
the kind of sizable following that Subversion
and Git achieved, it is an excellent DVCS still
in use. It is especially popular among die-hard
Python coders. Android developer Spencer
Elliot created one of the first of the few Mercu-
rial clients available as a free download from
the Google Play store. Mercury,10 shown in
the figure here, is a well-intentioned Mercurial
client that works from a rudimentary level but
falls short on execution. Given that the
application hasn’t been updated in more than
two years, it may eventually dissipate into the
ether along with Mercurial.
• Price: Free.
10. https://play.google.com/store/apps/details?id=ca.spencerelliott.mercury
Subversion
Even though these days Subversion has taken a backseat to Git, there is still
a mountain of legacy projects and workflow systems built around SVN that
will be in place for a long time to come. And now that the Apache Project
manages the Subversion codebase, its pedigree has been solidified into the
pantheon of great (for its time) software upon which even better software (like
Git) can rest upon its giant shoulders.
While several Subversion clients are available for Android, I prefer the paid
OASVN PRO.11 OASVN delivers the full Subversion experience in a native
Android GUI application. While I do wish Terminal IDE had an SVN installation
option, OASVN is a working alternative. However, OASVN does not have the
most attractive interface, as you can see in the following figure.
11. https://play.google.com/store/apps/details?id=com.valleytg.oasvn.android
To learn more about Subversion, read Mike Mason’s book titled Pragmatic
Version Control Using Subversion [Mas06], also published by Pragmatic
Bookshelf.
• Pros: Stable and actively maintained. The Pro version supports full SVN
updates and commits.
• Price: Free.
PHP developers will appreciate the free LAMP-like stack for Android by DK
Labs called KSWEB.13 Not only will you be able to write your PHP code using
the text editors discussed earlier, but with KSWEB, you will also be able to
locally test and debug your PHP code. You can even have others view the
results of your work by visiting your Android’s IP address and project URL
with a web browser.
Need to move files on and off your Android device via standard FTP? FTP
Server,14 a fork from the original (but now dead) SwiFTP FTP Server, delivers
a basic and intuitive FTP server on Android.
Nic Raboy’s SQLTool Pro Database Editor is an inexpensive app that can be
used to directly connect to and edit MySQL, Oracle PostgreSQL, and SQL
Server databases.15 Query results can be exported to CSV. It works best on
tablets.
12. https://play.google.com/store/apps/details?id=com.agilesoftresource
13. https://play.google.com/store/apps/details?id=ru.kslabs.ksweb
14. https://play.google.com/store/apps/details?id=be.ppareit.swiftp
15. https://play.google.com/store/apps/details?id=com.nraboy.sqltool
If you’re a developer who prefers using the Git and Mercurial-supported Bit-
bucket DVCS service,16 Saibotd’s free and open sourced application called
Bitbeaker offers a clean, Android-friendly interface to this GitHub competitor.17
For those looking to reminisce with ancient DOS-based coding tools and
utilities like Turbo Pascal and VisiCalc,18 check out AnDOSBox,19 one of the
better DOS emulators available on Android.
16. http://www.bitbucket.org
17. https://play.google.com/store/apps/details?id=ca.spencerelliott.mercury
18. http://edn.embarcadero.com/article/20803 and http://www.bricklin.com/history/vcexecutable.htm, respec-
tively.
19. https://play.google.com/store/apps/details?id=com.locnet.dosbox
20. https://play.google.com/store/apps
• Reddit Tasker Forum is a popular location on the Web where both amateur
and experienced Tasker users go to ask questions, post helpful and unique
Tasker applications, and engage with fellow fans of the program.4
1. https://plus.google.com/101304250883271700981/posts
2. http://code.google.com/p/android-scripting/wiki/Tutorials
3. http://www.pocketables.com/2013/03/overview-of-pocketables-tasker-articles.html
4. http://www.reddit.com/r/Tasker
5. http://stackoverflow.com/questions/tagged/sl4a
6. http://tasker.wikidot.com
[CGMW13] Jennifer Campbell, Paul Gries, Jason Montojo, and Greg Wilson. Practical
Programming: An Introduction to Computer Science Using Python 3. The
Pragmatic Bookshelf, Raleigh, NC and Dallas, TX, Second Edition, 2013.
[Mas06] Mike Mason. Pragmatic Version Control Using Subversion. The Pragmatic
Bookshelf, Raleigh, NC and Dallas, TX, 2006.
[Nei12] Drew Neil. Practical Vim: Edit Text at the Speed of Thought. The Pragmatic
Bookshelf, Raleigh, NC and Dallas, TX, 2012.
[Nö09] Staffan Nöteberg. Pomodoro Technique Illustrated: The Easy Way to Do More
in Less Time. The Pragmatic Bookshelf, Raleigh, NC and Dallas, TX, 2009.
[Pin09] Chris Pine. Learn to Program. The Pragmatic Bookshelf, Raleigh, NC and
Dallas, TX, Second Edition, 2009.
[Ril12] Mike Riley. Programming Your Home. The Pragmatic Bookshelf, Raleigh,
NC and Dallas, TX, 2012.
[Swi10] Travis Swicegood. Pragmatic Guide to Git. The Pragmatic Bookshelf, Raleigh,
NC and Dallas, TX, 2010.
[TFH13] David Thomas, Chad Fowler, and Andrew Hunt. Programming Ruby 1.9 &
2.0: The Pragmatic Programmer’s Guide. The Pragmatic Bookshelf, Raleigh,
NC and Dallas, TX, Fourth Edition, 2013.
scheduling SL4A scripts, 69– SMS, see text messages AutoNotification plug-in,
71 software requirements, xiii– 158–163
ScottEVest clothing, 29 xiv AutoRemote plug-in, 159
backing up and restoring
Scripting Layer for Android, software tools, xvi
scripts, 52
see SL4A sound, see media players; Battery Status task us-
scripting, effort involved in, 8 speech-to-text translation; ing, 49–50
security TTS technology buttons for scenes, 166–
installation of pro- sound effects, audio clips for, 168
grammed apps, allow- 99 Check Email widget us-
ing, 79 source version control sys- ing, 121–124
permissions required by tems, 193–198 configuring, 42–43
DashClock widget, 17 gestures, assigning to
Speak ’n’ Tweet widget, 126–
permissions required by tasks, 169–171
135
Tasker tasks, 58, 60, icon sets for, 106
assigning to headset but-
180 installing, 42
ton, 135
permissions required by Jabber Tracker task us-
Python script for, 126–
launchers, 13 ing, 140–141
134
Sense launcher, HTC, 10 task for, 134–135 JavaScript functions for,
Show Scene action, 168 widget for, creating from 173–176
task, 134 online resources for, 201–
SimpleDateFormat class, 83
202
SL4A (Scripting Layer for An- speech-to-text translation,
passing variables to
droid), 18, 63–72, see al- 30–31
scripts, 136
so Python interpreter for split() function, 120 permissions required for
SL4A SQLTool Pro Database Editor, tasks, 58, 60, 180
Check Email widget us- 198 plug-ins for, installing,
ing, 115–116, 118–121 159–160
Stack Overflow SL4A Tagged
downloading and in- polling frequency for, 42
Questions, 201
stalling, 64 profiles for, 43, 50–52,
Jabber Tracker task us- Stick it! floater, 21
55–56, 104–105, 147
ing, 136–139 SVN (Subversion) source ver-
prototyping with, 93–98
languages hosted by, 64, sion control, 193, 197–198
reading clipboard con-
72–73 SVOX text-to-speech synthe- tents, 154–155
media players stopped sis, 27 regular expressions in,
by, 124 148–150
online resources for, 201 T running SL4A scripts
Ruby interpreter for, 66, Talking Calendar application, from, 69, 122, 154–157
69 32 scenes, creating, 165–168
scheduling scripts, 69–71 Talking Clock application Speak ’n’ Tweet widget
shortcuts for, compared assigning to headset but- using, 134–135
to task widgets, 126 ton press event, 86–87 Talking Clock application
Speak ’n’ Tweet widget programming with AIDE, using, 43–53
using, 126–134 77–84 tasks for, creating, 43–
Talking Clock application Python script for, 68–69 46, 53–54, 95, 99–107,
using, 68–69 Ruby script for, 69 146
Tasker variables passed task for, 43–53 testing scripts, 96–97
to, 136 text-to-speech notifica-
Talking SMS and Caller ID
weather notification us- tions using, 145–151
application, 31
ing, 151–154 Train Station Alarm task
TaskBomb application, 70–71
SL4A editor, 66 using, 53–57
Tasker App Factory, 57–60 triggers for tasks, 42, 50–
SL4A Script Launcher, for
TaskBomb, 70 Tasker automation tool, 41– 52, 55–56
43 Twitch.tv widget using,
Smart AudioBook Player appli-
actions for tasks, 44–46 172–183
cation, 37
Application Launcher variables in, 45–49
Smart Tools Flashlight wid- toolbar using, 165–172 weather notification us-
get, 18 apps, creating from ing, 154–157
smartphone cases, 28 tasks, 57–60
widgets, compared to Tweepy library, Python, 127– Voice Notify program, 145
SL4A script shortcuts, 129 voice recognition, 27, 30–31,
126 Twitch.tv web API, 173–174 see also speech-to-text
widgets, creating from translation
Twitch.tv widget, 172–183
tasks, 94, 96, 107,
JavaScript for, 173–176
124, 134, 176–180
JSON data from, 173 W
Zoom utility for, 176–180 Wait action, 155
permissions required by,
Tasker Wiki, 202 180 Wake-On-LAN (WOL) packets,
terminal emulators, see com- task for, 173–176 7
mand line applications testing, 180–182 wallpaper, applying, 23–24
Terminal IDE code editor, update profile for, 182
wearable computing, 27–29
189–191, 194 Zoom utility for widget
creation, 176–180 weather forecasts
text messages Dark Sky program, 151
parsing and reacting to, Twitter
Forecast.io web service,
7 OAuth credentials for,
151
spoken, 31–33 129–131
notification of, based on
Python libraries for, 127–
text-to-speech technology, location, 151–158
129
see TTS technology web microframeworks, 74
Speak ’n’ Tweet widget,
Textastic code editor, 189 126–135 Weidner, Klaus (developer,
TextWarrior code editor, 193 Tyler, Roberto (developer, Ag- Hacker’s Keyboard), 192
3G radio, disabling, 100–101 it), 194 widgets, 9, 14–19, see al-
time.sleep() function, 132 so specific widgets
timer, 18, 93, see also Po- U displaying on home
modoro widget Udell Enterprises (developer, screen, 15
Moon Phase Pro widget), 17 displaying on lock screen,
TouchWiz launcher, Sam-
Unknown sources security 15
sung, 10
setting, 79 installed, viewing, 14
Train Station Alarm task, 53– list of, 17–19
57 UNSEEN command, IMAP,
lock-screen compliant,
120
triggers, for tasks, 42, 50–52, 15–17
55–56 WiFi radio, disabling, 100–
V
try-except block, Python, 119 101
Variable Set action, 46, 102–
TTS (text-to-speech) technolo- 103, 105, 155 Wilmot, Lee (developer,
gy, 27 Tasker), 42
Variable Split action, 47, 156
accessibility settings for, Windows Phone user inter-
146 variables
face, emulating, 22–24
Android Voice Xtreme passing from Tasker to
scripts, 136 WOL (Wake-On-LAN) packets,
application, 32–33
in Tasker, 45–49 7
APIs for, 83
configuring, 29–30 version control systems,
see source version control
X
Headset Button Con-
systems XMPP (Extensible Messaging
troller widget, 33–37
and Presence Protocol)
Talking Calendar applica- Vim code editor, 190, 194
client account for, 136–
tion, 32 VM (virtual machine), 63 137
Talking Clock applica-
voice calls Jabber Tracker task us-
tion, 43–53
handling based on caller ing, 136–143
talking notifications,
ID, 7 Python library for, 136
145–151
making with spoken
Talking SMS and Caller
ID application, 31
commands, 30 Z
spoken notification of, Zoom Text action, 179
Voice Notify program, 145
31–33 Zoom utility, 176–180
ttsSpeak() function, 120, 132
Daniel Sauter
(392 pages) ISBN: 9781937785062. $35
http://pragprog.com/book/dsproc
Chris Strom
(250 pages) ISBN: 9781937785444. $36
http://pragprog.com/book/csjava
Brian P. Hogan
(88 pages) ISBN: 9781934356968. $16.25
http://pragprog.com/book/bhtmux
Drew Neil
(346 pages) ISBN: 9781934356982. $29
http://pragprog.com/book/dnvim
Bruce A. Tate
(330 pages) ISBN: 9781934356593. $34.95
http://pragprog.com/book/btlang
Visit Us Online
This Book’s Home Page
http://pragprog.com/book/mrand
Source code from this book, errata, and other resources. Come give us feedback, too!
Contact Us
Online Orders: http://pragprog.com/catalog
Or Call: +1 800-699-7764