Webinars for Meetups
While I am still on
my presentation sabbatical,
there are still ways that I can help your meetup, GDG, or similar
collection of Android developers: webinars.
I hold webinars
several times a month, each usually lasting an hour. While there is a
nominal fee for attending, that fee is per connection, not per person.
A collection of people are welcome to attend via some shared connection
to the Dozeo web conference,
whether that collection represents a team at a firm in a conference
room or an independent group like a meetup in an, um, larger conference room. :-)
For groups, I can schedule additional webinars — on current or
past topics — at times that fit your group’s schedule. So, for
example, if your meetup meets on the third Tuesday of every month, we
can set up a webinar fitting that time slot. Times from 8am to 8pm (US
Eastern) are available.
If you are interested in scheduling a webinar as part of
an event for your group, contact me
and we can work out the details.
—Jan 22, 2015
The Busy Coder's Guide to Android Development Version 6.4 Released
Subscribers now have
access to the latest release of The Busy Coder’s Guide to Android Development,
known as Version 6.4, in all formats. Just log into
your Warescription page and download
away, or set up an account and subscribe!
This update is focused on a bunch of TV-related stuff that I had worked
on prior to Android Studio 1.0 shipping, causing the TV stuff to get
put aside temporarily. The TV material includes:
Preliminary coverage of the
leanback-v17 library, focused on
BrowseFragment for providing a two-dimensional, D-pad-friendly
navigation option for browsing a content catalog
A chapter on Android TV, converted from the Google TV chapter
Mention of the Fire TV Stick in the coverage of Fire TV
A new chapter reviewing a large sample app, Decktastic, which presents
conference-style presentations using an external display (HDMI, MHL,
Miracast, etc.), Chromecast (and other
RemotePlaybackDevice devices), and direct-to-TV devices (Android TV,
Fire TV, etc.)
This update also contains:
A new chapter on
AndroidJUnitRunner and JUnit4 support. Espresso
support should be covered in some future edition of the book.
VideoList sample in the chapter on the
SmartImageView with the Universal Image Loader for
asynchronously loading video thumbnails.
A merged chapter on the basics of Gradle and the manifest, as having
those spread over two chapters was too confusing.
Updated material on publishing AARs, focusing now on the official
Various bug fixes and such.
The next update is tentatively slated for mid-March 2015.
—Jan 20, 2015
Getting a JAR into Android Studio
Brian Marick writes:
I am stunned, as if struck by a ball-peen hammer, by how hard it is to say “use this jar” to Android Studio 1.0.2. If it’s even possible.
It’s certainly possible, and in a standard Android Studio project it
is pretty easy. Whether it is the right solution, though, is another matter.
I would recommend that you do some poking around and see if the library
is offered as an artifact in some place like Maven Central. The
“Gradle, please” Web site can help
with this, or you can use the Project Structure dialog in Android
Studio itself (File > Project Structure from the main menu).
Specifically, the Dependencies tab for your module
app) has a similar search feature to what “Gradle, please” offers.
Just use the + button and choose a “library dependency”, then search.
Whether you find the artifact from “Gradle, please” or add it via
the Project Structure dialog, the result is pretty much the same:
compile statement added to your module’s
// and perhaps other lines here
Using the artifact means that chained dependencies (e.g., the JAR
depends upon other JARs) are handled for you, and updating to a
newer version of the JAR is simply a matter of updating the version
number in the
compile statement. Plus, your version control system
is now tracking what version of the JAR you are using, as opposed
to checking in some random JAR binary.
But, suppose you have a random JAR (
andataco.jar), and you cannot
find an artifact for it.
If your module’s
build.gradle file has the standard new-project
compile fileTree(dir: 'libs', include: ['*.jar'])
then all you need to do is put the JAR in
libs/ within the
module, and you are done. The
compile fileTree() statement
says “yo, Gradle, take all the
.jar things in
compile ‘em into the project”. That will add the JAR to the
compile-time classpath and, for an Android project, also package
the JAR’s contents into your APK file.
—Jan 16, 2015
Library Authors: You Can't Always Get What You Want
Given the rise of Android Studio, more and more Android library authors
are creating Android library projects and publishing them as AARs,
as opposed to trying to stick to plain JARs. Nowadays, this approach
as the added benefit offering manifest merging, so a library author
can contribute elements to the manifest:
<uses-feature> elements that the library
needs for various operations
<activity>) elements, to save the developer using
the library to have to manually add them
<uses-sdk> element, with the library author’s own take on what
targetSdkVersion should be
and so on
Library authors should not get complacent, though, and assume that
just because they ask for it in the library’s manifest, that they will
get it. Developers have the ability to reject anything introduced
by the library’s manifest, through two major approaches:
tools:node="remove" attributes to copies of elements to be blocked,
such as having
tools:node="remove" on a
to specifically block libraries from adding that permission requirement
tools:overrideLibrary to the
<uses-sdk> element, indicating
libraries whose opinions on
should be ignored
Library authors need to practice defensive programming and make sure
that they react to the environment around them.
If you gotta gotta gotta have some permission, make sure that your
library “fails fast”, so that the developer is guaranteed to find out
that blocking the permission is not supported. This may come about
naturally by use of your library, such as a camera library failing
quickly when trying to use
android.hardware.Camera if the
CAMERA permission were blocked. However, if the permission is essential
but may not be used until later in the workflow, use
to determine if you have the permission, and fail early on with your
own exception, rather than wait.
If the permission is not essential for the overall library, but it is
essential for some feature of the library, try to gracefully degrade
if the feature is used but the permission is blocked. For example,
some app developers try to avoid
WRITE_EXTERNAL_STORAGE for fear of
backlash from users. If your app would default to using external storage
for something (and therefore perhaps needs this permission), see if
there is a workaround (e.g., have the file on internal storage and use
FileProvider to serve it to third-party apps). Or, simply fail the
request, ideally in some way that allows the user to understand what
is going on or for the app developer to react to the missing feature.
So, if you need
WRITE_EXTERNAL_STORAGE and do not have it, through
some custom checked exception, or have a
that the app developer should call to determine if the feature can be
used, or something.
The same holds true for anything else that you introduce in the
If you specify a
minSdkVersion, recognize that your vote may be
ignored, so you may be running on an older device. Where possible, try
to handle that gracefully (e.g., use
Build.VERSION.SDK_INT to see what
you really are running on and react). Or, check the version information
up front and fail fast, or at least introduce a warning to alert the
developer that you’re not responsible for any
due to your running on an older-than-expected Android device.
If you specify a
targetSdkVersion, you should be able to find out what the actual
targetSdkVersion is from the
ApplicationInfo object that you can
If you added components and planned on trying to use those components
yourself (e.g., register a
PendingIntent pointing to a
that you had set up in your manifest), you can use
determine if you actually have that
BroadcastReceiver registered in the
And so on.
Of course, this is all a pain. I need to do a better job of this myself
for my CWAC libraries.
:: adds item to to-do list::
On the other hand, we really should have been doing this sort of thing
before manifest merging came about, as we were expecting the app developer
to manually set up these things in their app’s manifest… and they might
not. Just because we can automate putting our requirements in the manifest
does not eliminate our need to validate what we got and handle differences
appropriately. As some
old British guys have pointed out for years,
you can’t always get what you want.
—Jan 15, 2015
I have a new crop of webinars
going on over the next couple of months:
Android Studio for Eclipse Users
is a quick tour of Android Studio, pointing out key differences between
how Eclipse worked and how Android Studio works.
A Peek at JobScheduler,
which, as the title suggests, reviews the
JobScheduler system service
that was added to Android 5.0, as an alternative to
What’s New with Notifications
covers some of the changes that arose in 2014 related to the use of
Notifications, such as customizing them for Android Wear and Android 5.0’s
Making Sense of Storage,
covering the differences between internal, external, and removable storage,
ContentProviders are replacing direct filesystem access for
accessing another app’s files.
(NOTE: those of you who signed up for the “Making Sense of Storage” from
mid-December that was canceled due to technical difficulties, Dozeo is
working again, and I have added another edition of that webinar for
noon US Eastern on January 22nd)
Remember: active subscribers have access codes on
the Warescription site for 80% off the
already-cheap registration fees for these webinars!
—Jan 08, 2015