The CommonsBlog


Be Careful Where You Use Custom Parcelables

Custom Parcelable classes — ones unique to your app, not a part of the Android framework — have had intermittent problems over the years when used as Intent extras. Basically, if a core OS process needs to modify the Intent extras, that process winds up trying to recreate your Parcelable objects as part of setting up the extras Bundle for modification. That process does not have your class and so it gets a runtime exception.

One area where this can occur is with AlarmManager. Code that used custom Parcelable objects with AlarmManager that might have worked on older versions of Android will not work on Android N.

Completely in-process uses of custom Parcelable objects, such as extras on LocalBroadcastManager Intents, is safe. Using custom Parcelables in the saved instance state Bundle should be safe. The further afield from that you get — including any place where you might distribute a PendingIntent — be careful and be sure to test thoroughly.

One workaround, such as it is, is to load the data from persistent storage when needed, perhaps using a process-level cache if your process still happens to be around. So, for example, suppose you used PendingIntent.getBroadcast() with AlarmManager. Rather than put a custom Parcelable in the Intent extra, just include enough key data to know what you need. Then, as part of processing the alarm event, go grab that data from cache or storage.

Another approach is to switch from Parcelable to “bundleable”: convert your object to and from a Bundle, sticking to framework-defined classes for all the contents of the Bundle. Since all the classes are available to all relevant processes, you should not run into the sort of problem that you get from custom Parcelable classes.

I assume that the problem with Parcelable will also affect Serializable, though I am not certain of that.

Jul 22, 2016


The Busy Coder's Guide to Android Development Version 7.5 Released

Subscribers now have access to the latest release of The Busy Coder’s Guide to Android Development, known as Version 7.5, in all formats. Just log into your Warescription page and download away, or set up an account and subscribe!

In this update, I:

  • Added a new chapter on Espresso

  • Revamped the chapter on Chrome OS to focus on the new implementation of Android-on-Chrome OS that debuted in late June 2016

  • Rewrote much of the chapter on SSL, to tie it into Android N’s network security configuration and the CWAC-NetSecurity backport

  • Added new material to the chapter on data binding for two-way binding, binding event handlers, and chained expressions

  • Updated the material on WebView to cover Android N’s new source of the WebView code (proprietary Chrome browser APK)

  • Updated Tutorial #1 to offer downloads of Android Studio 2.1.2, the particular version of Android Studio referenced in this book

  • Retired the chapter on action bar navigation (long since deprecated by Google), two chapters related to scripting (out of date), and the chapter on writing desktop apps in Android (replaced partly by the Chrome OS and keyboard/mouse chapters)

Version 7.6 is tentatively slated for late August. This will depend a bit on when Android Studio 2.2 ships to the release channel, as I will need to substantially overhaul some of the introductory chapters to address this change, and that will take some time.

Jul 21, 2016


Android on Chrome OS: Updated Information

Courtesy of a Google employee who reached out to me, here are some updates on the Android-on-Chrome-OS development process.

  • You no longer need to run a bash script on your developer machine to enable adb access, as you needed earlier. This simplifies setup a lot and makes it much easier for Windows developers.

  • If, however, you followed those earlier instructions, a recent Chrome OS update might have broken your adb access. If so, try turning off, then on, the Developer Options, via the switch in the action bar of the Developer Options screen. Then, try reconnecting via adb connect. You should get the standard Android debugging authorization dialog on the Chrome OS machine. After accepting that, you should be good to go to use adb.

  • AlarmManager and JobScheduler, which previously did not work, are now working. The exception is if the Chrome OS device is asleep (e.g., lid closed) — in that case, alarms and jobs will not fire. This includes any _WAKEUP alarms.

  • Chrome OS should remember whether you have enabled Android apps on the device even after a reboot. This used to not work, forcing you to re-enable Android app access after every reboot.

  • You are supposed to be able to file issues related to Android-on-Chrome-OS via this link, which redirects to the Chromium issue tracker, using a template that sets up some appropriate labels. As always, the more information that you can provide to replicate any bugs, the better off you will be.

Jul 19, 2016


Backporting Android N Network Security Configuration

The N Developer Preview gave us the network security configuration feature. This makes it rather easy to:

  • Use self-signed certificates for your HTTPS requests, such as for debug builds
  • Supporting unusual certificate authorities, ones that Android itself lacks support for
  • Limiting HTTPS requests to a specific authority, such as tying requests to your server to an authority that you use, to help reduce the odds that someone will be able to generate fraudlent certificates and implement a Martian-in-the-middle (MITM) attack
  • Going one step further and pinning your HTTPS requests to a specific certificate
  • And so on

The v24 edition of the Android Support Library does not appear to contain a backport of network security configuration. With luck, someday, it will have one.

In the meantime, though, I backported it myself.

