Monday, December 19, 2011

Android 4.0 ADB Backup / Restore

Android 4.0 ADB Backup/Restore
I switch phones quite a bit and the cloud is immensely useful for that, almost all of my #Android apps restore and most of the data is up there, even my wifi settings and wallpaper get reinstalled. But games are still lagging behind on this, they rarely keep their settings in the cloud or give a backup/restore option.

I really didn't want to lose my 'World of Goo' progress so I've just used adb backup/restore to pull it off one ICS device and push it onto another. Worked a treat.

The command lines I used:
> adb backup -f worldofgoo.bak com.twodboy.worldofgoofull
and a little dialog appears on the phone screen to confirm the backup and offer the chance to enter a password to protect.

> adb restore worldofgoo.bak
and another little dialog appears to confirm the restore

et voila, done. Other options on adb backup allow for full user data backups (-all), just type adb to see all options.


adb backup [-f ] [-apk|-noapk] [-shared|-noshared] [-all] [-system|-nosystem] []
- write an archive of the device's data to .
If no -f option is supplied then the data is written
to "backup.ab" in the current directory.
(-apk|-noapk enable/disable backup of the .apks themselves
in the archive; the default is noapk.)
(-shared|-noshared enable/disable backup of the device's
shared storage / SD card contents; the default is noshared.)
(-all means to back up all installed applications)
(-system|-nosystem toggles whether -all automatically includes
system applications; the default is to include system apps)
( is the list of applications to be backed up. If
the -all or -shared flags are passed, then the package
list is optional. Applications explicitly given on the
command line will be included even if -nosystem would
ordinarily cause them to be omitted.)

adb restore - restore device contents from the backup archive

Saturday, July 23, 2011

ViewPager example from PAUG

During a recent session at the Paris Android User Group (hi PAUG!) we did a live coding of a ViewPager example, it took around 5 minutes. What is a ViewPager? It is a tasty new class smothered in awesome sauce on a bed of rocking adapters, seriously I think I may use at least one in every Android app I make from now on. It was released as part of the updated Compatibility Package.

White on green was a great choice, right? very.... visible.

If you search for 'android view pager' you'll see many questions on how to implement smooth, finger tracking, horizontal view paging in Android, so it seems appropriate the solution is called ViewPager. ViewPager was launched at the end of last week as part of the updated Compatibility package and supports Android 1.6+.

Some of you may have been aware of the Workspace example open sourced with the I/O Sched app. An important difference between ViewPager and Workspace is that ViewPager pulls its views from an adapter, so like with a ListView as the items are slid off the screen they can be recycled and/or brought back in on the right side of the screen. The sample code for ViewPager shows this being done with a FragmentPagerAdapter, where each view is a fragment, giving you an amazing amount of control over your application.

In this example we are just sliding TextViews on and off the screen, here is the complete guide:

1) Download the update from Android SDK & AVD manager: Available Packages -> Android Repository -> Android Compatibility Package, revision 3. It will be installed in \extras\android\compatibility\v4

2) Create a new Android Project (I'm using Eclipse) and include the library. Properties -> Java Build Path -> Libraries -> Add External JARs -> android-support-v4.jar, it is in the install directory.
Update: As Thomas says if you're using the latest ADT you can now just right-click on your project -> Android Tools -> Add Compatibility Library

3) Your should now be able to use ViewPager in your Activity

4) If you use ViewPager in an xml layout, be sure to use the full reference, e.g.

<android.support.v4.view.ViewPager
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/awesomepager"/>


5) Create a PagerAdapter to serve up your Views to the ViewPager. The key methods to implement are getCount(), instantiateItem(), destroyItem() and isViewFromObject() here are my implementations along with some JavaDoc from the source.

Note: It is up to the developer to add the views they are creating in instantiateItem() to the collection being passed in. The converse applies to destroyItem(), you must remove the item from the collection. The collection in this example is the ViewPager that is using the PagerAdapter.

The complete project source is at http://code.google.com/p/viewpagerexample/

A more professional and complete example can be found in the Compatibility Package samples (in the install directory), where a FragmentPagerAdapter implementation is provided. Using fragments inside a ViewPager can provide much better structure to an application as each view has its own FragmentActivity.

Tuesday, June 21, 2011

Supporting Honeycomb pt2: Updating the Ultimate Stopwatch

For most developers, taking advantage of the features of Honeycomb is also going to involve ensuring their app runs on tablets. It is one thing to do this right from the inception of an app or game, but often a much harder task to upgrade an already complete project to look great on larger screens.

If your app has multiple views then you can utilise fragments to show more than one of them at the same time. If not then you can think about any other data or views that may be able to augment it, or possibly increase the size of some elements.

