Developing Android On Android Automate Your Device With Scripts and Tasks
Developing Android On Android Automate Your Device With Scripts and Tasks
Mike Riley
Many of the designations used by manufacturers and sellers to distinguish their products
are claimed as trademarks. Where those designations appear in this book, and The Pragmatic
Programmers, LLC was aware of a trademark claim, the designations have been printed in
initial capital letters or in all capitals. The Pragmatic Starter Kit, The Pragmatic Programmer,
Pragmatic Programming, Pragmatic Bookshelf, PragProg and the linking g device are trademarks of The Pragmatic Programmers, LLC.
Every precaution was taken in the preparation of this book. However, the publisher assumes
no responsibility for errors or omissions, or for damages that may result from the use of
information (including program listings) contained herein.
Our Pragmatic courses, workshops, and other products can help you and your team create
better software and have more fun. For more information, as well as the latest Pragmatic
titles, please visit us at http://pragprog.com.
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.
The team that produced this book includes:
Jacquelyn Carter (editor)
Potomac Indexing, LLC (indexer)
Molly McBeath (copyeditor)
David J Kelly (typesetter)
Janet Furlow (producer)
Juliet Benda (rights)
Ellie Callahan (support)
Contents
Acknowledgments
ix
Introduction .
xi
Part I Customize
1.
Getting Started
.
.
.
.
.
1.1 Analyzing Your Mobile Lifestyle
1.2 Mobile Personalization
1.3 Next Steps
3
3
6
8
2.
9
10
14
19
22
25
3.
27
27
29
33
37
41
41
43
53
Part II Explore
4.
Contents
4.4
4.5
vi
57
61
5.
63
63
67
69
71
72
6.
75
76
78
84
86
88
93
93
98
107
111
113
8.
Messaging Projects .
8.1 Check Email
8.2 Speak n Tweet
8.3 Jabber Tracker
8.4 Next Steps
115
115
126
136
143
9.
Notification Projects
.
.
9.1 Talking Notifications
9.2 Forecast.io
9.3 AutoNotification
9.4 Next Steps
145
145
151
158
163
165
165
172
183
Contents
vii
Part IV Appendixes
A1. Android Programming Tools
A1.1 Code Editors
A1.2 Source Version Control
A1.3 Miscellaneous Tools
187
187
193
198
201
Bibliography
203
Index
205
Acknowledgments
This is my second book for Pragmatic Bookshelf, and it has been a pleasure
to once again work with my dedicated and insightful development editor,
Jackie Carter. If you can follow along with the projects without any problem,
you have Jackie to thank. Her editorial skills and professional project management were crucial in keeping the book flowing smoothly and on schedule.
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 books 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 technically 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.
Introduction
In this book, were going on a journey of discovery. Were going to discover
how amazing the Android OS is and how it is transforming the way people
communicate. Were also going to learn how to leave our legacy desktop PCs
behind, even for native Android application development needs.
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.
Introduction
xii
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, hardware support, design aesthetics, and everything but the original design principles 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.
This evolutionary path is also manifested in Android application development
tools. Once clunky and incomplete, the Android SDK and Eclipse plug-ins
are finally capable of stable, team-based, test-driven development. While the
user interface construction toolkit could still use more polish, every other
aspect of the typical Android development and emulation on a desktop PC is
polished and professional.
One of the most exciting aspects of Android programming, testing, and
deployment is that its application development life cycle can now be done
directly on the Android device. This is a big deal. When compared to other
mobile operating systems that require an expensive PC outfitted with a decent
processor and plenty of RAM to run the target emulator, the projects discussed
in this book require only your Android device. When you code and run
applications on the same device, it greatly accelerates the development process,
just as it did during the desktop PC era.
Lets also not forget that, like a desktop computer, Androids 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 Androids success and
dominant market position.
Requirements
xiii
Requirements
This is a book about Android, so it should come as no surprise that a musthave 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 its 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 keyboards 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, Logitechs full-size keyboard 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
Introduction
xiv
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 Im usually bringing
along a backpack during my commutes, the Logitech keyboard adds practically 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, thats ita 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
well go in the next forty years.
xv
to see how they work, there is no overwhelming reason for average users to
consider jailbreaking and rooting their Android devices.
Introduction
xvi
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 Programming Tools, on page 187, for a list of some of my favorites. It should go
without saying that for Android development, Googles http://developer.android.com
website offers the official word on Android application development. This isnt
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. Its 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 books web forum. Should you happen
to spot an error, feel free to mention it on the books website errata page.
Youre also welcome to contact me directly via my mike@mikeriley.com email
address or follow me on Twitter @mriley. I look forward to hearing from you!
With that, were 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
mike@mikeriley.com
November 2013
Part I
Customize
CHAPTER 1
Getting Started
Todays 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
cant be done easily on most other mobile platforms.
In this book were 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 cant find what were 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.
1.1
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 cant 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 youre fighting the interface? Do you find yourself running 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?
Here is a personal example. I am bound by train schedules for my commute
into work. As such, an important feature that I needed from my Android
phone was a way for me to know the current time without having to dig into
my pocket for my phone and fumble with the security unlock code. Just
imagine how cumbersome that would be wearing thick gloves on a subzero
Chicago winter morning. Since I was already wearing earbuds to actively listen
to tech podcasts during my commute, hearing the time spoken was a much
more advantageous solution than the visual clock display.
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 programs 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 Ill take you through in this book mirrors my own iterations that best
suited my mobile lifestyle needs.
If youre 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 Im 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 days 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 youre not sure,
Androids Data Usage and Running apps (shown in the following figures)
are accessible via the Android Settings application.
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 youre 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 (Im 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 wouldnt have any new podcasts
to listen to on the way to work. By the way, I no longer do this manual
process since Ive scripted the entire procedure to kick off thirty minutes
before I wake up. Ive also created automated tasks to grab the latest news
and weather to read to me after the clock alarm awakens me. Well explore
how to write your own scripts and tasks later in the book.
What dream applications or widgets do you wish you had but havent
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, lets take a closer look at some of the more
interesting personal automation ideas we could build upon.
1.2
Mobile Personalization
After you have considered what opportunities for automation exist, start
brainstorming how to make those ideas come to life. You will discover that
the more you think about the improvements that customized automation can
bring, the faster new program ideas will flow. Some of the automated scripts
and applications that I have created on my Android devices include the following examples:
1.
https://play.google.com/store/apps/details?id=com.snoggdoggler.android.applications.doggcatcher.v1_0
Mobile Personalization
Parse SMS alerts for keywords and react accordingly. If youre 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.
Transmit Wake-On-LAN (WOL) packets in the middle of the night to
computers on your LAN or home network. This will wake them up, run
backups on their users home directories, and send a backup report of
success or failure to your Android device. Then let the computers go back
to sleep.
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.
Divert inbound phone calls based on caller ID information to voicemail
or automatically forward the call to a secondary number (such as a Google
Voice number that offers message transcription services) depending on
time of day or level of personal importance.
Once you have a list of needs in mind, you can start to define what is necessary to bring these ideas to fruition. If someone hasnt 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.
If youre already a programmer familiar with object-oriented languages like
Java, picking up the necessary skills to develop Android applications is
straightforward. Several books are available, and hundreds of text-based and
video tutorials exist online to help get you started. As you will see later in this
book, you can build applications that rival natively constructed commercial
Android programs using these tools built for programmers and nonprogrammers alike.
1.3
Next Steps
Keep the ideas presented in this chapter in mind as you read this book. As
you learn how to make Android perform automated tasks, consider how these
novel tasks can be expanded to make your life easier. The more you practice
creativity, the more creative you will become.
In the next chapter, we will dive into our first layer of customization by modifying 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.
CHAPTER 2
2.1
10
Launchers
The stock home screen that comes on the standard Google Nexus devices
offers a crisp, clean interface. But if you dont 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 homescreen 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 displayed when moving between screens.
Some device manufacturers have created their own custom launchers to
enhance and differentiate their Android devices. These include Samsungs
TouchWiz1 and HTCs Sense.2 This degree of customization demonstrates a
major advantage that Android has over competing mobile operating systems.
This also helps to accelerate user experience innovations because Android
offers a platform where experimentation is not only possible but embraced.
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 launchers 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 Lets take
a brief look at each of these to see what they have to offer and what differentiates one from the other.
1.
2.
3.
4.
5.
6.
http://en.wikipedia.org/wiki/TouchWiz
http://en.wikipedia.org/wiki/HTC_Sense
https://play.google.com/store/apps/details?id=org.adwfreak.launcher
https://play.google.com/store/apps/details?id=com.anddoes.launcher.pro
https://play.google.com/store/apps/details?id=com.gau.go.launcherex
https://play.google.com/store/apps/details?id=com.teslacoilsw.launcher.prime
Launchers
11
ADWLauncher EX
One of the most downloaded launchers on the market, ADWLauncher EXs
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
Larger installation footprint compared to other third-party launchers
Not yet optimized for Android 4.2 and newer
Can be problematic with some widgets
GO Launcher EX
With more than a million installations since its release into the Play marketplace, GO Launcher EX is by far the most popular on Google Play and has
12
Launchers
13
Pros
Cons
Comparatively expensive
14
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 generations youth,
this design trend has been reborn in the mobile generation. Even more levels
of customization can be realized using widgets. Lets 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 isnt 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, well 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 programs 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.
Widgets
15
Lock-Screen Widgets
While the original intent of the lock screen
Figure 5Android 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 security 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 offset this kind of inconvenience, Google introduced a widget enhancement
feature for the lock screen called, you guessed it, lock-screen widgets. The
lock-screen widgets that are bundled in the standard Android 4.2 OS allow
you to view items such as your calendar, email, and contacts and to even
launch the Camera app without having to unlock the screen.
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 screencompliant will be displayed, as shown in Figure 7, A selection of lock-screen widgets, on page 16.
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.
Figure 7A selection of
lock-screen widgets
7.
https://play.google.com/store/apps/details?id=net.nurik.roman.dashclock
Widgets
17
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 DashClocks
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
Romans 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 dont 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 prefer.
Calendar
This is the widget component of Googles
calendar application that is included with
Android running Google applications. Its
helpful for taking a quick glance at
upcoming scheduled events.
Moon Phase Pro
Being a child of the 1960s and having
early memories of watching a blurry television screen showing Neil Armstrong step
8.
http://code.google.com/p/dashclock/wiki/API
18
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.
Headset Button Controller
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 applications 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.
Smart Tools Flashlight
The Smart Tools bundle is a helpful collection of fifteen measurement
tools ranging from virtual rulers and protractors to metal detectors and
magnifiers. The program includes a helpful Flashlight widget that turns
on and off the rear camera light (if you have one on your phone or tablet)
with the touch of the Flashlight widget icon. This has helped me more
than a couple times while searching for keyholes and safe walkways and
for paper-based reading at night. Since I always have my Android phone
with me, I always have a flashlight with me as well thanks to this useful
widget.
Python Interpreter
This widget provides a shortcut to the Python interpreter hosted within
the Scripting Layer for Android (SL4A) program. Besides Python, SL4A
can host a number of other different languages within the Android environment. We will learn much more about the SL4A in Chapter 5, Scripting
with SL4A, on page 63.
Pomodoro Clock Widget
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
Floaters
19
Pomodoro timers and walk you through the process of building this widget
in Chapter 7, Tasker Pomodoro Widget, on page 93.
Check Mail Widget
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 applications that can be displayed on the screen
within a movable window. I call these programs floaters. Floaters behave just like a
window in a modern desktop computing OS.
Most can be resized, minimized, and maximized, and some even support multiple
instances, allowing multiple windows on the
screen at the same time. See the figure here.
The advantages of using floaters are not as
great as you might expect. They really dont
work all that well on an Android phone with
a small display. Screen real estate is already
at a premium, and managing windows on top
of an already limited overall display field can
get annoying after a while. Theres also the
dissonance problem of merging an old GUI
desktop application metaphor onto a modern
mobile operating system. It breaks up the
flow, and you may find yourself spending more Figure 9Several floaters in action
20
11.
12.
13.
14.
https://play.google.com/store/apps/details?id=com.myboyfriendisageek.aircalc
https://play.google.com/store/apps/details?id=com.myboyfriendisageek.airterm
http://kevinboone.net/kbox.html
http://www.busybox.net
Floaters
21
DICE Player15
DICE Player is a free (donations encouraged), full-featured media player
for Android. In addition to supporting a variety of playback formats, DICE
Player includes the ability to convert the normal full-screen playback
mode into a floating pop-up player. The windowed player can be resized
like any other floater-style application. One nifty aspect I like about the
DICE Player is its ability to speed up playback without altering the pitch.
This allows me to watch screencasts twice as fast without changing the
pitch of the audio. A typical scenario on my tablet is to have DICE play
back a screencast in double time while I have Terminal IDE or AirTerm
open, interacting with a server running the configuration being presented
in the screencast. Its the ultimate post-PC learning experience.
Overskreen16
Overskreen is another MBFG application that brings the floater technique
to the standard Android web browser. Because of this, Overskreen is a
no-frills browser that cant compete with the likes of Chrome or Firefox.
Still, its floater properties come in handy when searching the Web or
referring to a website while writing a document. It sure beats the alternative tap-and-swipe dance common when switching between running
Android programs.
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 MultiView. This essentially allows for multiple windows to play back different
video content at the same time. Its an awesome technology demo, but I
honestly havent 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 Androids home screen look and behave the way we want, lets
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
22
phone operating system, and another will re-create the look and feel of a
popular desktop operating system.
2.4
23
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 were going to use Nova Launcher Primes ability to import icons from
other launcher application themes. In this case, we will borrow some Windows
Phonelike 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.
24
Tinker with the layout until you achieve the look and feel youre comfortable
with. When youre done, it may look similar to the one shown in Figure 12,
A Windows Phone theme.
In the next example, we will use a free theme
originally designed for ADW.Launcher and
pull in its icon assets to reflect a popular
desktop OS.
Next Steps
25
2.5
Next Steps
This chapter showed just how easy it is to customize the Android graphical
user experience to your liking. Whether its embracing the mobile lifestyle to
the fullest or harkening back to a legacy PC user experience, Android gives
you the freedom to choose how you want the interface to look and behave.
This is a significant advantage, especially compared to platforms like those
powered by Apple iOS. Android allows you to express yourself without jailbreaking or rooting your device, something that might be required to do to
achieve the same effect on other mobile platforms.
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 download. If youre using TeslaCoils 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, dont 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 dont find one you like, you can create your own
26
CHAPTER 3
3.1
Wearable Computing
With all the recent interest in wearable computing, people often forget that
an Android phone already is a wearable computer. I have been using my
Android phone as a wearable computing device for years. Let me explain.
The term wearable computer has a broad definition applying to everything
from a wristwatch to a powered laptop strapped to a backpack. In terms of
my Android phone, I wear it in a case attached to my belt loop. However,
rather than reaching for the phone every time I hear its message chime, I
have written scripts and applications that inform me of those messages
1.
https://play.google.com/store/apps/details?id=com.svox.classic
28
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 Googles
much hyped and considerably more expensive Glass project, my Android
wearable configuration doesnt 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 eventually 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 headphone jack and tightly wrapping it with electrical tape to no avail.
As for Bluetooth headsets, I find that the sound quality still hasnt quite
matched the frequency ranges offered by wired headsets. There is also the
hassle of having to recharge the Bluetooth headsets battery before use. And
29
it can be a pain when that charge dies midway through the day without
having the means to recharge it until youre 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
After spending a wad of cash on replacing expensive earphones and wireless
headsets, I have reverted to cheap, throwaway headsets. They sound fine and
offer nearly the same level of durability as more expensive alternatives yet at
a far lower replacement cost.
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, lets next turn
our focus to the software involved in voice recognition and spoken text interaction.
3.2
2.
http://www.scottevest.com
30
Android speak at the playback speed you chose. And now that we know
Android can talk, lets explore how we can talk back to Android.
Running Android 4.2 and newer, you can hold
down the earphone button for about a second,
and the Google Now service will pop up,3 ready
to submit your query to Google for processing.
In addition to submitting who, when, what,
where, why, and how questions to Googles
search engine, you can also command certain
aspects of the phone by voicing key phrases,
such as the following:
Call <contact> will locate the contact
name most closely matching your spoken
entry and place a phone call to that contact.
Listen to <track> will play back the
requested music track using the default
music player.
Go to <URL> will open a web browser
and display the requested URL.
Open app <app name> will launch the
application, assuming it is installed on
your device.
3.
http://www.google.com/landing/now/
31
theyre far from perfect. Try any of these phrases on a noisy bus or outside
on a windy day, and youre not likely to see the results you expected.
Second, Google Now requires an Internet connection to work. Thats right. If
you want to play a song that is already stored on your device, ask to open an
application, or play a music track, Google Now has to submit your converted
speech-to-text request to its web service for these things to happen.
You would think thats 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 doesnt 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 Googles 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 youre 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 Im on the go, whether walking crowded city streets to work or riding
my recumbent along winding bike trails, I really dont 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.
Fortunately, several hardworking Android developers have created applications
that address these needs. Lets take a closer look at some of my favorites.
4.
https://play.google.com/store/apps/details?id=mahmed.net.spokencallername
32
Talking Calendar
One of my biggest frustrations with program
audio cues is that they provide only part of
the story. Lets 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 whats going on.
Talking Calendar eliminates this hassle by
actually speaking the event to you instead.5
Talking Calendar, shown in Figure 16, Configuring Talking Calendar, hooks into not only
your Google Calendar but your Exchange and
CalDAV-formatted calendars as well, which
is perfect for those who prefer to keep worklife and home-life events separate. The application is also smart enough to pause whatever
audio might be playing long enough to read
(via text-to-speech) the calendar event.
https://play.google.com/store/apps/details?id=com.pwnwithyourphone.talkingcalendar
https://play.google.com/store/apps/details?id=com.bulletproof.voicerec.avx
Button Control
33
3.3
Button Control
As I write this chapter, Google is ramping up hype for its impending release
of Google Glass, its self-proclaimed game-changing wearable-computing
device. Having been professionally around the computing block for nearly
thirty years, I have seen the rise and fall of a variety of devices. I worked with
Windows CE-powered wearable-computing head-mounted displays over a
decade ago, and while it was a thrill developing applications on bleeding-edge
technology at the time, those types of displays ultimately lost their luster for
me. Why?
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 its fun to dream of
the future, I need an unobtrusive working solution today without all the
annoyances Ive already encountered.
34
As odd as it sounds, I look forward to hearing the synthetic female voice used
as the default TTS engine in Android 4.2. Its nice to know that shes 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. Well 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
Button Control
35
36
Next Steps
37
3.4
Next Steps
In this chapter, we learned about wearable computing and how it relates to
todays Android devices. To that effect, we learned how to give Android
smartphones and tablets a voice by enabling Androids text-to-speech capability. We also discovered how several commercially available Android programs
take advantage of this built-in feature. And we configured a useful utility that
8.
9.
https://play.google.com/store/apps/details?id=ak.alizandro.smartaudiobookplayer
https://play.google.com/store/apps/details?id=com.snoggdoggler.android.applications.doggcatcher.v1_0
38
a.
http://www.instructables.com/id/Galaxy-Nexus-and-others-headset-remote-with-medi/
Part II
Explore
CHAPTER 4
4.1
Introducing Tasker
Available for purchase from the Google Play marketplace for only a couple of
dollars, Tasker centers around the ability to define tasks that execute a set
of predefined actions to take when certain conditions are met. This can be
something as simple as putting the phone into Airplane mode at bedtime or
as complex as having your phone autonomously send your family a text
message containing a Google Map link of your location when you reach a
destination.
1.
http://tasker.dinglisch.net
42
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 prizewinning programming competitions called Android Developer Challenges, and
Tasker was one of the finalists in that competition.
Tasker is somewhat equivalent to Apples Automator on OS X, and while
Taskers user interface is in need of a makeover, the power imparted by the
sophisticated scripts it can execute is unparalleled. Tasker exposes nearly
every part of the addressable hardware and event-oriented portions of the
operating system, making it relatively easy for people to configure their phones
to certain triggers and respond to certain events.
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
Talking Clock
43
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 Googles 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, Taskers screens will look somewhat different
on those older platforms. The good news is that the placement of dialog elements and Taskers core functionality are mostly the same between platforms.
After you have become acquainted with the
bevy of settings and polling frequencies that
can be customized, exit the Preferences screen
and switch to the Profiles tab. Profiles are
used to organize various tasks under a single
set to execute when a predefined condition is
met. If you created a task to turn on the GPS
radio and another task to sound an alarm
when a desired location condition is met, you
can combine these two tasks under a single
profile. There are two major advantages to
doing this. First, you can easily activate and
deactivate a set of tasks to be run as needed.
Second, you can reuse individually defined
tasks in other profiles without having to reinvent and version control the same task routine
over and over.
In the next section, we will put these ideas of
tasks and profiles to use for our first Tasker
program, a talking clock.
4.2
Talking Clock
44
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.
Figure 23Creating a
new task
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 Taskers 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
Talking Clock
45
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 Taskers 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 Googles own text-to-speech engine. Select
your engine of choice.
2.
https://play.google.com/store/apps/details?id=com.svox.classic
46
The Stream field allows you to assign the audio output to Androids 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 its 4:22 p.m. when you run the task, your phone will say
Sixteen point two two. Well, thats literally the time but not the common
North American way of speaking it. Lets fix that.
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 Taskers 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
Talking Clock
47
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 builtin %TIME variable that we called upon earlier. Save the step by selecting the
Action Edit label in the left of Taskers 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 Taskers 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, lets give them the appropriate names of %current_hour and %current_minute,
respectively. Just as before, choose Taskers Variable Set action from the
Action Category -> Variable dialog. Once completed, you should have four
action steps created in your Say Time task.
Now lets determine whether its a.m. or p.m. If the 24-hour value is less than
twelve, its a.m. If its greater than eleven, its 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 didnt just create the %am_pm and use If and Else
actions from Taskers Task Action options. SimpleIm lazy. My initial construction accomplished the same objective in fewer steps.
48
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 oclock 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.
We will fix the midnight problem by setting the %current_hour variable to 12 if
the %current_hour is equal to 0. Next, subtract 12 from the %current_hour if the
%current_hour is greater than 12. These two actions properly set the hour reading
value for a 12-hour clock.
Only a few more steps to go before our talking clock task is complete.
Lets now take care of the oh sound by setting a new variable that well call
%say_oh to the oh string. We will also need to add a step that will check to
Talking Clock
49
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 lets 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.
We can assemble and pass the complete string
to Tasker to pass to its Say function.
%current_hour %say_oh %current_minute %am_pm
Battery Status
50
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 tasks play button. Yep, all that information in just a single
line of instruction. Thats 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 %current_minute matched 00). So, lets 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.
Theres 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 were
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, thats 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.
Talking Clock
51
52
When youre 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 doesnt, make sure
your volume is turned up and your device isnt on mute. Also, double-check
your profile to make sure it is enabled. Whew! Were done!
53
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.
4.3
54
Choose the Notify Sound action and for this example name the action Train
Stop Ahead. Tasker will display this name in Androids 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.
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.
55
56
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 Taskers 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.
Thats all there is to it. But before placing your
waking trust entirely in the alert, test the task
to account for train speed, music playback
volume, GPS signal, and battery consumption
rate.
57
all the way up to 7, the highest level. Assuming your sound file is normalized,
that sound level should definitely get your attention.
Now lets 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 isnt 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!
4.4
3.
https://play.google.com/store/apps/details?id=net.dinglisch.android.appfactory
58
Choose to export the task As App. This will display the Tasker App Factory
disclaimer, essentially reminding you that Taskers developer isnt 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 users 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.
If your task requires additional permissions, such as accessing the Internet,
reading contact information, writing to the file system, and the like, you will
need to indicate those by selecting the Advanced Configuration check box.
Once you have completed the required configuration details, select the Configure 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
59
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 applications 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).
Figure 40Blocked
Installation dialog
60
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 its 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 wont bother
installing.
If your app really needs a cornucopia of permissions, you should spell out the reason for
each permission in your programs description
on the Google Play market. Even then, a lot
of potential users may balk at the installation
permissions.
4.
http://tasker.dinglisch.net/userguide/en/appcreation.html
Next Steps
4.5
61
Next Steps
So, thats Tasker, the wonderfully versatile Android script and application
generator that can automate a number of highly customized tasks. And you
can do so without knowing anything about the Android SDK or the Java
programming language. Its an amazing utility, one I use every day and one
that I know you will too.
Now that you have enough of an introduction to Tasker to get started
exploring on your own, here are a few ideas to jump-start your creativity:
Run an automated daily backup of your music and photos to Dropbox or
other cloud storage service while you sleep.
Wake up to a spoken reading of your favorite RSS feeds.
Download podcasts using your favorite podcast-catching client while
youre sleeping and have the latest batch queued up and ready to go when
you head out the door.
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 phones 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 dont have to take your eyes off the road.
If you manage physical servers or virtual machines, ping or send HTTP
requests to your machines and sound an alert if the servers fail to return
a response.
Develop your own Apple Siri or Google Now client using Taskers Get Voice
action combined with the HTTP Get action calling various web service
APIs.
62
5.
6.
http://tasker.wikidot.com/plug-ins-and-3rd-party
http://tasker.wikidot.com/profile-index
CHAPTER 5
5.1
64
differentiate Android from competitors like iOS because the early iPhone didnt
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
65) by opening the .apk file from your file system or via the Download complete
label in the notification tray.
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
66
pyCrypto
PyBluez
pyEphem
pySerial
Twisted
Zope
We wont need any of these additional packages for our scripting needs, but
its pretty cool to know you can write a full-blown enterprise-class asynchronous 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_picture.py script. If these scripts execute successfully, were ready to do the same
for the Ruby interpreter.
67
Joe asks:
a.
https://play.google.com/store/apps/details?id=org.ruboto.irb
5.2
68
understand that you should be able to follow along. Lets begin by considering
the Python port of the Talking Clock application.
SL4A/talkingclock.py
import android
import time
droid = android.Android()
droid.ttsSpeak(time.strftime("The time is %_I:%M %p."))
69
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 youre 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.
Thats 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 youre new to programming and want to learn the fundamentals using Ruby
syntax, Chris Pines book Learn to Program [Pin09] uses the language to teach
programming essentials. If you want to delve deeper into understanding Ruby,
check out Pragmatic Bookshelfs Programming Ruby 1.9 & 2.0: The Pragmatic
Programmers Guide [TFH13] by Dave Thomas, Chad Fowler, and Andy Hunt,
which is affectionately known as the Pick-Axe book.
5.3
4.
http://tasker.wikidot.com/sl4a
70
If you dont 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 loops
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-supported) service application that works like Tasker in that it executes applications at given times and/or time intervals.
5.
6.
https://play.google.com/store/apps/details?id=org.androidideas.taskbomb
https://play.google.com/store/apps/details?id=org.androidideas.scriptlauncher
71
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
TaskBombs main screen and select the Schedule icon (its 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 isnt the best task-scheduling software available, but its certainly
cheap and, more importantly, it works.
These simple scripting examples, combined with either Tasker or TaskBomb
as the script execution triggers, only scratch the surface of what can be done.
Entire legacy libraries and routines from the desktop or server can be quickly
ported to run on the Android platform, making SL4A a very powerful tool on
your Android utility belt.
5.4
72
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 todays 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. Heres a look at some of the more
interesting additions:
Clojure REPL7
Haskell8
Lisp9
Scala10 (requires root access)
Scheme REPL11
5.5
Next Steps
In this chapter, we learned about how to install and use the Scripting Layer
for Android to write programs using powerful scripting languages like Python
and Ruby. We also learned about scheduling those scripts to execute at predefined intervals using Tasker and TaskBomb. And we also discovered that
there are a host of other programming language runtimes available for the
Android platform, giving us considerable flexibility in choosing a language
for building our Android scripts and applications.
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 application counterpart.
7.
8.
9.
10.
11.
https://play.google.com/store/apps/details?id=com.sattvik.clojure_repl
https://play.google.com/store/apps/details?id=nl.bneijt.tryhaskell
https://play.google.com/store/apps/details?id=info.gomi.android.lisp.islisp
https://play.google.com/store/apps/details?id=com.mobilemagic.scalainstaller
https://play.google.com/store/apps/details?id=com.folone.replscheme
Next Steps
73
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:
Poll your favorite websites or Facebook or Twitter pages to verify site
availability, as well as to display any new content that has been posted
since you last ran the script.
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
74
weather in your area based on your GPS coordinates, pull down the
results, and read them to you via Androids text-to-speech engine.
Perform a package delivery status lookup based on shipment date and
tracking number. If the courier indicates that the package has been
delivered, send an email or SMS containing the tracking details to the
sender or other designated party.
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 SDKbased application. Whats more, we will compile this
application entirely on an actual Android hardware device. Thats 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 tabletno other computer required.
CHAPTER 6
76
6.1
Getting Started
This chapter assumes you have at least some exposure to the Java language,
which is the language that Android uses as its preferred development syntax.
Our Talking Clock application is simple enough to understand even without
much exposure to the language, but the more experience you have with Java,
the better.
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 Bookshelfs Hello, Android: Introducing
Googles 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.
http://developer.android.com/sdk
https://play.google.com/store/apps/details?id=com.aide.ui
Getting Started
77
(albeit limited) version and a premium key (costing up to $10, though sometimes on sale for much less) that unlocks all the limitations imposed by the
free edition. While the limitations of the free edition wont 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. Well then remove some of the template-generated code we dont 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.
78
worth checking out on your own, but we will stick with the Hello World template. 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 AIDEs code editor. The contents
of this file are pretty basic.
package com.mikeriley.talkingclock
import
import
import
import
android.app.*;
android.os.*;
android.view.*;
android.widget.*;
We will use this file as a starting point for our native Talking Clock project.
6.2
79
This will compile the app and attempt to install it on your phone. However,
as we saw with the Tasker App Creator, Androids security model prevents
apps from arbitrarily installing on your device unless you give explicit permission 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.
80
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 application. 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 thats done, select Open. This will display the main form of the
program, as shown in the following figure.
Most Android applications have some kind of
user interface. After all, a significant reason
for the platforms success is its tactile nature
of screen interface interactivity. But in our
case, were building a program that doesnt
need a user interface. It just has to speak the
current time and battery charge. Lets make
that change.
Return to the AIDE editor and select the MainActivity.java file from AIDEs file browser. This
81
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 books 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
import
import
import
import
import
import
import
import
import
import
android.app.Activity;
android.content.BroadcastReceiver;
android.os.Bundle;
android.content.Context;
android.content.Intent;
android.content.IntentFilter;
android.speech.tts.TextToSpeech;
android.speech.tts.TextToSpeech.OnInitListener;
android.os.CountDownTimer;
java.text.SimpleDateFormat;
java.util.Date;
82
@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);
}
}
}
}
}
83
Here we will import all the libraries we need to call upon for the programs
functions. Note that we dont 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.
We need to create an object called mBatInfoReceiver to collect the current
battery level and assign that level to a batlevel string.
Here we can determine whether the battery is currently charging. This is
the bonus feature I mentioned earlier in the chapter. This is a function
that we cant normally do with a standard Tasker task. We call the BatteryManager Intent (basically an exposed routine of an application that can be
called upon by another Android program) to determine whether the battery
is either charging or fully charged. Either way, the battery must be connected to a power source and we pass that fact to a boolean variable called
isCharging. If isCharging is true, we tack onto the batlevel string the phrase is
charging. Why would you want the device to say this when you can tell
by looking if its plugged into a power source? Consider a hands-free
driving scenario, where not only knowing the time but also whether the
phone was currently charging would be a nice-to-know benefit. If youre
a person who is always on the go, knowing not only the time but also the
battery status and charging state will help you maximize your power
management. It will also remind you that your phone is tethered to a
power cable and that you should disconnect it before leaving the vehicle.
During the applications creation event, we register the mBatInfoReceiver so
we can use it to collect the results of calling the ACTION_BATTERY_CHANGED
intent. We also register the TTS engine so we can call upon it after we
obtain the battery and time results.
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
84
the hour oclock, and 0109 minute oh designations. Then we concatenate 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 dont put this
delay into the program, we wont hear anything spoken because the program 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 dont use the onTick() event in this program, but we have to declare it
to satisfy the OnInitListener implementation we used in the MainActivity class.
Finally, we clean up the program by unregistering the Intent receiver we
created to capture the battery level, shut down the TTS engine to free up
that resource, and then call Androids finish() function to tell the OS were
done with all the variables we created. Androids garbage collector will
automatically take care of the rest.
With the code out of the way, were ready to give the project a spin!
6.3
85
3.
4.
http://xamarin.com/monoforandroid
www.adobe.com/go/HRTDI
86
6.4
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/plugout 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.
Lets do one more assignment with Headset Button Controller and run our
Talking Clock application when we plug our headphones into our phone.
Select the programs 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 youre done, your screen should look similar to Figure
51, Assigning Talking Clock to a headset plug insertion action, on page 87.
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
dont, check your settings and headset volume. Once you have confirmed that
the headset plug-in action works, test the triple-click assignment by tripleclicking 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.
6.5
88
Next Steps
In this chapter we went from zero to sixty and learned a lot about programming
native Android applications. However, unlike other introductory books on
Android programming, we wrote our native application entirely using the
Android device. While the future of computing is clearly moving away from a
desktop-centric world to a mobile-centric one, Android is the first among its
competitors to declare its ecosystem entirely post PCenabled. I suspect that
Apple and Microsoft will eventually reach a milestone when developers will
be able to create applications entirely on those platforms (no OS X or Windows
desktop software required), but as of today, Android is in the top slot.
Now that you can build truly native Android applications without relying on an
external computer or Android emulator, the speed and agility gained will allow
you to rapidly prototype and build app ideas. And because these apps are built
using Androids native SDK, there are no additional runtimes or dependencies
required. This allows you to very quickly post your finished app online or distribute
it via the Google Play store. Using the AIDE also allows you to access APIs that
are not supported in third-party automation tools like Tasker. In addition to the
enhanced Talking Clock application we built, consider building other short yet
highly relevant utilities for your personal workflow, such as the following:
5.
6.
7.
8.
9.
http://developer.android.com/guide/topics/providers/calendar-provider.html
http://developer.android.com/guide/topics/connectivity/wifip2p.html
http://developer.android.com/guide/google/gcm/index.html
https://developers.google.com/appengine/
https://developers.google.com/translate/
Next Steps
89
10. http://developer.android.com/guide/topics/location/index.html
11. http://developer.android.com/guide/topics/connectivity/nfc/nfc.html
Part III
Build
CHAPTER 7
7.1
1.
http://www.pomodorotechnique.com
94
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.
If we were to modify the native Java version, we would have to go through a
compile, deploy, and testing phase compared to Taskers two-step edit-andrun process. We would also need to lug around a keyboard if we were to make
a large modification to the codebase in the native client. By keeping the design
iterations in Tasker for as long as possible, not only do we make the development process considerably easier on ourselves, but we also benefit from the
fact that when we ultimately sit down and code the native version, we will
know exactly what it needs to do.
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.
At its core, the widget we will construct is essentially a countdown timer. We will start the
countdown at twenty-five minutes by clicking the
widgets icon. It will display the minutes remaining before the timer expires. When the timer
reaches zero, the Android device running the
widget will play a sound effect and vibrate for a
brief period.
Tasker includes two types of widgets that can be
hooked up to Tasker-scripted tasks. The first
offers more of a shortcut to launching a task, with
the main feature being the ability to control the
widgets icon, related scene, and text label. The
other Tasker widget offers a simple countdown
timer interface that can be used to trigger a task
script when the timer reaches zero. Refer to these
choices in Figure 52, Two types of Tasker widgets.
95
By the sound of it, using Taskers Task Timer widget satisfies most of our
applications 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 lets 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 available on your phone. You can play back this sound via Androids six sound
channels by selecting the list of Stream options. Lets 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 lets 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 milliseconds. This brief burst may be too short to notice, so lets triple this vibration
time to 600 milliseconds.
Finally, lets 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 Taskers
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.
96
Countdown Widget
Return to Androids 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.
97
Pomodoro dialog. If the ring tone isnt loud enough or the vibration isnt 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.
If your Android device has an aggressive power management setting, it might
shut off the phone and prevent the timer from counting down and triggering
the Pomodoro task. This is because Android by default doesnt want widgets
to continue running while the device is in standby mode. You can imagine
the impact a dozen widgets polling the network or constantly refreshing
graphics to the screen would have on battery charge and system performance.
Unless an application or widget specifically requires wake lock in its manifest
of permissions, the Android OS will take over and do its job. In the case of
Tasker, it was already granted this permission (not to mention a bunch of
other system-wide permissions) when you installed it.
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 Properties 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.
98
7.2
99
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,
were going to have to ditch it in favor of Taskers other widget, simply called
the Task widget.
Once you have obtained an MP3 audio start clip of your choice (for the purposes of this exercise, Ill 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 Androids 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/
100
the timer countdown expires, and Ill assume you chose the pomostop.mp3 file
available from this books 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.
Leave the Stream option set to Media. This
will play back the MP3 audio clip on the same
channel and volume as the standard Android
audio application (such as the music player)
volume. After accepting the settings by
choosing the Action Edit label in the upperleft corner of the dialog, verify that Tasker can
correctly locate and play back the file and that
the volume is loud enough to hear. Do this by
selecting the Play icon in the lower-right corner of the PomoStart task edit dialog. If you
dont hear anything, check your Androids
volume and mute settings. If successful, you
should hear a few windings of a kitchen clock
timer.
101
Joe asks:
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 displayed, 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 Androids web browser and attempt to load your favorite
website. The browser should complain that the web page you were trying to
reach is unavailable.
102
103
104
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 Taskers 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 theres a problem. Tasker wont accept our value of running
the task every one minute, as you can see in the following figure.
It looks like Tasker wont let us set up a profile
to run a task at intervals less than two minutes apart. The reason for this limitation is
to prevent the task(s) assigned to a profile
from running so frequently as to have a
notable degrading impact on your Androids
battery charge. So, in order for us to create
this Pomodoro timed interval context, we have
no choice but to set the lowest value of the
context interval to execute every two minutes.
Now that we have created the timed interval
context, we need to assign it to a task. From
the Task Selection dialog that popped up after
we accepted the context interval, select the
PomoWidget task we created earlier. We now
have a Pomodoro context to trigger our
PomoWidget task every two minutes. Cool!
With a context ready to run our PomoWidget
countdown task every two minutes, we can
Figure 57Tasker will not execute create the widget, right? Not yet. We still have
profiles at an interval less than two a few more important issues to address. The
minutes apart.
first is figuring out how to set the Pomodoro
timed interval context to start running when
we touch the Pomodoro widget icon. We also have to find a way to stop running
105
the context when the countdown reaches zero. Lastly, it would be good user
feedback to see the current value of %COUNTDOWN on the widgets 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.
2. We have a running clock, but now we have
to instruct the profile to turn off when
%COUNTDOWN reaches zero. To do so, open
the PomoWidget task for editing and add a
Profile Status action called Pomodoro, just
like we did for the PomoStart task. But this
time, instead of setting the value to On, we
are going to set Profile Status to Off under
one condition, that being If %COUNTDOWN < 1.
When set correctly, the Profile Status dialog
for this task should look like the figure here.
Time Remaining
With the starting and stopping actions of the
Pomodoro profile interval timer in place, were
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 58Turning 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 weve
been tracking all this time. But instead of setting it to a number, we are
106
Finishing Touches
Lets do one more thing and place the proverbial cherry on top of our creation. Lets 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 Taskers 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
With all the pieces now in place, your
PomoStart and PomoWidget tasks should look
like the screens in Figure 59, The PomoStart
task, and Figure 60, The PomoWidget task, on page 107, respectively, and the
Pomodoro profile should look like the one shown in Figure 61, The final
Pomodoro profile, on page 107.
Figure 59The PomoStart task
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
107
The big moment has finally arrived. Its time to try our Tasker-constructed
Pomodoro widget and see whether it performs the way we expect it to perform.
7.3
108
choose Taskers Task widget. Upon doing so, Taskers 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 dont have any additional 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 dont 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 thats what is supposed to happen. But thats 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?
Remember when we set up the task to decrement %COUNTDOWN by 1 each time
the PomoWidget task was run? Well, that would have worked had Tasker
allowed us to run the task once a minute. But Tasker restricts us to running
tasks at a minimum of every two minutes. That means we need to change
the Variable Set action in the PomoWidget task from %COUNTDOWN - 1 to
%COUNTDOWN - 2. Go ahead and do that now and save the changes to the
PomoWidget task. Note that you dont have to remove the widget you just
created. Instead, just edit the PomoWidget task in Tasker, and the widget we
created earlier will simply adopt the new instructions. Thats pretty cool.
Return to the home screen where you placed the PomoWidget task-assigned
widget. Now repeatedly touch the widget to more quickly advance the countdown. 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 its an Android phone, since Android tablets usually dont have a
vibrate function because they dont 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 lets 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
109
isnt 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 didnt 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 didnt 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.
110
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 countdown 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 Androids 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
111
7.4
112
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 Taskers 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 dont own Tasker
isnt possible, since the current version of Tasker App Factory does not
support widget generation (although Taskers 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, Taskers
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 cant see our Tasker-based Pomodoro widget on Androids
widget selection screen (along with a nice graphic indicating the widget
itself), and it cant 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 certainly 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.
Next Steps
7.5
113
Next Steps
We spent quite a bit of time going over the construction of the Pomodoro
widget using Tasker. But now that you know the specifics of doing so, building
a Tasker widget from scratch should be a much faster and more intuitive
experience. This chapter also introduced a number of new ideas and Tasker
features, including audio playback and event intervals, that you will be able
to apply to other Tasker-related projects. You can also use the Pomodoro
widget as a foundation to build other interval-driven task triggers. We can
also enhance the widget with features that will deliver more than just a
Pomodoro stop clock. Here are a couple of ideas to get you started:
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 Taskers 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 Taskers Music Stop and Music Start Media
actions, respectively.
Reward yourself with the successful completion of a Pomodoro by pulling
from a random list of encouragement text and have Taskers Say action
speak phrases like Way to go! and Nice job. Take this concept further
by pulling down famous quotes or a fortune cookie text generator from a
free web service API like the one found on http://iheartquotes.com/api, convert
the text to speech, and be surprised by what your Android device will say
to you.
In the next chapter, we will combine the Tasker knowledge weve 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.
CHAPTER 8
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.
Lets begin with a project that leverages the power of an SL4A-hosted Python
script with the easy-to-use task management of Tasker. If youre like me, this
simple project will also be one of the most used scripts throughout the day.
8.1
Check Email
This project will run a Python script to check for new email messages and
speak their subject lines should any messages arrive in the inbox. We will
use Tasker to schedule the script to run at regular intervals as well as make
it easy to run from the home screen via a Tasker widget.
Because I prefer to listen to music or podcasts while commuting, working
out, or cleaning the house, Im often wearing headphones. Any chance I can
hear information without having to dig out my phone to do so is a great timesaver. Email is one of the primary reasons I carry around a smartphone, even
more so than voice calls or SMS messages. Yet I find it maddening to hear
an email notification chime sound during my commute, dig the phone out of
my case, unlock the screen, and bring up the email client only to discover
that a spam message arrived.
While this project wont reduce spam, it will reduce the number of steps
necessary to discover whether you have received such a message. It will also
116
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.
Check Email
117
118
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.
Check Email
119
Next, lets try connecting to the IMAP server (in our example, well use Gmail)
and navigate to our email Inbox. Notice the use of the word try in the last
sentence. We will use Pythons 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. Lets 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.")
for item in unread_messages:
droid.ttsSpeak("Message " + str(item) + ".")
typ, message_content = server.fetch(str(item), '(RFC822)')
for response in message_content:
120
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 librarys 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 SL4As 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 were interested only in the email subject and sender, we need to
parse the email message header only. Note the use of the regular expression function re.sub(r'<.*>', "", message[header])). This searches for and replaces
the email address with a blank string. We do this so we dont have to listen
to Android say both the senders 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_
address@theirdomain.com>. Since we often know people primarily by
their names, not their email addresses, its unnecessary and redundant
to have Android speak both their names and their email addresses to us.
If we have a problem retrieving or parsing the messages, we can gracefully
exit the routine by having Android inform us that there was a problem
doing so.
Check Email
121
Tasker Integration
Lets create a new stand-alone task for the Check Mail script. This way, well
have the flexibility to reuse the Check Mail routine in other tasks. Well also
be able to assign the Check Mail task to a widget, allowing us to check for
122
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 Taskers 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 lets 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
its 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 didnt run, make sure your WiFi radio is turned on.
Check Email
123
124
But as I mentioned earlier, I dont 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 doesnt perform
exactly as intended, I honestly like the fact that Tasker takes command and
stops the script on my behalf. If this isnt 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. Its literally a showstopper. Ideally this problem can be
fixed in a future SL4A update.
Before we move on to our next project, lets make the Check Email function
accessible via a Tasker widget so we can easily run it from the Android home
screen.
Check Email
125
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 fourbutton press on my middle headset hardware button to trigger the action to
run the Check Email script.
To do so, launch the Headset Button Controller program and select Quadruple Click
from the Easy tab. Select Tasker task from
the pop-up list, as shown in the figure here.
For longer clicks like these, I recommend
leaving the Play beep sound checkbox
enabled as an audio cue that you have indeed
tapped the headset hardware button four
times. Then, just as we did with the task
widget assignment, select the Check Email
task from the Tasker task list. Once the
assignment is configured, test it by plugging
in your headset and tapping the headset
hardware button four times. Doing so should
launch the Check Email Tasker task that will
in turn run the checkemail.py Python SL4A
script. Now whenever youre on the go and
want to check for new email without having
to reach for your smartphone, just tap your
headset button four times to hear any new Figure 74Assigning a Tasker task
to a quadruple-click
email messages you may have received. Now
thats pretty cool!
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:
Minimize the reading of spam by filtering out message readings from
unknown sources. Create an array of approved senders and iterate through
it to verify that the sender is in the list before retrieving and reading the
subject.
126
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.
Add the ability to respond to a message via speech-to-text conversion. We
will learn how to do this in the next project.
8.2
Speak n Tweet
Keeping with the theme of hands-free audio-delivered data exchange, our
next project will post a speech-to-text translation to your Twitter timeline.
Select a widget or a few clicks of your headset hardware button, wait for the
audio cue to speak, say what you want posted, and Android will convert your
speech to text, confirm what you said, post it to your Twitter account, and
read back to you what was just posted. Just as we did with the Check Email
Speak n Tweet
127
project, were 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 speechtranslation and tweet-posting Python script.
128
Speak n Tweet
129
a.
b.
c.
d.
http://fabfile.org
https://www.dlitz.net/software/pycrypto/
http://code.google.com/p/python-for-android/wiki/Modules
https://github.com/tweepy/tweepy
With these files in place, youre 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
130
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.
Speak n Tweet
131
132
We will also leverage Python for Androids 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()
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 Tweepys OAuthHander function.
Speak n Tweet
133
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"
auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_token_secret)
Googles speech-to-text service does a nice job in this case, but it doesnt
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. Well 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 thats 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
134
your most recent posts. There you should see a recently added Hello world.
entry on your Twitter timeline. Awesome!
Now lets 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 were in the Task Edit screen, lets also assign an icon for the task so
well 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 youll be able to run the Speak Tweet task directly
from your home screen by selecting the Speak Tweet widget!
Speak n Tweet
135
Finally, lets assign the click of our headset button to the Speak Tweet task. Choose how many
clicks you prefer. For the sake of this project,
lets assign it to four clicks of the headset button.
Open the Headset Button Controller program
and select the Quadruple click from the Easy
tab. Choose the Tasker task followed by the
Speak Tweet task from the Task Selection list.
Save the changes, plug in your headset, and click Figure 80The Speak Tweet
widget
the headset hardware button four times in a row.
You should hear the familiar Android speech
recognition indicator chime in your ears. Say what you want to tweet,
acknowledge, and verify that the tweet was posted on your Twitter timeline.
If youre 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
youre 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
Use the StreamListener function of the Tweepy library to listen to tweets
being posted in real time by the accounts you follow on Twitter. Refer to
the streamwatcher.py example from the Tweepy project GitHub page.3
Enhance the script using Tweepys friends_timeline() function by asking
Android to Read new tweets.
Add geolocation data to your tweets by enabling the GPS radio and capturing and posting your coordinates. We will learn how to record and
transmit GPS data in our next project.
2.
3.
http://smilesoftware.com/TextExpander/index.html
https://github.com/tweepy/examples/blob/master/streamwatcher.py
8.3
136
Jabber Tracker
The projects we have worked on so far in this chapter have used SL4A for
code logic and Tasker as the shell and script execution scheduler. But Tasker
can also be used to pass values it has acquired to SL4A scripts via Taskers
Pass Variables field in its Run SL4A Script action. Using the familiar Tasker
variable name syntax of %NAME_OF_VARIABLE, we can supply our Python
scripts with values for additional processing. Were going to take advantage
of this feature in this project.
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
devices latitude and longitude to Google Maps. This will allow the messages
recipient to click the link and see on a map exactly where the device is located
whenever the script is running. While were at it, well 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 Androids GPS radio. Finally, we will take our Android for
a test ride to see how well the tracking messages account for its location.
http://xmpp.org
Jabber Tracker
137
XMPP server, the iChat (aka Messages in OS X 10.8) server included with
Apples 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
Lets 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 associated 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.
Next, visit http://gmail.google.com and create another Gmail account to be exclusively used for sending instant messages to your primary Gmail account.
After you create the second account, you need to allow your primary account
to receive messages from this second account. To do so, add the Gmail.com
address of the second account to your Google Hangouts chat list via the Add
Contact menu item. Once the invitation has been sent, log into Gmail with
the second account and accept the Google Hangouts invitation. And with
that, your primary and secondary Gmail accounts are associated with each
other. You should now be able to verify this association by sending a test
instant message from your secondary Gmail account to your primary account.
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
138
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 = 'secondary_address@gmail.com'
password = 'secondary_address_password'
recipient = 'primary_address@gmail.com'
uid = xmpp.protocol.JID(username)
client = xmpp.Client(uid.getDomain(), debug=[])
client.connect(server=('talk.google.com',5223))
auth = client.auth(uid.getNode(), password, 'JabberTracker')
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()
Jabber Tracker
139
recipient Google Hangouts account you want to send your instant messages to.
This portion of the script creates the XMPP user identifier from the username 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 encountered. We also connect the client to the XMPP server (in this case,
talk.google.com) and the servers port number (in the case of Google Hangouts,
which uses XMPP secure login, the port number is 5223). Once were
connected to the server, we authenticate our XMPP client login credentials
with the server and prepare to transmit our instant message.
This is where we format our XMPP message by incorporating the location
and battery values passed from Tasker to the script. The location data
will be incorporated into a Google Maps URL. Assuming that the message
recipient is using a modern XMPP-compatible client like Apple iChat/
Messages, Google Hangouts, Pidgin, or similar applications, this URL will
display the location pin icon in the browser.
When we imported the random Python library earlier to create a random
number, we did so because Google has incorporated a feature that filters
out repeating messages. This way, if someone is accidentally sending the
same instant message twice, the recipient sees the message only once.
However, since we want to see all messages regardless of whether the
message contents are identical, we need to bypass this message-filtering
feature by assigning a unique message ID to each instant message we
transmit. We do this by generating a random integer between one and
ten million, assuring that the likelihood of generating the same message
ID in the same user session is very low.
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 dont try running the script just yet. If you do, it
will fail because it isnt receiving the latitude, longitude, date, and battery
values being passed to it by Tasker. Lets work on fixing that now.
140
Save this action. With the Jabber Tracker task complete, it should look like
Figure 82, The Complete Jabber Tracker Tasker task.
Jabber Tracker
141
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.
Transmit an instant message whenever the state of the device changes,
such as whenever the Bluetooth or WiFi radios turn on or off, when the
Next Steps
143
8.4
Next Steps
In this chapter, we created several practical tasks and scripts that provided
us with multiple types of hands-free messaging. We also saw how easy it was
to integrate the power of scripting languages like Python with the ease of
integrating these scripts with Tasker profiles and tasks. In addition to building
upon these projects by enhancing their interactivity or extending their features,
we can create new Tasker and SL4A combinations. Consider the following
ideas:
Build your own Google Now or Apple Siri replacement using Androids
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 youre 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 connected 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.
7.
8.
http://www.stackoverflow.com
http://en.wikipedia.org/wiki/Keyhole_Markup_Language
http://arduino.cc and http://raspberrypi.org, respectively.
CHAPTER 9
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. Lets get talking!
9.1
Talking Notifications
Applications that intercept notifications and convert these messages to speech
are nothing new. A popular open source program called Voice Notify is a
personal favorite.1 But if you already use Tasker, these types of applications
are unnecessary since Tasker offers excellent built-in support for a variety of
ways to use and interact with notifications.
This project will essentially replicate entirely in Tasker what programs like
Voice Notify can do. We will also use Taskers built-in regular expression
1.
https://play.google.com/store/apps/details?id=com.pilot51.voicenotify
146
Talking Notifications
147
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.
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 notification is received in Androids 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 Notification task we created earlier. With the Notification Event profile configured,
the Profile screen should look similar to Figure 88, The Notification Event
profile.
Thats all there is to it. Now whenever you receive a text notification in
Androids notification area, your device should speak the contents of that
148
message. This comes in handy when using programs such as instant messaging, email, media players, meeting reminders, and news readers that post
message updates to the notifications area. If youre already wearing a headset,
theres 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. Thats 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. Lets find out how in the next section.
Notification Filter
Taskers support for regular expressions can be found mainly in its interpretation 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 SL4As notification that the Python script has either started or
exited.
Building this pattern-matching instruction in a regular expression may look
strange if you dont have prior experience building regular expression statements. But once you become familiar with regular expression syntax and
experiment with its parsing capabilities, you quickly appreciate the succinct
power that is inherent in the technology. Heres the regular expression we
will test for in the Read Notification task:
/.*\.py\s(started|exited)\.
Lets 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
Talking Notifications
149
150
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.
Forecast.io
151
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 Taskers 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 Androids notification light
if your hardware supports those features.
Execute additional scripts or tasks depending on the notifications being
received. For example, load your favorite SMS program whenever an SMS
notification is received, ready for you to reply to the message as soon as
you unlock your screen.
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 Androids notification area.
9.2
Forecast.io
One of the most useful iPhone programs Ive 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 wont get very far without a key.
2.
3.
4.
http://www.darkskyapp.com
http://forecast.io
https://developer.forecast.io/register
152
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 Androids notification bar.
While we could work directly with Pythons built-in urllib and json modules
to unpack the response we received from Forecast.ios servers, there is an
easier way. Developer Zeev Gilovitz created an easy-to-use Python wrapper
for Forecast.io that well 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, lets 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.")
https://github.com/ZeevG/python-forcast.io
Forecast.io
153
154
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.
This last line is used as a hack to get around an annoying limitation.
While Tasker is perfectly capable of passing parameters to SL4A running
Python, doing the reverse isnt supported. What Tasker does support is
the ability to read and assign the contents of Androids clipboard to a
Tasker variable. Thats why were copying the results of our concatenated
weather forecast string into the clipboard.
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 isnt the most elegant way to handle the passing of variables from a scripts 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 its what we have to work with until Taskers 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 Androids 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 Androids 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 automated GPS On/Off functionality works only on older or rooted Android devices.
Forecast.io
155
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 Taskers 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 dont want to
execute the rest of the task if we fail to obtain this vital GPS information.
Following a successful GPS coordinate lock-on, we can proceed to run the
localforecast.py SL4A script. Add this by selecting the plus icon in the middle of
the lower Task toolbar and choose Script followed by the Run SL4A Script
action. Assign the Name field of this action to the localforecast.py file. Add the
%LOC location variable to the Pass Variables field and save the action. That
takes care of providing the script with latitude and longitude data and executing the Python script.
Next, we have to assign the contents of the Android clipboard that contains
the copy of the scripts 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. Taskers 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 theres a problem. If we ran this action immediately following the Run
SL4A Script action, we wouldnt see the correct results being assigned to the
%FORECASTIO variable. Thats because Tasker doesnt 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 seconds 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 devices 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.
156
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)
Its time to put that delimiting colon character to use. We are going to use
Taskers Variable Split action as we did earlier in the Talking Clock task, but
instead of splitting on a period, were 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.
Forecast.io
157
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.
158
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 widgets 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.
Incorporate push notification services like Google Cloud Services (GCM)
for Android or third-party services like Pushover to keep track of events
from other people and machines.6
In the next project, were 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 incorporated into Android programs. The Headset Button Controller program, for
6.
AutoNotification
159
https://play.google.com/store/apps/details?id=com.joaomgcd.autonotification
https://play.google.com/store/search?q=joaomgcd&c=apps
https://play.google.com/store/apps/details?id=com.joaomgcd.autoremote
160
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 generated 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.
AutoNotification
161
10. http://www.accuweather.com
162
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.
Running the Forecast.io task
generates an AutoNotificationstyled Android notification
complete with the weather
map link. Since we didnt
choose an icon to use for the
notification, AutoNotification
substituted the default Tasker
icon for us instead. AutoNotification not only allows us to
Figure 99Selecting the notification displays the
change this icon but also add
weather map in a web browser.
an icon in the notification
message. And check out how
choosing the Select for Weather Map SubText opens a web browser showing
the weather map at the time the Forecast.io task was last executed, like the
one shown here.
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 AutoNotifications 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
Next Steps
163
Make the Forecast.io notification persistent so that you dont 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.
9.4
Next Steps
The Android notification area plays an important role in managing real-time
inbound information and helps keep you informed without cluttering your
screen with annoying pop-up messages. Skilled user interface designers and
developers make this look obvious and effortless in elegant Android applications, but it takes practice coupled with a lot of trial and error to see what
works and what doesnt. Thats why I find working with Taskers notification
functionality coupled with plug-ins like AutoNotification to be so helpful. If
something doesnt look quite right, I can immediately jump into the task and
tweak the settings until the results are satisfying.
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 notifications. 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.
Create a task that executes additional scripts upon receiving text in a
notification that matches a defined string. For example, if the string contains the SMS name, phone number, or other unique identifier of your
partner, set the phone to a unique vibrate pattern and/or audio cue until
the notification bar is accessed.
Make your own pull-down system stats notification area showing
remaining battery charge, GPS coordinates, and radio on/off status in a
static or ticker-style format.
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 functionality. We will also further extend Tasker with additional plug-ins to help us
realize these project possibilities faster than ever before.
CHAPTER 10
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 youre constantly on the go, sometimes
a picture truly speaks a thousand words.
In this chapter, were 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. Well create the interface elements and
wire those up with tasks that execute when those onscreen elements are
interacted with.
Lets 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.
166
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).
While we could create a series of freestanding
buttons for each task or program we want to
run, it will be easier to organize and nicerlooking if we place these buttons into a rectangular frame. To do so, select the Scenes tab
in Tasker and create a new scene via the plus
icon. Name the scene App Launcher. Tasker
will then show a blank screen with a center
rectangle. This is the scene container. You
can resize the container by long-pressing the
container and moving your finger left, right,
up, or down to alter its width and height. Set
the width and height roughly to the size of a
Tasker task icon, as shown in the figure here.
Once youre satisfied with the containers
dimensions, you can save your changes by
selecting the back button or the Tasker icon
in the upper-left corner of the screen. Then
reselect the scene to continue editing it.
Figure 100The App Launcher
scene container
Application Launcher
167
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 didnt have to rely on Taskers built-in close scene button size.
168
Application Launcher
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 reference the task and launch our App Launcher
task when we select that widget, it would be Figure 104Exit button warning
for overlay scenes
more elegant if we could instantiate it with a
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.
170
Figure 106Nova Launcher Prime gesture Figure 107The final running Application
settings
Launcher
Application Launcher
171
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 launchers 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.
172
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.
http://twitch.tv
https://play.google.com/store/apps/details?id=tv.twitch.android.viewer
Twitch.tv Widget
173
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 information 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, were going to use
Taskers built-in support for JavaScript instead. In addition to the features
available for Androids browser-based JavaScript engine, Tasker has added
a number of JavaScript functions of its own to provide more extensive interoperability with Taskers 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 thats the approach we are going to take
with this project. While theres 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.
3.
http://tasker.dinglisch.net/userguide/en/javascript.html
174
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 Dans Gaming. Dan employs a clever green-screen effect on his
broadcasts that allows viewers to see him speak comments and see his reactions to onscreen events. He is also a passionate gamer who makes clever,
often funny, and insightful comments about his entertaining gaming adventures. 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 youre curious about learning what this and other
Twitch.tv web service URLs can provide, visit Twitch.tvs 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);
https://github.com/justintv/Twitch-API
Twitch.tv Widget
175
info that will be used to build the HTML-rich text string to be displayed in
176
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.
Building a widget user interface using Zoom is similar to building Tasker
scenes, though Zoom does have a few quirks of its own. One of these annoyances is how Zoom rarely renders a widget UI the way you designed it. Because
of various factors such as different Android hardware devices with different
screen dimensions, calibrations, and font metrics, its just one of those design
aspects that you will have to tweak to get the widgets graphic and text elements to look just right.
Once Zoom has been installed from the Google
Play store, launch it and create a new widget
template by selecting the green plus arrow in the
lower-right corner. Name the template Twitch
Channel and assign it a cell width and height of
2 x 1. Zoom will warn you that the dimension
chosen wont be able to create the widget with
those dimensions. However, because Zoom was
created prior to the changes made to the way
widgets can be displayed and resized on the fly
in Android 4.2 and newer, this warning is no
longer relevant. As for the other settings, you can
leave the default values in place, as shown in the
figure here.
5.
https://play.google.com/store/apps/details?id=net.dinglisch.android.zoom
Twitch.tv Widget
177
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 buttons, 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 magnifying 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 manually 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
178
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 correctly 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 misleading. Instead, you will more likely have to run the widget, switching back and
Twitch.tv Widget
179
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.
When you are satisfied with the design layout,
save the changes by selecting the green check
mark icon in the lower-left corner of the screen.
But before we can place the new widget on our
home screen and use it, we need to add one more
action to our Twitch Channel task. This action
will be to tell Tasker which text element to place
the results of the %TWITCHRESULT variable into.
Open the Twitch Channel task in Tasker and add
the final action. With Zoom installed, you will
now see a new Zoom icon and category in the
Select Action Category dialog. Select the Zoom
category followed by the Zoom Text action. Select
the magnifying glass for the Element field. This
will pop up a list of Zoom text elements that we
created earlier. Choose the Twitch Channel
/Status element from the list. Then set the Text
field to our %TWITCHRESULT variable and save the
changes. Once completed, the final Twitch
Channel task should look like Figure 113, Complete Twitch Channel Tasker task, on page 180.
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. Im
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 dont, the results of the Twitch Channel task wont 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
180
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. Thats
because Tasker needs to be granted explicit permission to access and control other programs on
your Android device, including access to Zooms
widget properties. To grant such permission to
Tasker, follow the messages instructions by
selecting Preferences from Taskers main menu.
Then select the MISC tab and locate and check
the Allow External Access checkbox, as shown in
the figure here.
Now that Tasker has been granted external access
to programs like Zoom, return to the widget and
Figure 114Allowing Tasker
once again touch the Broadcast Status title text.
external program access
For example, if you set the %CHANNEL to dansgaming
and Dan is broadcasting at the moment, you
Twitch.tv Widget
181
should see the title of Dans active Twitch broadcast and the number of people
currently watching his show.
If Dan isnt currently broadcasting his show
or your Android device is not connected to
the Internet, the status text will state in red
text that his channel is unavailable. When
working, your widget may show something
similar to Figure 115, The Custom Twitch.tv
Channel Status widget.
If Dan is broadcasting his show, we can Figure 115The Custom Twitch.tv
conveniently launch the Twitch client by
Channel Status widget
selecting any part of the status text. (Of
course, if you havent created and/or signed in with a Twitch account already,
follow the onscreen prompts to do so. Once you are a registered Twitch.tv
member, you can follow other people on the service.)
If Dan is broadcasting, you can scroll
through the channels until you find his
username and follow him. Once a username
is being followed, it will show up in the
Following section of the Twitch Android
application, as shown in Figure 116, The
Twitch.tv Android client.
When I tested my Zoom-based Twitch widget for this book, Dan was broadcasting a
week-long twenty-four-hour-a-day adventure-gaming marathon, featuring both live
and prerecorded content. So, when I
selected his channel from my Following list,
a stream of his gaming efforts was played
within the Twitch client.
The custom Twitch widget has made monitoring favorite channels so much easier and
interactive, and I rarely ever miss a chance
to see game players like Dan broadcast live
as a result. But even though the option to
manually run the Twitch Channel task by Figure 116The Twitch.tv Android
client
touching the Broadcast Status text in the
widget is convenient, it would be even more
182
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. Lets create a new Tasker profile that automatically
runs the Twitch Channel task at regular intervals.
Next Steps
183
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 JSONconforming 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 Zooming further along:
Parse an array of usernames to check the broadcast status on more than
one user.
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.
184
Visit the books 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 exploration. 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.
Part IV
Appendixes
APPENDIX 1
188
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.
DroidEdit Pro is also cloud-friendly in that it
can be used to issue remote build commands
on the server receiving file transfers like
Rubys Capistrano project. For example, you
can create and save a sophisticated build
script on the file-receiving server that can be
triggered by DroidEdit Pros Add External
Command function. Upon completion of a file
transfer, the commands you define are executed on the remote server, and the results of
the execution can be displayed in a result
screen or in a new or existing document. You
can use it to compile C or Java programs and
run Ruby or Python scripts or even complex
Puppet server workflows.
Andr offers a free, ad-supported non-Pro
version that provides a taste of the full version, but its not one I would advocate using
for the long haul. Besides its lack of remote
file transfer support, who wants annoying ads
popping in and out while youre trying to
concentrate on writing code?
https://play.google.com/store/apps/details?id=com.aor.droidedit.pro
Code Editors
189
can also remotely issue commands to the host server when files are transferred, 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.
Price: $1.91 US.
Terminal IDE
There is one Android Terminal program I consistently use above all othersTerminal IDE.2 Created by hacker Spartucus Rex, the applications GPLv2-licensed
source code and helpful, albeit minimal, documentation are freely available
for download from its Google Code project home page.3
In addition to providing a clean terminal interface to the rudimentary subset
of Linux command-line utilities on Android, Terminal IDE includes an Install
System button on its main screen that downloads and installs a vast array
of terminal applications. Secure shell, a minimal Java SDK, rsync, git, and
many more programs help round out the Terminal IDE experience. And all
of this command-line goodness is available for standard devices (no root
access required) running Android 2.3 or newer.
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.
3.
https://play.google.com/store/apps/details?id=com.spartacusrex.spartacuside
http://code.google.com/p/terminal-ide/
190
Code Editors
191
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 IDEs 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, its
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, its a shining example of the open source ideology on the
Android platform.
Pros: Comprehensive terminal package with a slew of useful, preconfigured
command-line utilities. It does not require root-level access to install and
use. It includes useful onscreen keyboard replacement optimized to work
with terminal entry. Its also free with source code available for download
and study.
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
192
5.
https://play.google.com/store/apps/details?id=org.pocketworkstation.pckeyboard
193
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
Its 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.
TextWarrior also features a text clipboard
on a virtual shelf that slides in and out of
the screen, as well as the usual autoindent and word wrapping that is expected
with modern-day editors. Word and character count are also standard, as is its
unique ability to copy selected text
dragged onto a target area. All this, combined with the free open source software
license, makes TextWarrior a text editor
worth installing.
Pros: Handles large text files that
would crash other GUI-based Android
text editors. It has a drag-and-drop
text editing interface. It supports a
rudimentary set of markup and programming languages, and its free.
Cons: Does not syntax highlight HTML
or XML. It can have problems with
nonstandard Android onscreen keyFigure 121Viewing a large debug file
boards. The interface and cursor
using TextWarrior
operation take time to get used to.
Price: Free.
https://play.google.com/store/apps/details?id=com.myopicmobile.textwarrior.android
194
Git
Git is bundled in two products we have already evaluated: AIDE and Terminal
IDE. AIDEs version of Git is unlocked when the AIDE Premium key is purchased. 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 AIDEs or Terminal IDEs
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 youre 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 Vims 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.
8.
9.
https://play.google.com/store/apps/details?id=com.madgag.agit
https://github.com/tpope/vim-fugitive
https://github.com/motemen/git-vim
195
196
If youre 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 Swicegoods book Pragmatic Guide to Git [Swi10], published by
Pragmatic Bookshelf.
Pros: Free. It has exceptional DCVS.
Cons: No GUI-friendly read-write Git client exists yet on Android, although
developer Roberto Tyler aspires that his Agit client will achieve this status
one day, eventually. However, I have been waiting for nearly a year to see
this much-needed functionality added, so I have low expectations that
Agit will receive such an upgrade any time soon.
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 Mercurial 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 hasnt been updated in more than
two years, it may eventually dissipate into the
ether along with Mercurial.
Pros: One of the only Mercurial-compatible
clients available on Google Play. It can
import Mercurial repositories from popular
public Mercurial repositories such as Google
Figure 123Mercury for Android
Code, Bitbucket, and CodePlex. Its free.
Cons: Read-only client with bare-bones beta
interface. It does not support secure repositories, and its yet another application that unnecessarily requires it automatically start at boot time.
Price: Free.
10. https://play.google.com/store/apps/details?id=ca.spencerelliott.mercury
197
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
198
To learn more about Subversion, read Mike Masons 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.
Cons: Kludgey interface. Its slow. There is no GUI-based diff visualization.
Price: Free.
12.
13.
14.
15.
https://play.google.com/store/apps/details?id=com.agilesoftresource
https://play.google.com/store/apps/details?id=ru.kslabs.ksweb
https://play.google.com/store/apps/details?id=be.ppareit.swiftp
https://play.google.com/store/apps/details?id=com.nraboy.sqltool
Miscellaneous Tools
199
If youre a developer who prefers using the Git and Mercurial-supported Bitbucket DVCS service,16 Saibotds 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.
Hundreds of other excellent code-centric utilities are available for download
from the Google Play store. Google has made searching for applications a
breeze via the Play Store Android app or the Play Store website.20 You will
likely find what you are looking for.
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, respectively.
19. https://play.google.com/store/apps/details?id=com.locnet.dosbox
20. https://play.google.com/store/apps
APPENDIX 2
1.
2.
3.
4.
5.
https://plus.google.com/101304250883271700981/posts
http://code.google.com/p/android-scripting/wiki/Tutorials
http://www.pocketables.com/2013/03/overview-of-pocketables-tasker-articles.html
http://www.reddit.com/r/Tasker
http://stackoverflow.com/questions/tagged/sl4a
202
6.
http://tasker.wikidot.com
Bibliography
[Bur10]
[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.
[Fri97]
[Hog12]
[Mas06]
[Nei12]
Drew Neil. Practical Vim: Edit Text at the Speed of Thought. The Pragmatic
Bookshelf, Raleigh, NC and Dallas, TX, 2012.
[N09]
[Pin09]
[Ril12]
[Sau12]
Bibliography
204
[Swi10]
[TFH13]
David Thomas, Chad Fowler, and Andrew Hunt. Programming Ruby 1.9 &
2.0: The Pragmatic Programmers Guide. The Pragmatic Bookshelf, Raleigh,
NC and Dallas, TX, Fourth Edition, 2013.
Index
SYMBOLS
% (percent sign), preceding
Tasker variables, 45
DIGITS
3G radio, disabling, 100101
A
accessibility settings, 146
ACTION_BATTERY_CHANGED intent,
83
actions, for tasks
Hide Scene action, 167
JavaScriptlet action, 174
Notify action, 156, 159
Perform Task action,
123, 167
Run SL4A Script action,
69, 134, 140, 155
Say action, 4446, 49,
146
Show Scene action, 168
Variable Set action, 46,
102103, 105, 155
Variable Split action, 47,
156
Wait action, 155
Zoom Text action, 179
ADW Theme MacOS, 2425
ADWLauncher EX, 11
Agit, Git client, 194
AIDE (Android Java IDE), 76
84
creating apps, 7778
downloading and installing, 77
Git included in, 194
libraries for, 76, 83
online resources for, 201
running apps, 84
Talking Clock application
using, 7784
templates for, 77
AirCalc floater, 20
airplaine mode, turning on or
off, 101
AirTerm floater, 20
alarms
based on GPS location,
5357
setting with spoken commands, 30
AnDOSBox tool, 199
Android AIDE on Google+,
201
Android APIs, 76, 83
Android device, see device
Android Java IDE, see AIDE
Android OS
advantages of development with, xii
history of, xi
jailbreaking, xivxv
rooting, xivxv
version requirements for,
xiii
Android Scripting Environment (ASE), see SL4A
Android Scripting Tutorials,
201
Android Voice Xtreme application, 3233
AndroZip File Manager, 198
Apex Launcher Pro, 11
.apk file extension, 57
Index
Automator application, OS X,
42
AutoNotification Tasker plugin, 158163
AutoRemote Tasker plug-in,
159
B
backups, automating, 7
battery status, programming
with AIDE, 83
Battery Status task, 4950
BatteryManager intent, 83
Bitbreaker tool, 199
Bluetooth keyboard for Android, xiii, 81
browsers
Overskreen floater, 21
spoken commands for, 30
button controls, headset, 33
37
configuring, 35
long button press restrictions, 34
operating, 3637
soldering more buttons,
38
buttons, in Tasker scenes,
166168
C
calculators, AirCalc floater,
20
Calendar widget, 17
calendars
adding events with spoken commands, 30
spoken events from, 32
Case Logic TBC-412, 28
cellular data, disabling, 100
101
Check Email widget, 19, 115
126
assigning to headset button, 125
checking for WiFi in, 122
mail server compatibility
for, 116118
Python script for, 115
116, 118121
task for, 121124
testing, 121, 123
time and resources used
by, 122123
widget for, creating from
task, 124
D
Dalvik virtual machine, 63
Dark Sky program, 151
DashClock widget, 16
Data Usage app, 5
database editors, SQLTool Pro
Database Editor, 198
device
accessibility settings for,
146
clipboard, reading into
Tasker variable, 154
155
keeping awake while
running applications,
97
mobile lifestyle using, 3
7
programming on, 75, 78
radios on, disabling, 100
101
Dias, Joo, developer
AutoNotification Tasker
plug-in, 159
AutoRemote Tasker plugin, 159
DICE Player floater, 21
DoggCatcher Podcast Player,
6
DOS emulators, 199
DroidEdit Pro code editor,
188189
206
E
.egg file extension, 65
Elliot, Spencer (developer,
Mercury), 196
Emacs code editor, 191192
email, spoken
Android Voice Xtreme,
3233
Check Email widget, 19,
115126
events, see calendars
Extensible Messaging and
Presence Protocol,
see XMPP
F
Fabric library, Python, 129
Fehling, Ken (developer,
TaskBomb), 70
fetch() function, 120
file managers, AndroZip File
Manager, 198
finish() function, 84
flashlights, Smart Tools
Flashlist widget, 18
floaters, 9, 1922
For loop, Python, 120
Forecast.io web service, 151
Python wrapper for, 152
from keyword, Python, 152
FTP Server, 198
G
GAE (Google App Engine), 88
GCM (Google Cloud Messaging), 88
geographical location,
see GPS
gestures, assigning to tasks,
169171
Gilovitz, Zeev (developer
Forecast.io Python wrapper), 152
Git source version control,
194196
Gmail IMAP settings, 117
GO Launcher EX, 11
GO Launcher EX Windows
Phone 7, 2224
Google App Engine (GAE), 88
Google Cloud Messaging
(GCM), 88
Google Now, 3031, 34
Index
Google Translate API, 88
GPS
alarms based on location,
5357
capturing location to
send in message, 140
turning radio on or off,
101
weather forecasts based
on location, 151158
graphics
Application Launcher
toolbar using, 165172
Twitch.tv widget using,
172183
keyboard
Bluetooth, xiii, 81
on-screen, 192
KML (Keyhole Markup Language), 143
Kober, Christoph (developer,
Headset Button Controller),
18, 34
Kravchencko, Alex (developer,
Smart AudioBook Player),
37
KSWEB tool, 198
I
images, see graphics; photos
IMAP (Internet Message Access Protocol), 116118
IMAP UNSEEN command,
120
Instructables.com website, 38
Internet Message Access Protocol (IMAP), 116118
J
Jabber Tracker task, 136143
capturing location, 140
frequency of, 141
L
launchers, 914
list of, 1113
security issues with, 13
themes for, applying, 22
24
libraries
Android APIs, 76, 83
Python, 116, 118, 127
129, 136
location, geographical,
see GPS
lock-screen widgets, 1517
Logitech Tablet Keyboard for
Win8/RT and Android, xiii
M
Mac desktop wallpaper, 24
Mac OS X desktop, emulating, 2425
maps, spoken directions
from, 30
MBFG (My Boyfriend is a
Geek), floaters by, 2021
207
media players
controlling with headset
buttons, 37
DICE Player floater, 21
SL4A scripts stopping,
124
spoken commands for, 30
Stick it! floater, 21
Mercurial source version
control, 196
Mercury source version control, 196
mobile lifestyle
analyzing, 36
needs for, determining,
67
Moon Phase Pro widget, 17
My Boyfriend is a Geek
(MBFG), floaters by, 2021
N
NFC (Near Field Communication), 89
notifications
disabling, 100101, 150
filtering, 148150
talking, 145151
of weather forecasts,
151158
word wrap limitations for,
158, 161162
Notify action, 156, 159
Nova Launcher Prime, 12, 22
25, 169171
Nurik, Roman (developer,
DashClock widget), 16
O
OASVN PRO, Subversion
client, 197
OAuth credentials for Twitter,
129131
onFinish() event handler, 83
onInit() event handler, 83
onTick() event handler, 83
OnInitListener interface, 83
online resources, xvi, 187
202
AIDE, 76, 201
Android SDK, 76
Bitbreaker tool, 199
browsers, 21
button soldering technique, 38
calculators, 20
Calendar Provider, 88
Index
code editors, 187193
command line applications, 20
cron job scheduler, 70
database editor, 198
DOS emulators, 199
file manager, 198
file transfer programs,
100
floaters, 2021
FTP Server, 198
gadget-friendly clothing,
29
GAE, 88
GCM, 88
Google Translate API, 88
Headset Button Controller widget, 18
KML, 143
launchers, 10
lock-screen widgets, 16
media players, 21, 37
Moon Phase Pro widget,
17
NFC, 89
onscreen keyboard, 192
OS X emulators, 24
PHP development, 198
podcast applications, 6
Pomodoro Technique, 93
Python libraries, 65,
129, 136
Ruboto framework, 67
SL4A scripting, 201
SL4A scripting languages,
7273
source version control
systems, 193198
SVOX text-to-speech
synthesis, 27
Tasker App Factory, 57,
60
Tasker automation tool,
41, 62, 201202
Tasker icon sets, 106
Tasker JavaScript functions, 173
Tasker plug-ins, 159
Tasker variables, 45
text-to-speech applications, 3133
Textastic code editor, 189
TTS, 145
Twitch.tv service, 172
Twitter Developers apps,
129
weather forecasts, 151,
161
web microframeworks, 74
WiFi Direct, 88
Windows Phone emulators, 22
Zoom utility, 176
Overskreen floater, 21
P
pattern matching, see regular
expressions
percent sign (%), preceding
Tasker variables, 45
Perform Task action, 123, 167
permissions
DashClock widget requiring, 17
launchers requiring, 13
Tasker tasks requiring,
58, 60, 180
phone calls, see voice calls
photos, automatically editing
and posting, 7
PHP development tools,
KSWEB tool, 198
Pocketables Tasker Articles,
201
podcast applications, 6
Pomodoro Technique, 93
Pomodoro widget, 18, 93112
assigning tasks to widget,
96
audio clips for, 99
disabling radios during,
100101
features of, 93, 98
icon for, 95, 106
keeping device awake
during, 97
limitations of, 111112
profile for, 104105
prototyping, 9398
task for decrementing
and ending timer, 95,
102107
task for starting timer,
99102, 105106, 109
testing, 9697, 107111
Processing language, 73
profiles, for tasks, 43, 5052,
5556, 147
programming skill requirements, 7
programming tools, 187199,
see also AIDE; SL4A
prototypes, 8, 9398
PyCrypto library, Python, 129
208
R
Raboy, Nic (developer, SQLTool Pro Database Editor,
198
radios, disabling, 100101
recognizeSpeech() function, 132
Reddit Tasker Forum, 201
regular expressions
in Python, 119120
in Tasker, 148150
Restivo, Andr (developer,
DroidEdit Pro, 188
Rex, Spartucus (developer,
Terminal IDE), 189
rooting, xivxv
RSS news feeds, converting
to speech, 7
Ruboto framework, 67
Ruby interpreter for SL4A,
66, 69
Run SL4A Script action, 69,
134, 140, 155
Running Applications app, 5
S
Samsung TouchWiz launcher,
10
Say action, 4446, 49, 146
scenes, in Tasker, 165168
Index
scheduling SL4A scripts, 69
71
ScottEVest clothing, 29
Scripting Layer for Android,
see SL4A
scripting, effort involved in, 8
security
installation of programmed apps, allowing, 79
permissions required by
DashClock widget, 17
permissions required by
Tasker tasks, 58, 60,
180
permissions required by
launchers, 13
Sense launcher, HTC, 10
Show Scene action, 168
SimpleDateFormat class, 83
SL4A (Scripting Layer for Android), 18, 6372, see also Python interpreter for
SL4A
Check Email widget using, 115116, 118121
downloading and installing, 64
Jabber Tracker task using, 136139
languages hosted by, 64,
7273
media players stopped
by, 124
online resources for, 201
Ruby interpreter for, 66,
69
scheduling scripts, 6971
shortcuts for, compared
to task widgets, 126
Speak n Tweet widget
using, 126134
Talking Clock application
using, 6869
Tasker variables passed
to, 136
weather notification using, 151154
SL4A editor, 66
SL4A Script Launcher, for
TaskBomb, 70
Smart AudioBook Player application, 37
Smart Tools Flashlight widget, 18
smartphone cases, 28
T
Talking Calendar application,
32
Talking Clock application
assigning to headset button press event, 8687
programming with AIDE,
7784
Python script for, 6869
Ruby script for, 69
task for, 4353
Talking SMS and Caller ID
application, 31
TaskBomb application, 7071
Tasker App Factory, 5760
Tasker automation tool, 41
43
actions for tasks, 4446
Application Launcher
toolbar using, 165172
apps, creating from
tasks, 5760
209
AutoNotification plug-in,
158163
AutoRemote plug-in, 159
backing up and restoring
scripts, 52
Battery Status task using, 4950
buttons for scenes, 166
168
Check Email widget using, 121124
configuring, 4243
gestures, assigning to
tasks, 169171
icon sets for, 106
installing, 42
Jabber Tracker task using, 140141
JavaScript functions for,
173176
online resources for, 201
202
passing variables to
scripts, 136
permissions required for
tasks, 58, 60, 180
plug-ins for, installing,
159160
polling frequency for, 42
profiles for, 43, 5052,
5556, 104105, 147
prototyping with, 9398
reading clipboard contents, 154155
regular expressions in,
148150
running SL4A scripts
from, 69, 122, 154157
scenes, creating, 165168
Speak n Tweet widget
using, 134135
Talking Clock application
using, 4353
tasks for, creating, 43
46, 5354, 95, 99107,
146
testing scripts, 9697
text-to-speech notifications using, 145151
Train Station Alarm task
using, 5357
triggers for tasks, 42, 50
52, 5556
Twitch.tv widget using,
172183
variables in, 4549
weather notification using, 154157
Index
widgets, compared to
SL4A script shortcuts,
126
widgets, creating from
tasks, 94, 96, 107,
124, 134, 176180
Zoom utility for, 176180
Tasker Wiki, 202
terminal emulators, see command line applications
Terminal IDE code editor,
189191, 194
text messages
parsing and reacting to,
7
spoken, 3133
text-to-speech technology,
see TTS technology
Textastic code editor, 189
TextWarrior code editor, 193
3G radio, disabling, 100101
time.sleep() function, 132
timer, 18, 93, see also Pomodoro widget
TouchWiz launcher, Samsung, 10
Train Station Alarm task, 53
57
triggers, for tasks, 42, 5052,
5556
try-except block, Python, 119
TTS (text-to-speech) technology, 27
accessibility settings for,
146
Android Voice Xtreme
application, 3233
APIs for, 83
configuring, 2930
Headset Button Controller widget, 3337
Talking Calendar application, 32
Talking Clock application, 4353
talking notifications,
145151
Talking SMS and Caller
ID application, 31
Voice Notify program, 145
ttsSpeak() function, 120, 132
U
Udell Enterprises (developer,
Moon Phase Pro widget), 17
Unknown sources security
setting, 79
UNSEEN command, IMAP,
120
V
Variable Set action, 46, 102
103, 105, 155
Variable Split action, 47, 156
variables
passing from Tasker to
scripts, 136
in Tasker, 4549
version control systems,
see source version control
systems
Vim code editor, 190, 194
VM (virtual machine), 63
voice calls
handling based on caller
ID, 7
making with spoken
commands, 30
spoken notification of,
3133
210
W
Wait action, 155
Wake-On-LAN (WOL) packets,
7
wallpaper, applying, 2324
wearable computing, 2729
weather forecasts
Dark Sky program, 151
Forecast.io web service,
151
notification of, based on
location, 151158
web microframeworks, 74
Weidner, Klaus (developer,
Hackers Keyboard), 192
widgets, 9, 1419, see also specific widgets
displaying on home
screen, 15
displaying on lock screen,
15
installed, viewing, 14
list of, 1719
lock-screen compliant,
1517
WiFi radio, disabling, 100
101
Wilmot, Lee (developer,
Tasker), 42
Windows Phone user interface, emulating, 2224
WOL (Wake-On-LAN) packets,
7
X
XMPP (Extensible Messaging
and Presence Protocol)
client account for, 136
137
Jabber Tracker task using, 136143
Python library for, 136
Z
Zoom Text action, 179
Zoom utility, 176180
Seven in Seven
Go beyond learning a new languagelearn seven. And get up to speed on the latest NoSQL
databases.
Visit Us Online
This Books Home Page
http://pragprog.com/book/mrand
Source code from this book, errata, and other resources. Come give us feedback, too!
Read our weblogs, join our online discussions, participate in our mailing list, interact with
our wiki, and benefit from the experience of other Pragmatic Programmers.
Check out the latest pragmatic developments, new titles and other offerings.
Contact Us
Online Orders:
http://pragprog.com/catalog
Customer Service:
support@pragprog.com
academic@pragprog.com
http://pragprog.com/write-for-us
Or Call:
+1 800-699-7764