"; */ ?>

android


16
Jan 13

Backup and Reset Nexus 4: Cracked and Locked Screen

Story of a Flaw


Nexus 4 has an invisible design flaw: the back side of a phone is just glass, which, while looks pretty to some, makes it slide down and fall from pretty much any surface. Another unfortunate caveat is the curved unprotected glass on the front. If the phone falls down, it’ll most likely crack…

And here I present a 20 day old brand new Nexus 4:

nexus screen

After the unfortunate flight down, the screen is done and stopped responding to any tapping/touching. In addition the screen is locked with a gesture pattern. The phone is not rooted and with a locked bootloader: exactly how it comes from Google.

Android iTunes


At this point I need to back it up and factory reset the phone in order to ship it safely for repairs. Since Google is moving towards Apple’s “lock down and control” system design, the phone can’t be just plugged in via USB to back up its files (e.g. via USB Mass Storage), now days there is MTP. As Google puts it:

“We did it because we wanted to be able to merge the “public shared storage” (i.e. for music and photos) with the internal private app storage.”

Yea, ok, while it does have a technical merit, it really brings user experience closer to the “iTunes level”, not as bad yet, but quite close. In any case, since the Nexus 4 screen is locked, Android iTunes complains that until that screen is unlocked it won’t be showing any files. Yea, thanks for the security Apple.. I mean Google.

Unlocking the Screen


There is a great tool written by Alexanre which allows to control an Android device remotely from Mac/PC. In other words a regular keyboard/mouse could be used to control the Android device. The tool is called Android Screencast. The only caveat, the phone needs to be rooted in order to be controlled by this tool. I got to see the phone’s screen on my Mac:

android screencast

In order to make Mac keyboard to work I need to do “chmod 777 /data/dalvik-cache” as root (e.g. “su”), but the phone is not rooted, bummer. The tool is great though.

Btw, if the phone was rooted, I could simply do: “adb shell rm /data/system/gesture.key” to get rid of the screen lock.

Backing Up What’s Dear


One thing I knew I could do for sure is to backup the “sdcard”. I knew this because of two things: I have “USB Debugging” on, which means I can use adb, and “sdcard” is not owned by root, which means it can be “pulled”/”read” by adb. Hence the first step is clear:

./adb pull /sdcard/ /destination

At this point all the pictures / videos / music, etc.. are backed up. Now I need to backup my SMS, contacts, etc.. Information that lives in Android “databases”. For example contacts usually live here “/data/data/com.android.providers.contacts/databases”. Which can’t be simply “pulled” as pitures, since they are protected, and hence cannot be read by adb directly.

Another tool to the rescue: Moborobo. The only caveat it is a Windows tool, and in order to install it I needed to power up my virtual box. The tool is pretty neat and quite powerful. Unfortunately all it could backup for me was SMS, everything else failed, but it is one step further nevertheless + I have most of my contacts gmail synced. Apps would be nice to backup, but they can be reinstalled manually later on.

Waving Goodbye or The Factory Reset


Now the interesting bit: the factory reset. It was not really straightforward, since most of googled instructions either talk about doing it from within a phone by tapping through settings, which is not an option in this case, or by using Home / Back buttons which are also a part of the screen that does not work. But after some minutes “the way” revealed itself.

Firstly the phone needs to be rebooted in “Recovery mode”, which can be done through fastboot, in case “USB Debugging” is not enabled:

Disconnect the phone. Power it down (by holding the Power button). Reboot into fastboot mode by holding the Volume Down button and Power:

fastboot start

The “Recovery Mode” is two Volume button clicks away (confirm with a Power button once the mode is selected):

fastboot recovery

In case “USB Debugging” is enabled, the easier way to get to this step would be via adb:

./adb -d reboot recovery

Which will boot into:

recovery mode

From here press and hold Power button and then press Volume Up, which will get into:

android factory reset

Now all that needs to be done is to mentally wave good bye to all the data and confirm the reset:

confirm factory reset

And the Award Goes To…


All the pictures are courtesy of my good old Nexus S, which has fell down countless number of times over the years and have a couple of scratches on the back. Yes, “they” knew how to build phones for real in the good old days..


5
Apr 11

Mobile Devices Visiting Dotkam

Looking at mobile stats I can conclude that Android users are most interested in my content ( number of users vs average 21 seconds on the page ), where iPhone users are most curious ( max number of visits ), and of course thank you the lonely “Sony” user who spent 4 and a half minutes here :)

Moible Devices Visiting Dotkam

But overall most of my daily visits ( currently about 1300 ) are coming from other places. Need to work on that..


10
Jan 11

Android Development: Best Practices