In the case of the Ultimate Stopwatch the counting digits clearly need to be larger, then the remaining screen space can be used to include an easier to access list of lap times and split times. I mocked up some wire frames and settled on the following design.


So how do you make this magic happen? Well, as the Ultimate Stopwatch uses a SurfaceView and I spent so long getting the small screen UI right, I didn't really want to mess with it, so I'm going to leave it alone and just add new layouts for x-large devices. For many apps, especially those using standard layouts, it is less of an issue and the Android Compatibility package is the best option for a consistent application. I am however going to use fragments for the new layouts, to give me the best control over the larger screen whilst keeping my class files smaller. I'll have a fragment for the animated stopwatch view, one for the counter digits and one for the lap times.

1. In your project properties set the Android Build Target to 11

2. Tell Android that your app is optimised for Honeycomb by updating the androidmanifest.xml by adding <uses-sdk android:targetSdkVersion="11" /> as per my last post, which also shows how to enable hardware acceleration for good measure.

3. To totally segment my previous code I created a new Activity which decides which version of the app to launch based on OS version and screen size, not forgetting to update the AndroidManifest.xml.

4. I've done custom layouts for both landscape and portrait to give optimal experiences. As I'd used fragments it made the portrait view much easier, it only took a couple of minutes.

5. Another thing to remember is that your menu items will now appear in the Action Bar. It is good practice to let Android know which items it can hide under the overflow button if necessary by appending android:showAsAction="ifRoom" in to the item in your Menu.xml.

6. When building the layouts and activities, be mindful of the fragment lifecycle, making sure to inflate your views in the onCreateView() method.

7. To add a little more Honeycomb goodness I also used ObjectAnimator to do a 180 degree animation on the lap times fragment when switching to Countdown Mode and back again, this hides the times and informs the user of the mode the app is in. I also freshened up the Countdown time select dialog with the new NumberPicker.


Launching this update was also a great opportunity to refresh the Android Market listing, adding new screenshots, featured image and descriptions.

The full source of the Ultimate Stopwatch & Timer is available at http://code.google.com/p/android-ultimatestopwatch/

For those of you who want to know how USW looked in landscape on a tablet before this overhaul, prepare yourselves:


Follow me on twitter for further Android related updates.

Saturday, May 21, 2011

Supporting Honeycomb pt1: targetSdkVersion=11



Since the day I started at Google I've been trying to find the time to update all of my Android apps to support Honeycomb. However, I'm into my 3rd month and various distractions, like the awesome I/O, have meant that I haven't touched any of them.

So, here we go, part 1, Honeycomb support for 3 of the 9 apps I have live in the Android Market. I'll confess now that I've chosen the easiest 3, in fact they are all so easy that there is just one line to change. The apps are Auto Bright, Dimmer (Night Mode) and The Cleaner.

These apps all run in compatibility mode on Honeycomb, which means it shows the 'menu button' in the system bar to the right of the previous tasks, home and back buttons. To sort this out all you have to do is update the AndroidManifest to ensure it includes:

<uses-sdk android:targetSdkVersion="11"/>

Now that extra compatibility icon will vanish and technically these apps will support Honeycomb, perfect!

For the sake of completeness I've taken this opportunity to also furnish 'The Cleaner' with support for Honeycomb's Lights out Mode. This mode reduces the system bar elements on a Honeycomb device to small dots, making them less distracting. It is usually used for immersive experiences in games, video players, image galleries, etc...

To set Lights Out Mode on a view, just set the system UI visibility to STATUS_BAR_HIDDEN.

v.setSystemUiVisibility(View.STATUS_BAR_HIDDEN);


--- Updated 24/05/2011 ---
As WarGoth points out there is no need to use reflection to maintain backwards compatibility, simply wrapping the code in an android.os.Build.VERSION.SDK_INT>=android.os.Build.VERSION_CODES.HONEYCOMB check is sufficient. Clarification in the comments from Weeds that this only applies to Android 2.0+, the class loader would throw a java.lang.VerifyError on 1.5/1.6.

if(android.os.Build.VERSION.SDK_INT>=android.os.Build.VERSION_CODES.HONEYCOMB) {
    v.setSystemUiVisibility(View.STATUS_BAR_HIDDEN);
}

--- End ---

I did it slightly differently by using reflection to maintain compatibility with older versions of Android without duplicating classes:

Class classView = Class.forName("android.view.View");
Method methodSetSystemUIVisibility = classView.getDeclaredMethod("setSystemUiVisibility", int.class);
methodSetSystemUIVisibility.invoke(v,1);



The full source of these apps is available on Google Code

Part 2 of this series will take on converting one of my more complicated applications.