Saturday, June 30, 2012

How to access SQLite database file in Android.

As we know that Android has inbuilt database called SQLite where application can store their data. SQLite was mainly developed for embedded devices. I am not going to discuss here about SQLite database but I am going to demonstrate how Android developer can access the SQLite database. This might be helpful while debugging the code especially to store application data in SQLite database tables. You can access the SQLite database file in emulator or rooted device.

Ways of accessing SQLite database file:

  • Copying from Phone/Emulator to your laptop
  • Accessing via Android shell and Sqlite commands.

Copying from phone/Emulator to your laptop:

You can easily copy the database file by just executing the command given below. But before that make sure  ...<android-sdk>/platform-tools/ is in environment path otherwise this command can executed only in .../platform-tools/ directory.
$adb shell /data/data/your.package.name/databases/databasefilename.db 
Database file can also be downloaded by Eclipse. If you have already installed the ADT plugin then it will be easier to browse the Android Emulator files. In Eclipse menu Window > Open Perspective > Other > DDMS . If the device/emulator is connected to your system, DDMS perspective shown in picture will appear. 
Eclipse Android file browser for SQLite database file access
Eclipse android file browser
DDMS perspective button marked as 1 in the picture: Once you select this perspective click the "File Explorer"(Which is marked as 2 in above picture) tab you will see the list of folder in the window. You can browse /data/data/your.package.name/database  where you will see a list of database files. Once you select the desired database file, "disket icon" on the upper-right corner of the window will get activated(which is marked as 4 in the above picture). Once you press this icon, the Eclipse will ask you to browse the place where you want to download the database file. 
Database table can be browsed with help of sqlite GUI or Mozilla browser if this extension is installed in your Mozilla browser.


Accessing via Android shell and Sqlite commands:

The following command is used for accessing file either from rooted device or emulator. 
$adb devices               #This command lists all the devices attached to your system
List of devices attached 
emulator-5554 device     #This emulator is the one which was running on my system.

$adb shell       #This allows you to access Android shell.
$ls              #This command lists all directories present in the current directory
.
.
data             #Sqlite database files are present in this directory
sdcard
sys
system
.
.
$cd data/data   #Now you need to find your package name here. eg com.rakesh.android.test

$cd com.rakesh.android.test/databases
$ls
mylist.db
$sqlite3 mylist.db
sqlite> .help        #This command lists the commands available in SQLite.
sqlite>.tables       #This command lists the tables present in the SQLite database.
sqlite>.schema       #This command shows the schema of the database.
sqlite>select * from myTable  #You can also run the queries in similar way.
sqlite>.exit         #This command exits you from SQLite command prompt.
$                    #Press Ctrl+C to come out of Android shell

For more commands and info about SQLite, please visit this site www.sqlite.org


Your valuable comments are always welcomed. It will help to improve my post and understanding.

"By three methods we may learn wisdom: First, by reflection, which is noblest; Second, by imitation, which is easiest; and third by experience, which is the bitterest."
By : Confucius

Android AVD Emulator libGL.so error

After announcement of Jelly bean I upgraded to Android SDK 4.1. After upgrade, AVD didn't boot up properly and it always froze on Android boot Image. I noticed the following error on the console.

Failed to load libGL.so error 
libGL.so: cannot open shared object file: No such file or directory

After a bit of research I discovered that if I install  "libgl1-mesa-dev:i386" I can get rid of the issue. Following command can be used to install the libgl.

$sudo apt-get install libgl1-mesa-dev:i386

After installation and restarting the system, I didn't notice any error and AVD worked like charm.

Your valuable comments are always welcomed. It will help to improve my post and understanding.

"By three methods we may learn wisdom: First, by reflection, which is noblest; Second, by imitation, which is easiest; and third by experience, which is the bitterest."
By : Confucius

Wednesday, June 27, 2012

How to find Android default screen orientation.