The CWAC-NetSecurity library is the home of this backport. It uses the NDP4 code from the AOSP for the network security configuration implementation, with minor adjustments to get it to build going back to API Level 17 (Android 4.2). Adding it to your project is a matter of:

  • Getting the native network security configuration working on an Android N test environment
  • Adding the CWAC-NetSecurity library to your project
  • Adding a few lines of code to configure OkHttp3 or HttpURLConnection to apply the network security configuration rules

Along the way, I added a few more options, such as the ability to choose the configuration to use on the fly, rather than have to use the one defined in the manifest, as the native implementation requires.

CWAC-NetSecurity is optimized for use with OkHttp3. Some network security configuration features are available to HttpURLConnection, and there are instructions for building bridges to other HTTP client APIs. Or, use the backport directly, bypassing my TrustManagerBuilder wrapper.

TrustManagerBuilder had resided in the CWAC-Security library. I moved it into CWAC-NetSecurity, deprecating the version in CWAC-Security.

Until Android N transmogrifies into a nougat-flavored Android 7.0, CWAC-NetSecurity is in a pre-release state. I will upgrade CWAC-NetSecurity to use newer AOSP code as it is released, such as when the AOSP code for Android 7.0 ships. A table in the project README tracks library versions and corresponding AOSP code bases

Bug reports are welcome, if I can reproduce the bugs. :-)

Jul 11, 2016


Android on Chrome OS: adb Access

The Android-on-Chrome OS documentation was updated recently to include instructions on connecting to your Chrome OS device through adb from your development machine. This will allow you to run apps on the Chrome OS device from Android Studio, for example.

Unfortunately, the instructions have bugs, and I don’t know where to report those bugs. So, here is what worked for me, using their instructions as a starting point.

Get the Basics Working

Follow the instructions in my “Getting Started” and “Getting (Side-) Loaded” blog posts to get your Chrome OS device up to date and in developer mode, plus get the Android subsystem working.

Configure the Chrome OS Device

The official instructions ask you to use “virtual terminal 2” and log in as root to make changes to Chrome OS. I could not get this to work; even their supplied default root password was not recognized.

Instead, I used Ctrl-Alt-T to open crosh. From there, I executed the shell command to get to bash. And, for their documented root commands, I used sudo.

So, if you get to bash using those steps, execute the following statements:

sudo /usr/libexec/debugd/helpers/dev_features_rootfs_verification
sudo reboot

This will reboot your Chrome OS device, requiring you to go through the whole Play Store acceptance/login process again.

Then, go back into bash, and execute:

sudo /usr/libexec/debugd/helpers/dev_features_ssh

This enables an SSH daemon and presumably makes corresponding adjustments to the iptables-based firewall.

Find Your Chrome OS IP Address

The official instructions tell you to do this “from ChromeOS settings”, without actually explaining how that is done.

Go into Settings (e.g., tap on the time/WiFi/battery/account bar in the lower-right, then tap the gear icon). Towards the top of the Settings page, there will be an “Internet connection” section. If you are using WiFi, tap on the “Wi-Fi network” item, then tap on the WiFi network that you are using. That should bring up a three-tab dialog with details about this network connection. The middle tab — Network — will show your IP address. Make note of this.

Configure Your Development Machine

UPDATE 2016-07-19: The process described in this section is no longer needed.

On your computer that you use for Android development, switch to some likely directory, then run the following command from a terminal window:

curl -s "https://chromium.googlesource.com/chromiumos/chromite/+/master/contrib/setup_adb?format=TEXT" | base64 --decode > chrome-adb.sh

This will download a bash script named chrome-adb.sh. Open it in your favorite text editor and confirm that you are comfortable with what it is doing. Or, Windows users might use the script as the basis for working out how to configure their SSH client and perform similar steps.

If you are comfortable with the script, ping your Chrome OS device (to confirm that you can reach it), then run the script:

ping <IP>
bash chrome-adb.sh <IP> <HOST>

Replace <IP> with the IP address of your Chrome OS machine that you determined previously. Replace <HOST> with the name that you want to use to identify this Chrome OS device in the future. This value only appears to be used inside of your SSH client configuration (~/.ssh/config) and is not used elsewhere.

If everything works, this should emit the following output, or something like it:

INFO: SSH connectivity established.
SELinux: Loaded file_contexts contexts from /file_contexts.
INFO: ADB set up complete.

Connect to Chrome OS for Development

When you want to develop using the Chrome OS device as the target, execute the following command:

adb connect <IP>:22

where <IP> is the same IP address that you used previously. Note that the official docs drop off the connect part, which does not work.

At this point, you should get the standard Android debugging authorization dialog, after which adb devices should show your connection, and you should be able to run apps on the Chrome OS device akin to how you do so for locally-connected devices, emulators, etc.

UPDATE 2016-07-19: If you used the instructions shown earlier in the previous section, adb access to your device may no longer work. If so, try turning off, then on, the Developer Options, via the switch in the action bar of the Developer Options screen. Then, try reconnecting via adb connect.

Jul 08, 2016


Older Posts