Friday, February 25, 2011

Getting gingerbread on Nexus One

If you are an impatient person like me (when it comes to gadgets !), with a nexus one but no gingerbread yet, you might definitely be aware that there are official versions of Gingerbread 2.3.3 floating out there.

I faced some problems getting gingerbread to my N1.

<noobie_skip>
I had CM7 on my nexus one which is gingerbread but I wanted to get to a stock version (why ? my choice :D and for some reason gapps wasn't able to install the GMail app on CM7 !) Noobies, you are supposed to ignore this block
</noobie_skip>

So, I was able to get back to stock version 2.2 using instructions here. From then on my impatience triggered ignorance and things started to go foo bar !

I started getting a very strange error. Something like :

assert failed: file_getprop(“/system/build.prop”, “ro.build.fingerprint”) == “google/passion/passion/mahimahi:2.2.2/FRG83G/91102:user/release-keys” ll file_getprop(“/system/build.prop”, “ro.build.fingerprint”) == “google/passion/passion/mahimahi:2.3.3/GRI40/102588:user/release-keys”
E:Error in /sdcard/update.zip 
(status 7)
Installation aborted



Eventually, I figured out that I was trying to directly jump from FRG33 to GRI40 (This is Gingerbread 2.3.3) ! All the zip files floating out there are incremental - they only take you one level up !

So, you may want to check the file name. For e.g. :
2854b06b22b9.signed-passion-FRG83G-from-FRG83D.2854b06b.zip

This file will take you from FRG83D to FRG83G. You will need to go on flashing each one. So find all the zip files that will take you from your version up to GRI40
For me it was from FRG83 -> FRG83D, then FRG83D -> FRG83G and finally FRG83G -> GRI40

Wooohooooo. Gingerbread it is !

Hope this helps someone !

Note: Unfortunately I cannot provide you with all the zip file paths. Since the links may be broken or get broken over time and I do not wish to keep on updating those. Use our friend Google to get to the files ! :)

Thursday, February 17, 2011

Android : Passing data between main thread and worker threads.

There may be situations where you want to spawn a thread from your Activity or Service to handle long running (and may be blocking) tasks. In such cases, its sometimes necessary to pass data back and forth between the main thread and the worker thread(s). E.g. if the worker thread finishes a task and returns the result to the main activity to display the results OR you want to keep a worker thread around and ask it to switch between tasks depending on some message you pass to it.

In the past, I faced some problems understanding these concepts associated with different classes in android.os like the Handler, Looper, HandlerThread etc...

I'll try to explain these concepts in a simple language. Probably most of these explanations are from the developer documentation, but I thought consolidating these at one place may help to get a good picture.

Ok. So, when an application runs, it runs in a Main thread called as the UI thread. Any other thread can be created using the standard java.lang.Thread class. As I said in a typical situation you will spawn a thread, may be pass some data to it OR the thread may pass back some data to the Main thread from time to time as well as when its done executing.

Let us consider the task where we need to send data to a worker thread. So first, we create a worker thread.

STEP 1: Create a worker thread

class MyThread extends Thread {
    @Override
    public void run(){
    }
}

In our main thread...

MyThread mThread = new MyThread();
mThread.start();

When you have to pass any messages to a thread or get messages from a thread, the receiving thread needs a MessageQueue. By default, a thread created by using the java.lang.Thread class will not have a MessageQueue associated with it. Its just a plain old thread as in the Fig. 1 (Yes, I know. What an innovative diagram !! :D ).




Now, we need to attach a MessageQueue to our thread. The Looper class provides the method prepare() to create a message queue for a thread. We need to call this method from the receiving thread's run method.


STEP 2: Call the Looper methods


class MyThread extends Thread {
    @Override
    public void run(){
           Looper.prepare();
           Looper.loop();
    }
}



As you see, there is one more Looper method called in the code. This loop() method will start running the message loop for the current thread. In simple terms, it will start looking at the MessageQueue and processing the messages. This is how I interpret the Looper as in Fig. 2.



But, who sends the messages to the MessageQueue and how are these processed ? There is a class called the Handler. The Hander allows us to send and process Messages (as well as Runnable Objects) associated with the thread's MessageQueue. So, we need to create a Handler. It is important to note that the Handler is associated with the thread that creates it ! The Handler provides methods to handle (receive) Messages as well as send and schedule messages. For details, please refer to documentation.



STEP 3: Create a Handler to receive the Messages

class MyThread extends Thread {
    public Handler mHandler;