Recently while developing my personal project, I had a requirement to find the default screen orientation of device. Tablet default screen orientation is landscape whereas Mobile phone default screen orientation is portrait. 
Well after a little bit of research I found that getRotation method can fetch me the default orientation. This method can be used in the following way: 
this.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay()
               .getRotation()
 If this method returns Surface.ROTATION_0 (no rotation) then it means that the current screen orienation is the default screen orientation.  For example, if the tablet is currently in  landscape orientation then this method returns Surface.ROTATION_0(value 0x00000000) else it returns either  Surface.ROTATION_90 or Surface.ROTATION_270.
This arises one more question as how to determine the current orientation of the screen. It can be determined by the following method.
this.getResources().getConfiguration().orientation
The return value can be either of these
Configuration.ORIENTATION_LANDSCAPE
Configuration.ORIENTATION_PORTRAIT
Configuration.ORIENTATION_SQUARE
These values themselves suggest the orientation of the screen. 

Your valuable comments are always welcomed. It will help to improve my post and understanding.

"By three methods we may learn wisdom: First, by reflection, which is noblest; Second, by imitation, which is easiest; and third by experience, which is the bitterest."
By : Confucius

Monday, June 25, 2012

Android Source code browsing

As an engineer,  most of the time you spend on browsing peers' code in your company. Sometimes we think that how these platforms(i.e Android, Java, etc.) have been written? Is there anyway of getting access of source code? Is there any advantage of this?
 Well, there can be certainly some advantages. I would say, you may consider the following points as  advantages.
  • First hand Information. Source code browsing reveals large-scale software program. 
  • Increases your conceptual understanding of platform.
  • Gives idea about how you can do things more precisely and efficiently. It increases your code writing skills.
  • Makes you learn the coding standard and convention followed by the platform.
  • Live examples .
  • You may eventually contribute to the platform enhancement.

There are two ways of browsing the source code:

  1. Copy/clone source code repo.
  2. Online source code browsing.

1. Copy/clone source code repo.

If you have prior knowledge of git/repo and greping code in source directory then this option would be useful for you. If you are not keen to learn Git then please proceed to the next section. You can clone the Android source repo from these two places. 
  • googlesource : If you want to clone the android googlesrouce repo you can follow instruction given here.
  • github : Go here. Select the repositiory which you want to clone. Click on the Readonly button.  You will find url in text field similar to this git://github.com/android/android-module-repository.git and then execute these commands:

$mkdir android-src
$cd android-src
$git clone git://github.com/android/android-module-git-repository.git 

2. Online Source code browsing.

There are various websites available for Android source code browsing. I have listed some of them here. These are arranged in order of their usefulness to developer.
  1. www.grepcode.com : I personally like this website since it is really easy to use and handy. You can see the member function and the directory/package structure on the same webpage. You don't need to navigate around. This website has categorized the source code in different groups based on the module and its functionality. In case you have used Eclipse as an IDE then you will take less time to understand the user interface. There are four tabs Outlines, Files, Hierarchy and Comments, as we have in Eclipse IDE. In Outline tab you can browse methods and variables present in the class and its accessibility(private, protected and public). The File tab shows the folder/directory structure. The Hierarchy tab shows  how a particular class has been derived from other class along with its inheritance hierarchy. The Comments tab may not be so useful however it helps you to comment using your Facebook login. There are four links available on the top of the code frame. They are Find usage, Diff, Raw, Download and HTML widget. Find usage link provides you code snippet giving you the idea about the usage of particular method/variable  in different places. The Diff link provides the difference between the different code versions. The Raw link opens a new browser window which contains the source code.  The Download link itself suggest  what it does. The HTML Widget helps to share the source code. The most useful feature is that you can check the definition of class/variable by clicking on its name. This website also has java source code.
  2. Androidxref.com : This website has index Android 2.3.6, 4.0.4 and 4.1.1 source code. It provides almost similar features as provided by grep.com
  3. www.java2s.com : This is also a good resource. I will rank this site on the second place. It doesn't provide as many features as grepcode does. But still this website can be used for code reference. It also provides code examples which can be really helpful sometimes. 
  4. www.github.com :  This site is not basically designed for code browsing purpose but it can be used for the same. This website organizes the files in the same way as your hardrive does.(I host my source code on github. ;-) }