Cyanogen LogoI got introduced to an Android application development during Philly ETE conference by listening to “A guided tour of the Android ETE mobile application” talk, where Andrew Oswald ( a Java Architect from Chariot Solutions ) talked about creating an Android app for the conference, which was a cool introduction to “what it takes” to write one of those apps from scratch. I am looking forward to more talks around mobile development this year at Philly ETE conference as well.

Meanwhile I rely mostly on Android’s Developer Guide whenever I seek answers to my questions or/and best practices. Here are my notes on such practices I picked up listening to “A Beginner’s Guide to Android” Google I/O 2010 talk:

1. Avoid creating objects unless you really need to, try reusing Android’s API instead. Creating an object in a “desktop” world is relatively cheap, however in such a resource constraint environment as a mobile phone, it will drastically impact the performance.. not in a good way.

2. In order to avoid friendly “Force Close” popups from your applications, use Android’s “AsyncTask” which will allow to execute a certain activity in background:

 private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
     protected Long doInBackground(URL... urls) {
         int count = urls.length;
         long totalSize = 0;
         for (int i = 0; i < count; i++) {
             totalSize += Downloader.downloadFile(urls[i]);
             publishProgress((int) ((i / (float) count) * 100));
         }
         return totalSize;
     }
 
     protected void onProgressUpdate(Integer... progress) {
         setProgressPercent(progress[0]);
     }
 
     protected void onPostExecute(Long result) {
         showDialog("Downloaded " + result + " bytes");
     }
 }

read more about AsyncTask in Android Developer Guide

3. Think about what an absolute minimum amount of updates / syncs you can do, and stick to this minimum. This will greatly improve battery life as well resource usage by the application.

4. Only use a WakeLock when you need one with as minimum level as possible: PARTIAL_WAKE_LOCK, SCREEN_DIM_WAKE_LOCK, FULL_WAKE_LOCK. Here is more about PowerManager

5. Respect a “Back” button: make sure it actually brings user back to a previous state rather than to another state of the application’s flow.

6. Always check whether “data transfer” is enabled on a device, before attempting to transfer data:

ConnectivityManager cm= ( ConnectivityManager ) getSystemService( Context.CONNECTIVITY_SERVICE );
boolean backgroundEnabled = cm.getBackgroundDataSetings();

this is especially important while roaming, when that “twitter update” can cost user a lot. So do respect user settings.

7. Don’t use undocumented ( not officially supported ) APIs => Next Android release your app is going to break.

8. Respect and use an application lifecycle:

void onCreate(Bundle savedInstanceState)
void onStart()
void onRestart()
void onResume()
void onPause()
void onStop()
void onDestroy()

read more about Android Application Lifecycle