    @Override
    public void run(){
           Looper.prepare();

           mHandler = new Handler() {
                   public void handleMessage(Message msg) {
                       // Act on the message
                   }
           };
           Looper.loop();
    }
}

If you notice, this code is the same that is listed on the Looper documentation page here.  Few things to mention here are. The Handler is created in this thread, hence it is associated with the default Looper (read MessageQueue) in the current thread. There are constructors for the Handler that allow us to specify the Looper (again, read MessageQueue). This allows us to write a cleaner code by writing the Handler class separately and passing on a Looper (again, again, read MessageQueue) when the Handler is created. I'll get to this in a while. But as I have insisted, it is worth noting that whenever the developer documentation refers to a Looper, you can assume they are talking about a queue. I'm really not sure why they have surfaced the Looper class. It creates more confusion (at least for me). Also, when dealing with passing the messages, with this mechanism, we really need not care of the MessageQueue call. That is the reason I haven't linked it to the documentation. Anyways... things are what they are ! For me, I like to interpret this whole mechanism as depicted in Fig. 3.


Let me know if you like PAT or your way of viewing it !

So, now any other thread having the reference to mHandler will be able to call the send or post methods of the Handler class to send a Message (or a runnable object) to our thread. The code for sending message will look like:

Message msg = Message.obtain();
msg.obj =  // Some Arbitrary object
mHandler.sendMessage(msg);

Pretty simple yeah ! Btw, there are various methods to set/get data for the Message object which can be found in the developer documentation for the Message class.

Summary of Steps :
1. Create a Handler in the receiving thread [If it is the main thread, create one in the main thread]. By default the handler will be associated with the default queue (Looper).
2. So, if the receiving thread is created by using java.lang.Thread, then we need to call the Looper.prepare() and Looper.loop() in order to set up the message queue for the thread.
3.  In the sending thread, prepare a message object (or a Runnable object)
4. Get a reference to the Handler in the sending thread and call the send/post methods on it to send a message.

HandlerThread:
Since by default java.lang.Thread doesn't contain a message queue (Looper), Android provides a class called as the HandlerThread which already contains a message queue. The only difference in using the HandlerThread class over the method described above is that you need not call the Looper.* methods.

On creation of a HandlerThread, Android will create a thread containing the looper. So, in the main thread the code will look like:

HandlerThread myThread = new HandlerThread("Worker Thread");  
myThread.start(); 

We separately create a Handler as follows:

class MyHandler extends Handler { 
    public MyHandler(Looper myLooper) { 
        super(myLooper);
    }
    public void handleMessage(Message msg) { 
    }
} 

Now in the main thread, we get the looper for the HandlerThread and pass it when we create the Handler as follows:

Looper mLooper = myThread.getLooper(); 
MyHandler mHandler = new MyHandler(mLooper); 

Whenever we want to send a message from the main thread, we do it in a similar fashion.

Message msg = mHandler.obtainMessage(); 


msg.obj =  // Some Arbitrary object
mHandler.sendMessage(msg); 


I like to visualize this as shown below in Fig. 4 where we write the Handler separately and then pass a looper to it on its creation.





Friday, February 11, 2011

Nokia chooses WP7 over Android