If you are really into Android and want to browse code on your Android phone then this application can be very handy. You can browse the code on the go.
These two sites java2s and grepcode host java source code and are really useful tools in your armour.

If you want to install git in Ubuntu machine, you may execute command below: 
$sudo apt-get install git

Similar topic:
Python package/library source code browsing

Your valuable comments are always welcomed. It will help to improve my post and understanding.

"By three methods we may learn wisdom: First, by reflection, which is noblest; Second, by imitation, which is easiest; and third by experience, which is the bitterest."
By : Confucius

Monday, June 18, 2012

Handy git commands

Clearcase was my first version control software. I used it for 2 years and eventually I liked it since most of the commands are really simple to understand. In these two years I used to debug the code on debugging branch. Once I was done with the fix, I renamed the branch to follow the standard specified by my company. The command below was really handy to rename the branch.
 [cmd-context] $rename replica:old_branch_name new_brach_name 
But when I migrated to Git version control, I couldn't get head around git. It took a while to discover that even git has command to rename the branch which is as following.
$ git branch -m old-branch-name new-branch-name 
This kind of practice leaves a lot of branches in your local and remote repo and sometimes you wonder to clean this up.
$git push origin :debug-branch 
The above command will delete debug-branch on the origin remote and below is the command used to delete the branch present in local repo.
$ git branch -D debug-branch 
This command can also be used with -d option. The only difference between these two commands is that -D forces the delete process but -d doesn't.
If you have made some changes in a file and now you don't want those changes. you can run the following command to do that.
$ git checkout <file-name>  
There are instances when you staged the file but now you want to unstage the file. For this use the below command.
$ git reset HEAD <file-name> ...  



Your valuable comments are always welcomed. It will help to improve my post and understanding.

  "By three methods we may learn wisdom: First, by reflection, which is noblest; Second, by imitation, which is easiest; and third by experience, which is the bitterest." 
By : Confucius

Wednesday, June 13, 2012

Application to send SMS on Android Platform

I have been playing around with Android application in past. I thought of writing a simple application which can send a SMS.
Android has provided android.telephony.SmsManager class which has exposed different methods for sending SMS. If the message size is less than 160 character then we can use the the following method.
sendTextMessage(String destinationAddress, String scAddress,
        String text, PendingIntent sentIntent, PendingIntent deliveryIntent)
If you just want to send the message and not bothered about the send result then just pass the destinalAddress(MDN) and text(Message). 

Here is the code snippet for main Activity class.
package com.rakesh.simpleSms;

import com.rakesh.broadcastreceiver.DeliverSMSBroadcastReceiver;
import com.rakesh.broadcastreceiver.OutgoingSMSBroadcastReceiver;

import android.app.Activity;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.telephony.SmsManager;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

public class SimpleSMSAppActivity extends Activity {
 private EditText etNumber;
 private EditText etMessage;
 private SmsManager manager;
 public static final int  MAX_MESSAGE_SIZE = 160;
 public static final String SMS_SENT = "SMS_SENT";
 public static final String SMS_DELIVERED = "SMS_DELIVERED";
 private final BroadcastReceiver outgoingSMSBR = new OutgoingSMSBroadcastReceiver();
 private final BroadcastReceiver deliverSMSBR = new DeliverSMSBroadcastReceiver();
 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
  //  btSendMessage = (Button)findViewById(R.id.btSendMessage);
  etNumber = (EditText)findViewById(R.id.etNumber);
  etMessage = (EditText)findViewById(R.id.etMessage);
  manager =  SmsManager.getDefault();
 }

 public void sendMessage(View view){
  String number = etNumber.getText().toString();
  String message = etMessage.getText().toString();
  Log.d("RK","number : "+number+", message : " + message  );

  if(!isNullOrEmpty(number) && !isNullOrEmpty(message)){
   if(message.length() > MAX_MESSAGE_SIZE){

    Toast.makeText(this,"Message is longer then allowed in SMS",Toast.LENGTH_LONG).show();
   } else{
    PendingIntent piSend = PendingIntent.getBroadcast(this, 0, new Intent(SMS_SENT),0);
    PendingIntent piDelivered = PendingIntent.getBroadcast(this, 0, new Intent(SMS_DELIVERED), 0);

    manager.sendTextMessage(number, null, message, piSend, piDelivered);
    etMessage.setText("");
   }
  }
 }

 @Override
 protected void onResume() {
  registerReceiver(outgoingSMSBR, new IntentFilter(SMS_SENT));

  registerReceiver(deliverSMSBR, new IntentFilter(SMS_DELIVERED));

  super.onResume();
 }

 @Override
 protected void onPause() {
  unregisterReceiver(outgoingSMSBR);
  unregisterReceiver(deliverSMSBR);
  super.onPause();
 }

 private boolean isNullOrEmpty(String string){
  return string == null || string.isEmpty();
 }
}