9. Externalize resources: localization / optimized layouts / strings / array of strings / etc.. Android compiles them into a list of internal resources by assigning an integer ID to each of them, hence making it “cheaper” at runtime, and easier to change => since they are defined in a single location. Here is an example of auto generated ( random layout ) resources:

    public static final class layout {
        public static final int about_details=0x7f030000;
        public static final int all_upcoming_filtered_buttons=0x7f030001;
        public static final int details_text=0x7f030002;
        public static final int details_webview=0x7f030003;
        public static final int faq_details=0x7f030004;
        public static final int faq_details_row=0x7f030005;
        public static final int main_tabs=0x7f030006;
        public static final int map_details=0x7f030007;
 
        //.... the above is auto generated

10. Think of hiring or delegating UI to people who are designers. Beauty is important

11. Be resolution independent. Check out “layoutopt” and “hierarchyviewer” that come with Android SDK under “tools”. They help analyzing and optimizing layouts.

12. Consider using a “non sticky” services when appropriate:

@Override
public int onStartCommand( Intent intent, int flags, int startId ) {
 
     handleCommand( intent );
 
    // If this Service gets killed, don't restart it
    return START_NOT_STICKY;
}

this is useful for services that are going to be executed on a regular basis. So when you are pulling for updates every 10, 15 minutes, it is ok if one of such updates is missed in favor to a healthy resource management

13. Do not use foreground services unless you absolutely need to.

And if you do use foreground services, use an ongoing notification ( which, starting from Android 2.0, used automatically, if a service is started as a foreground one, but just to keep something in mind to be used for older OS versions )

14. Kill your own services via stopSelf():

@Override
prtoceted void onPostExecute( Void result ) {
    stopSelf();
}

15. Use Intents and Intent Filters to Leverage Other Apps

16. Prefer Alarms and Intent Receivers to Services

Now, with this in mind, go and Rock That Android Space!


10
Jan 11

Android: Prefer Alarms and Intent Receivers to Services

Cyanogen LogoContinue learning from “A Beginner’s Guide to Android” Google I/O 2010 talk, here is an example on how to use Intent Filter + Intent Receiver + Alarm to implement “schedule to execute every so often” functionality.

In Android, Alarms let you set an event to happen either in the future or on an ongoing basis in the future.

Let’s say we have a listener ( extends BroadcastReceiver ) that would execute a certain action ( MyService ):

public class MyReceiver extends BroadcastReceiver {
 
    @Override
    public void onReceive( Context context, Intent intent ) {
 
        Intent myIntent = new Intent( context, MyService.class );
        context.startService( myIntent );
    }
}

Now let’s connect/map this listener/receiver to a “REFRESH_THIS” Intent by creating an intent filter in a manifest file:

<receiver android:name="MyReceiver">
    <intent-filter>
        <action android:name="REFRESH_THIS"/>
    </intent-filter>
</receiver>

So whenever a system broadcasts a “REFRESH_THIS” intent, MyReceiver is going to spawn up and a “context.startService( myIntent )” is going to be executed.

Now in order to schedule “REFRESH_THIS” intent to be broadcasted, we would use an AlarmManager:

String alarm = Context.ALARM_SERVICE;
AlarmManager am = ( AlarmManager ) getSystemService( alarm );
 
Intent intent = new Intent( "REFRESH_THIS" );
PendingIntent pi = PendingIntent.getBroadcast( this, 0, intent, 0 );
 
int type = AlarmManager.ELAPSED_REALTIME_WAKEUP;
long interval = AlarmManager.INTERVAL_FIFTEEN_MINUTES;
long triggerTime = SystemClock.elapsedRealtime() + interval;
 
am.setRepeating( type, triggerTime, interval, pi );

The above Alarm will wake up a device every 15 minutes and execute MyReceiver’s onReceive() method. The cool thing is that even if your application is killed, this alarm will continue to run without your application running on the background consuming resources.

One thing to note..

Prefer Inexact Alarms …so OS can optimize when the alarm goes off

Why!?.. Let’s say there are 15 applications that set 15 alarms, which take a minute each to execute, and are all scheduled to be executed with a 15 minute interval => Potentially ( depending on the time they’ve been scheduled at ) they can end up executing every minute ( one after another ) resulting in Android device to be constantly on which is a dramatic impact at the resource usage.

“Inexact Alarms” would let OS “phase shift” these alarms to execute at the same time, rather than being arbitrary distributed depending on the time they were scheduled at. This allows OS to optimize and allocate resources in more intelligent fashion. So if you have something that needs to happen regularly, but does not need to happen at exact time, use “Inexact Alarms”.

In the above “alarm example”, in order to use Inexact Alarm change this line:

am.setRepeating( type, triggerTime, interval, pi );

to

am.setInexactRepeating( type, triggerTime, interval, pi );

Now the alarm will rely on the OS to optimize its execution time.


10
Jan 11

Android: Using Intents and Intent Filters to Leverage Other Apps

Cyanogen LogoUsing “Intent Filters” is a very powerful way to connect different applications together which allows greater reuse and makes a user experience transparent to the fact that more than one application is used to achieve a certain task.

Here is an example that is discussed in “A Beginner’s Guide to Android” Google I/O 2010 talk.

Let’s say there is an application that finds hotels and would like to use another application to book it. For that it creates an implicit “Intent” where it says: “hey android, I intent to book this hotel, please find an application that is capable of booking it, and pass the data to do the booking”:

String action = "com.hotelapp.ACTION_BOOK";
String hotel = "hotel://name/" + selectedHotelName;
Uri data = Uri.parse( hotel );
 
Intent bookingIntent = new Intent( action, data );
 
startActivityForResult( bookingIntent );

Now let’s say there is such a booking app installed on a device. Then, in its manifest, it will announce itself through the “intent-filter”, as an application capable to perform this action, e.g. “com.hotelapp.ACTION_BOOK”, to get the data from another app and book a hotel:

<activity android:name="Booking" android:label="Book">
    <intent-filter>
        <action android:name="com.hotelapp.ACTION_BOOK"/>
        <activity android:scheme="hotel"
                      android:host="name"/>
    </intent-filter>
</activity>

Within the “Activity” of a booking app, you can then “getIntent()” to find the one that was used, get the action along with the data and do the booking:

@Override
public void onCreate( Bundle savedInstanceState ) {
 
    super.onCreate( savedInstance );
    setContentView( r.layout.main );
 
    Intent intent = getIntent();
 
    String action = intent.getAction();
    Uri data = intent.getData();
 
    String hotelName = data.getPath();
 
    // Providing booking functionality
    // ... ...
 
    setResult( RESULT_OK, null );
    finish();
}

THE TAKE AWAY: Think about exposing functionality ( can be full of partial workflows ) of your apps in order for other developers / apps to use. At the same time check what is already exposed for you to leverage from other developers / apps.

P.S. Read more about Intents and Intent Filters