Going through the news reader this morning, I learnt that Nokia, one of the greatest manufacturers of mobile devices has chosen WP7 over Android. Not that I hate WP7 (as of yet, since I haven't tried it), but I would have loved to have my favorite Android on Nokia devices.
Being from India, where Nokia phones are seen as prime devices (at least till recently), and having used few of Nokia phones before, I was eagerly waiting to hear Nokia adopt Android.
Now, it will be an interesting market to see. I'm not much concerned how this affects WP7 (sorry Microsoft, not a big fan), though for the time being it will definitely be a breather for them. I'm worried about the future of Nokia. But still I hope that somewhere in future, Nokia will shake hands with the green robot !

BTW, did I hear somewhere that Nokia CEO Stephen Elop is a former Microsoft employee ! Ahem ahem ...

Thursday, February 10, 2011

Android development cheatsheet


Here is a list of commands I find useful when developing applications. Do add to comments any commands that you use and find useful. I'll update accordingly. Also, I would be interested if anyone has any android UI related cheat sheets :)


android
-    Create/delete/view Android Virtual Devices
-    Create/update projects
-    Update the SDK with new platforms, addons and docs.

android list target
android list avd
android --help
android create avd –n <avd_name> -t <target_ID> -c <size>[K|M]
android create project --target <target_ID> --name <prjname> --path <where>
                       --activity <activityname> --package <package_namespace>

android update project [--name|-n] <prjname> [--target|-t] <target_ID>
                       [--path|-p] <thepath_to_prj>

android create lib-project --target <target_ID> --name <prjname> --path <where> 
                           --package <package_namespace>

adb
adb [-d|-e] install <path_to_your_bin>.apk
adb push <local> <remote>    - copy file/dir to device
adb pull <remote> [<local>]  - copy file/dir from device
e.g : adb push foo.txt /sdcard/foo.txt
adb shell
adb devices
adb –s emulator-5554 shell

#sqlite3 /data/data/com.example.google.rss.rssexample/databases/rssitems.db
sqlite>.exit
adb logcat [<option> … [<filter-spec>] …
[V – Verbose, D – Debug, I – Info, W – Warning, E – Error, F – Fatal, S – Silent]

adb logcat <tag1>:<priority1> …..
e.g. : adb logcat ActivityMgr:I MyApp:D *:S

others 
mksdcard [-l label] <size>[K|M] <file>
emulator –avd <avd_name> –sdcard <file>
telnet localhost <emulator-port>


#From inside telnet:


- sms send <sender phone number> <text message>
- geo fix <longitude> <latitude> [<altitude>]



Thursday, February 3, 2011

Android 3.0 encryption : Initial Thoughts


A little background:

Few days back Google released a preview version for the Android 3.0 SDK code named HoneyComb. For quite some time now, the enterprise has been asking for device management features for the Android Platform. Blackberry has these features integrated into their solution. Recently Apple also embraced the initiative and supported enterprise features in their iOS 4.

The obvious reason for these trends is due to the customer demands. Earlier, enterprises used to provide employees with smart phones (read blackberries) to access corporate resources. Blackberry was the only solution providing secure corporate access, encryption and security policies. However, with iPhone getting popular, the momentum shifted in last couple of years. Now, instead companies providing the smartphones, employees demand the type of phone they want and companies' IT departments have the daunting task to support these smartphones. These demands lead Apple to add device management support to iOS.

Android seems to be a very different game. It is gaining a lot of popularity these days. The open nature of it has enabled the platform to be adopted by a huge number of manufactures resulting in a burst of Android powered devices. In the corporate world, employees are asking for supporting Android devices too.

Some initial thoughts (technical):

In Froyo (Android 2.2), google introduced some device admin APIs. Using these, some basic device management functionalities could be achieved. (Device lock, set password, device wipe). However, one primary concern for corporates is Encryption !

Just few days back, google released a preview version of honeycomb SDK. This is my interpretation of the Encryption API found in HoneyComb preview SDK. I'll update the blog or write a new post when I learn more on this.

As a device admin, an application first has to check weather Encryption is supported by the tablet (in hardware). I don't think there is software encryption algorithm in honeycomb. I'll be surprised to see a software encryption (it will defenitely slow down the tablet in my opinion - but who knows, there are always surprises in the world !).

So, assuming there is hardware support, the admin app can test it (using the getStorageEncryptionStatus) and then call the start encryption method (setStorageEncryption). This will trigger the hardware encryption process. According the honeycomb preview api documentation, this will encrypt only the application storage area (i.e. all the internal memory - my guess) and may not the external memory (sd card).

SDK documentation for the setStorageEncryption says:

<snip>
This policy controls encryption of the secure (application data) storage area. Data written to other areas (e.g. the directory returned by getExternalStorageDirectory() may or may not be encrypted.
</snip>

I came across an engaget article that says that the motorola xoom has an option to encrypt the entire tablet. This is a bit incomplete and misleading. Does this mean that Motorola has extended honeycomb to encrypt the SD card as well ? Who knows, only time will tell. I'm curious to know what kind of encryption is supported - hardware/software. Will it (and how much) affect the performance ? and will this initiative please corporates and will they embrace Android devices ?

Time will tell and if it tells me first, I'll update the blog :) Do leave any comments if you find any information or corrections.


Thursday, October 21, 2010

Android C2DM Messaging (Server Push for Android Phones)

UPDATE: Added diagrams to get concepts clear.

From monday, I have been fighting to get the C2DM (Cloud to Device Messaging) working. And with somewhat frustration and a lot of help from some good people out there, I got it working ! :)

In this article I describe my findings and try to explain the concepts in simple words and list out steps you need to do to get it working. For an example code I would suggest you take a look at Gabor's blog which is  this. Its really awesome.!

NOTE: Also, I would suggest you to take a look at the sample code provided by google. If I get time, I will also post some sample code (don't wait for me to do that :D). Also, just take a look at the classes in the google.android.c2dm package provided in the sample codes. No need to dig into the details, but I may talk about them later in this post.

So what is C2DM ? It is a server push mechanism provided by Google so that 3rd party applications can push messages to their applications on Android devices. Currently as of today, it is in beta, and if you are an enterprise, you will need to apply and have talks with Google before having your application out with a lot of users and lot of messages to push. However, for developers with a gmail account ID, the registration request should be pretty easily accepted and you will be "whitelisted".

Before digging into details, let us see what are the top level concepts and which components are involved. Basically there are 3 entities involved:
0. The Google C2DM service.
1. Your server application. I'll call it as the "FOOServer". This will send the message to the C2DM service which will forward it to the requested device.
2. The application on the device that receives the message. I'll simply call it DeviceApp.

So, no points to guess that C2DM acts as a middle man and does the message passing. How ? It uses the default google services on the Android phone. So the basic requirement for this whole thing to work is that there should be at least one logged-in Google account from the device.

Now, when you signup for the C2DM, you will be providing them with the following (only 2 relevant things are mentioned):
1. The Application Name. This is actually the package name that you will provide. It is very important to remember this, because this is the package name you will have to use for your DeviceApp and worst part is that in the whitelisted mail that you get from Google, this is not mentioned. I haven't found a way to look at our registered information. If anyone knows this, please comment and let me and other know. So, for the time being consider that the package name is "com.foo.test"

2. The second important thing on the registration form is the Role Account Email ID. Make sure that this email is not used on any device. I have found that the messaging will not work for that device. So, for our example lets say it is FOO@gmail.com

Just for fun, the following diagram depicts the above step.



So, till now, we have the email account ID which is FOO@gmail.com and the package name.

Who needs what
Ok, so how does each entity react to the C2DM and what IDs and credentials does it use ?


DeviceApp
The device app registers with the C2DM service. It tells the C2DM service that it would like to receive messages from FOOServer. In return it gets back a registration ID.
So,
DeviceApp -----[FOO@gmail.com]------> C2DM
C2DM  --------[registrationID]--------> DeviceApp


The first action is done via a registration Intent. If you see the C2DMessaging class you will get this. Here, the DeviceApp sends the FOO@gmail.com address specifying that it would like to receive messages from this account.
Next, You will need to extend the C2DMBaseReceiver and override the onRegistered and onUnregistered methods. So, the onRegistered method will be called when the C2DM server accepts the registration. In this method you will receive a registrationID. This is a very long alpha numeric string that identifies the device.

Now, the DeviceApp needs to convey back this registration ID to the FOOServer. It is recommended that at this point you also send some unique device identifier to keep track on the FOOServer. The reason is that Google may change these registrationIDs and may not be unique. If Google changes any IDs it will push the new ID to the DeviceApp which has to handle it in similar fashion.
So, if you choose say IMEI/MEID as the unique identifier, then,


DeviceApp -----[UniqueID, registrationID]------> FOOServer


Thats it ! The device is now registered and ready to receive any messages. The following diagram shows this registration work flow:


Registration Work Flow





FOOServer:
The FOOServer will store (or update) the registrationID received into its local database. So, eventually the server will have registrationIDs from all the devices the DeviceApp is on. To send a message to a particular device, the FOOServer needs to POST to the C2DM Service the following four three things:
1. The accountName which will be FOO@gmail.com (Update : Thank you @matest for pointing it out that this is not needed)
2. An authentication Token [explained below]
3. The registrationID of the device it wants to send the message.
4. The message itself ( I think the limit is 1024 charcters)


You can get the authentication token by providing the credentials for FOO@gmail.com. I used curl to get the token. In our case the command would be :


curl https://www.google.com/accounts/ClientLogin -d Email=FOO@gmail.com -d "Passwd=FooPassWord" -d accountType=GOOGLE -d source=FOOServer -d service=ac2dm


[note this command is taken from comments posted on this blog]


Getting the auth token




This should give you few very long string values one of which would start with "Auth=". This is the one you want. Even if I have used curl here, it is recommended that you get the token programmability, because even this token might change. If it changes, the new token would be returned as a response to the POST that we do to send the message.

Sending the message



I would like to thank Gabor Paller for writing a very good article on this and helping me with this process. Also, thanks to DavidMyton for his article. The comments below this article are pretty useful too. I also found this discussion on c2dm google group helpful.

I have written this in a hurry. So let me know of any "bugs" in the article and I'll fix those  !!
Thank you !

Friday, October 15, 2010

Using IntelliJ (or any IDE) with command line tools for developing Android projects

Recently I did some Blackberry development, and started using IntelliJ for that. I liked the concept of having the IDE separate from the build environment. There is some extra work involved but it is convenient if you need a command line interface may be to automate your builds.
Anyways jumping directly into the topic. I have here put together somethings you will need to do to use your choice of IDE and build using android command line tools. Since I have started liking to work with IntelliJ, I will also mention some IntelliJ specific tweaks.

So, clearly there are 2 parts here: The IDE set up and the build setup.
For build set up, we can just use the 'android' command to create the project. So, if we have a project in mind say TestProject, we'll create it using the command :

android create project --target 8 --name TestProject --path ./TestProject --activity TestActivity --package com.foo.Test

You can know the target by issuing the command :
android list target

I will not go deep into what are the targets and why you need them. You can find this information on the Android Developers Website.

The create project command will generate a directory structure which will contain bunch of directories and some configuration files and the build.xml required by ant.

Before you create/import the project in your IDE, issue the "ant debug" command on this generated directory structure. This will generate the R.java file which is the resource file which is needed for compiling along with your source files.

If you come from the Eclipse world, you know that there is a "workspace" in which there can be multiple "projects". Analogous to that, in IntelliJ, there is a "Project" in which there can be multiple "modules".

Talking in terms of IntelliJ, create an empty project (without any modules).
Now,
- Click File -> New Module
- In the Add Module dialog, see that "Create module from scratch" is selected. Click next
- In the Content Root field, browse to the root of this project. The name field will automatically be updated. Click Next
- It will mark the TestProject/src and the TestProject/gen directories as the source directories. This is what we want and this is why we ran the build process before creating the process. If you haven't run the build command before, it will only show the "src" directory. In that case, after you create the project, run the ant command and then come back to the module properties and mark the "gen" folder as a source folder. Doing this is important, or else it will never resolve the R.java references and is quite frustrating.
- Click Next and then Finish.

Now that we have added a new module, we'll need to add android libraries so that we can get intellicense !
- Right click on the module, go to Module Settings.
- Click on dependencies tab.
- Click Add -> Module Libraries
- Click Attach Jar Directories
- Select the specific android platform directory (that you used for creating the project with --target) For us that will be android-8 and will be located at ${ANDROID_SDK}/platforms/android-8
Select this path. Click OK twice. Click Apply.

You are all set !! But wait. There is still a trick pending !
Any time you change any of the resource files, the R.java will be outdated. No issues while building, but the IDE will start cribbing. The Eclipse plugin takes care of updating th R.java. For IntelliJ or other IDEs it might be irritating to see those unresolved references. Not just irritating to see, but some IDEs constantly bug with pop ups for unresolved references. A common mistake will be to import the generic "android.R" package ! In this case, the "R" reference will be resolved but won't find any of user defined resources.

So, each time when you add a resource, you'll need to build by issuing the ant command. But, many times the code is not complete and there is not point running the whole build. All we need is the command to generate the R.java file.

Simple, before writing any code, just run the ant command with the verbose output turned on. E.g. ant -v debug

In the -pre-build target, you will find the command for generating the R.java file. An example is as follows :

-pre-build:

-resource-src:
[echo] Generating R.java / Manifest.java from the resources...
[null] Current OS is Windows 7
[null] Executing 'C:\android-sdk_r07-windows\android-sdk-windows\platforms\android-8\tools\aapt.exe' with arguments:
[null] 'package'
[null] '-f'
[null] '-m'
[null] '-M'
[null] 'C:\androidworkspace\TestProject\AndroidManifest.xml'
[null] '-S'
[null] 'C:\androidworkspace\TestProject\res'
[null] '-I'
[null] 'C:\android-sdk_r07-windows\android-sdk-windows\platforms\android-8\android.jar'
[null] '-J'
[null] 'C:\androidworkspace\TestProject\gen'
[null]
[null] The ' characters around the executable and arguments are
[null] not part of the command.

Now, all you need to do is extract and form command from this and put it in a batch file (or shell script) and whenever you add any resources, just run the batch file in order to generate the R.java

Hope this helps someone !