and two broadcast receiver classes are as following.

OutgoingSMSBroadcastReceiver.java
 
public class OutgoingSMSBroadcastReceiver extends BroadcastReceiver {

 @Override
 public void onReceive(Context context, Intent intent) {
  
  switch(getResultCode()){
  
   case Activity.RESULT_OK:
      Toast.makeText(context, "SMS sent", 
                 Toast.LENGTH_SHORT).show();
      Log.d("RK","RESULT_OK");
         break;
      case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
          Toast.makeText(context, "Generic failure", 
                  Toast.LENGTH_SHORT).show();
          Log.d("RK","RESULT_ERROR_GENERIC_FAILURE");
          break;
      case SmsManager.RESULT_ERROR_NO_SERVICE:
          Toast.makeText(context, "No service", 
                  Toast.LENGTH_SHORT).show();
          Log.d("RK","RESULT_ERROR_NO_SERVICE");
          break;
      case SmsManager.RESULT_ERROR_NULL_PDU:
          Toast.makeText(context, "Null PDU", 
                  Toast.LENGTH_SHORT).show();
          Log.d("RK","RESULT_ERROR_NULL_PDU");
          break;
      case SmsManager.RESULT_ERROR_RADIO_OFF:
          Toast.makeText(context, "Radio off", 
                  Toast.LENGTH_SHORT).show();
          Log.d("RK","RESULT_ERROR_RADIO_OFF");
          break;
  }
 }
}
DeliverSMSBroadcastReceiver.java
package com.rakesh.broadcastreceiver;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.Toast;

public class DeliverSMSBroadcastReceiver extends BroadcastReceiver {

 @Override
 public void onReceive(Context context, Intent intent) {
 
          switch (getResultCode())
            {
             case Activity.RESULT_OK:
                Toast.makeText(context, "SMS delivered", 
                        Toast.LENGTH_SHORT).show();
                Log.d("RK","RESULT_OK=> DELIVER");
                break;
             case Activity.RESULT_CANCELED:
                Toast.makeText(context, "SMS not delivered", 
                        Toast.LENGTH_SHORT).show();
                Log.d("RK","RESULT_CANCELED");
                break;                        
            }
 }
}
Make sure you have provided the right permission to application in manifest file.

<manifest android:versioncode="1"   
 android:versionname="1.0" package="com.rakesh.simpleSms" 
 xmlns:android="http://schemas.android.com/apk/res/android">

    <uses-sdk android:minsdkversion="10">
    
 <uses-permission android:name="android.permission.SEND_SMS">
 
    <application android:debuggable="true" android:icon="@drawable/ic_launcher" 
         android:label="@string/app_name">
        
        <activity android:label="@string/app_name" android:name=".SimpleSMSAppActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN">
                <category android:name="android.intent.category.LAUNCHER">
            </category></action></intent-filter>
        </activity>
    </application>
 
</uses-permission></uses-sdk>
You can find the source code here.

Please provide your valuable comments to improve this blog.

"By three methods we may learn wisdom: First, by reflection, which is noblest; Second, by imitation, which is easiest; and third by experience, which is the bitterest."
By : Confucius

Sunday, June 10, 2012

Simple Python script to access Excel file meta-data/data

Recently I got interested in Python programming actually this was my first scripting language and its really a handy tool. I would like to share a small code which  can access Excel(*.xls) file.  I am assuming that you are having Ubuntu machine. In order to run this code you need to have xlrd package and Python installed. If your system doesn't have xlrd package then you can install it in two ways.
you can install by use of pip  
$ sudo pip install xlrd 
otherwise try to execute below command 
$ sudo apt-get install python-xlrd
Here is a simple code which demonstrate a few functionality of this library.
#!/usr/bin/python
import optparse  ###Option parser
try:
import xlrd; ###Need to make sure xlrd library is available
except ImportError:
 print 'Could not find package "xlrd". Try installing it first'
 print ''
 print 'Halting.'
 sys.exit(1)

def formatDataTypeString(dataType):
 # Cell Types: 0=Empty, 1=Text, 2=Number, 3=Date, 4=Boolean, 5=Error, 6=Blank
 formatString =":"
 if dataType == 0:
   formatString +=" Empty :"
 elif dataType == 1:
   formatString +=" Text :"
 elif dataType == 2:
   formatString +=" Number :"
 elif dataType == 3:
   formatString +=" Date :"
 elif dataType == 4:
   formatString +=" Boolean :"
 elif dataType == 5:
    formatString +=" Error :"
 elif dataType == 6:
    formatString +=" Blank :"

   return formatString


def metaData(xlFile):
    """This method takes one argument which is xl file name. It display the 
    meta-data of the xl file. It displays sheet names present in the file 
    and the content type.
    """
    book = xlrd.open_workbook(xlFile) 
    print("#########sheet Names#########") 
    sheetNames = ""
    for sheet in book.sheet_names():
        sheetNames += str(sheet) + " "
    print(sheetNames)

    sheets = book.sheets()
    for sheet in sheets:
       
        print("=====" + str(sheet.name) + "(" + str(sheet.nrows) + ", " + str(sheet.ncols) + ")=====")
        if sheet.ncols > 0:
            curCol = 0;
            colsType = ""
            while curCol < sheet.ncols:
                colsType +=formatDataTypeString(sheet.cell_type(0,curCol))   
                curCol +=1         
            print("First row cell Type " + colsType)
        else:
            print("Sheet is empty")

def showData(xlFile, sheetName):
    """This method takes two arguments xlFile name and SheetName. 
    It display data if it is present in the provided sheet"""
    book = xlrd.open_workbook(xlFile)
    if sheetName:
        sheet = book.sheet_by_name(sheetName)
    else:
        sheet = book.sheet_by_index(0)
    if sheet.nrows > 0:
        for i in xrange(sheet.nrows):
            print(sheet.row_values(i))
    else:
        print ("Sheet is empty")

def main():
    ##Argument parsing

    parser = optparse.OptionParser(usage = "%prog filename [options] \n" )
    parser.add_option("-m","--metadata",
                        action="store_true",
                        default = False,
                        dest = "metaData",
                        help = "Meta information of XL sheet")
    parser.add_option("-d","--showData",
                        action="store_true",
                        default = False,
                        dest = "showData",
                        help = "Show Data of specified sheet otherwise show data from first sheet")
    parser.add_option("-s","--sheet",
                        dest = "sheetName",
                        help = "Sheet name whose data you want to see. This option should be used with -s(--showData) option")
    
    (options, args) = parser.parse_args()
    #print (args)
    if len(args) != 1:
        parser.print_help()
        return -1
    else:
        if not args[0]:
            print("Please provide file name")
            print("")
            parser.print_help()
            return -1
        else: 
            if options.metaData:
                metaData(args[0])
            elif options.showData:
                showData(xlFile=args[0], sheetName=options.sheetName)
            else:
                parser.print_help()

if __name__ == "__main__":
    main()
you can find the find source code here
Please provide your valuable comments to improve this post.