Thursday, June 30, 2011

SQLite DB Example



There are 4 ways of storing data on the android platform:

  • 1.    Preferences
  • 2.    SQLite Database
  • 3.    Files
  • 4.    Network

A word about each of them here and then I will move on to an example that shows how to work with SQLite DB that comes along with the android platform.

Preferences – 
Basically used for storing user preferences for a single application or across applications for a mobile. This is typically name-value pairs accessible to the context.

Databases – 
Android supports creating of databases based on SQLite db. Each database is private to the applications that creates it 

Files –
Files can be directly stored on the mobile or on to an extended storage medium. By default other applications cannot access it.

Network – 
Data can be stored and retrieved from the network too depending on the availability.

If an application wants to store and retrieve data for its own use, without having to share the data across applications, it can access the SQLite DB directly. There is no need of a content provider. We have seen in anearlier post how to use content providers

In this example, we will do the following:
1.    Create a database (typically a one time activity)
2.    Create a table (typically a one time activity)
3.    Insert values into the table
4.    Retrieve the values from the table
5.    Display the retrieved values as a List view
6.    Delete all the records from the table before closing the connection to the database

Step 1: Create a database:

   sampleDB =  this.openOrCreateDatabase(SAMPLE_DB_NAMEMODE_PRIVATEnull);

This opens a database defined in the constant SAMPLE_DB_NAME, if it already exists. Else it creates a database and opens it. The second parameter is operating mode : MODE_PRIVATE meaning it is accessible to only this context. The other modes are and MODE_WORLD_WRITABLE. MODE_WORLD_READABLE

Step 2: Create a Table:

sampleDB.execSQL("CREATE TABLE IF NOT EXISTS " +
                        SAMPLE_TABLE_NAME +
                        " (LastName VARCHAR, FirstName VARCHAR," +
                        " Country VARCHAR, Age INT(3));");

Step 3: Insert values into the table:

sampleDB.execSQL("INSERT INTO " +
                        SAMPLE_TABLE_NAME +
                        " Values ('Makam','Sai Geetha','India',25);");

Step 4: Retrieve values 

Cursor c = sampleDB.rawQuery("SELECT FirstName, Age FROM " +
                        SAMPLE_TABLE_NAME +
                        " where Age > 10 LIMIT 5"null);
            
      if (c != null ) {
            if  (c.moveToFirst()) {
                  do {
String firstName = c.getString(c.getColumnIndex("FirstName"));
                  int age = c.getInt(c.getColumnIndex("Age"));
                  results.add("" + firstName + ",Age: " + age);
                  }while (c.moveToNext());
            } 
       }

Step 5: Display the values as a list 
            
       this.setListAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,results));

The statement displays it as a list as the class extends a ListActivity.

Step 6: Delete the values from the table in the finally part of the try block

finally {
            if (sampleDB != null
                  sampleDB.execSQL("DELETE FROM " + SAMPLE_TABLE_NAME);
                  sampleDB.close();
        }

It is as simple as this to work with the SQLite DB even in android. No different from a desktop application. However, there are various overloaded methods of query() provided by the SQLIteDatabase class which can be more optimally used instead of execSQL.

The complete code for this example is downloadable here.

Monday, June 27, 2011

Android Google Map Application Example


Android Google Maps Application
  • To integrate with Google maps application you need to apply for a free Google Map API Key.
  • To get the Google Map API Key you need to sign up for the Android Maps API.
  • To sign up, you will need to provide the certificate's fingerprint (MD5).
  • If you have a certificate fingerprint (MD5) you can sign up here and get the API Key.
To get certificate fingerprint (MD5) follow the simple steps below:
  • You need to get the keystore file for getting the certificate fingerprint (MD5).
  • Your keystore file can be found at the following path
"C:\Documents and Settings\<username>\Local Settings\Application Data\Android"
(Or)
"C:\Documents and Settings\<username>\.android"
  • Keystore file name is "debug.keystore" file.
  • Copy the "debug.keystore" file to some other folder (ex: - "D:\Androidkeystore\") (its user friendly to use).
  • Open command Prompt and go to the Java installed directory. ("C:\Program Files\Java\<JDK_version_number>\bin")
  • Then type the below line (given in box) and press enter.
keytool.exe -list -alias androiddebugkey -keystore "D:\AndroidKeystore\debug.keystore" -storepass android -keypass android
Now you will get a certificate fingerprint (MD5). (see the below image).
getmd5certificate
Here the MD5 certificate fingerprint is"64:88:A2:FC:AA:9F:B1:B0:CA:E4:D0:24:A8:1E:77:FB"
Enter the MD5 certificate fingerprint in the textbox and get the API Key (see below image)
signupformapapikey
After clicking the Generate API Key Button , you will get Google Map API Key (red circled).
getxmlcodeformap
Now the sample xml layout code to use the Google map application in Android is as specified below
Coding:-
To use Google map in your application, you need to add <uses-library> element together with the <uses- permission> in AndroidManifest.xml file.
Now your AndroidManifest.xml code looks like
[sourcecode language="xml"]
<?xml version="1.0? encoding="utf-8??>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="pack.sample.map"
android:versionCode="1?
android:versionName="1.0?>
<application android:icon="@drawable/icon" android:label="@string/app_name">
<uses-library android:name="com.google.android.maps" />
<activity android:name=".SampleMapApplication"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>
[/sourcecode]
To display map in your application, modify the main.xml file. It is located in <project-folder>/res/layout.
Use <com.google.android.maps.MapView> element to display map.
Now your main.xml code looks like
[sourcecode language="css"]
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<com.google.android.maps.MapView
android:id="@+id/mapView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:enabled="true"
android:clickable="true"
android:apiKey="0U7-rnRk3Os0sPZnZF9iejONnHMsGRLxU0JbrBg"/>
</RelativeLayout>
[/sourcecode]
Now edit your Java class file as specified below
[sourcecode language="java"]
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
@Override
protected boolean isRouteDisplayed() {
return false;
}
[/sourcecode]
Now run the application, you should be able to see the Google Map...

Android XML Parsing Tutorial – Using DOMParser





Moving ahead from Android XML Parsing using SAXParser, here we are going to see about how to parse a XML using DOM Parser.
we are going to parse XML from net ( by passing URL ) not from local file or string.
The output looks similar to
[sourcecode language="xml"]
<maintag>
<item>
<name>AndroidPeople</name>
<website category="android">www.androidpeople.com</website>
</item>
<item>
<name>iPhoneAppDeveloper</name>
<website category="iPhone">www.iphone-app-developer.com</website>
</item>
</maintag>
[/sourcecode]
XMLParsingDOMExample.java
This is main activity class. when App. starts this file will be called first.
This file contains how to use DOM Parser to handle XML tags.
[sourcecode language="java"]
package com.androidpeople.xml.parsing;
import java.net.URL;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import android.app.Activity;
import android.os.Bundle;
import android.widget.LinearLayout;
import android.widget.TextView;
public class XMLParsingDOMExample extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/** Create a new layout to display the view */
LinearLayout layout = new LinearLayout(this);
layout.setOrientation(1);
/** Create a new textview array to display the results */
TextView name[];
TextView website[];
TextView category[];
try {
URL url = new URL(
"http://www.androidpeople.com/wp-content/uploads/2010/06/example.xml");
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new InputSource(url.openStream()));
doc.getDocumentElement().normalize();
NodeList nodeList = doc.getElementsByTagName("item");
/** Assign textview array lenght by arraylist size */
name = new TextView[nodeList.getLength()];
website = new TextView[nodeList.getLength()];
category = new TextView[nodeList.getLength()];
for (int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);
name[i] = new TextView(this);
website[i] = new TextView(this);
category[i] = new TextView(this);
Element fstElmnt = (Element) node;
NodeList nameList = fstElmnt.getElementsByTagName("name");
Element nameElement = (Element) nameList.item(0);
nameList = nameElement.getChildNodes();
name[i].setText("Name = "
+ ((Node) nameList.item(0)).getNodeValue());
NodeList websiteList = fstElmnt.getElementsByTagName("website");
Element websiteElement = (Element) websiteList.item(0);
websiteList = websiteElement.getChildNodes();
website[i].setText("Website = "
+ ((Node) websiteList.item(0)).getNodeValue());
category[i].setText("Website Category = "
+ websiteElement.getAttribute("category"));
layout.addView(name[i]);
layout.addView(website[i]);
layout.addView(category[i]);
}
} catch (Exception e) {
System.out.println("XML Pasing Excpetion = " + e);
}
/** Set the layout view to display */
setContentView(layout);
}
}
[/sourcecode]

Friday, June 24, 2011

Android RSS reader with image

Since posting a link to my simple RSS Reader for Android implemented using a custom SAX parser I have some questions regarding upgrading to handle images - I have previously posted on how to implement new tags in the feed that you want to handle (including nested tags) - but one question I received was regarding when images are just embedded in the text (e.g. not a specific image tag, but say as part of a description as HTML).

So, I have updated the code (uploaded, see the sidebar) - this time it parses the description text data to retrieve any Image links its pretty grim string manipulation, but it does the job!


As you can see, it now parses the image URL from the description and inserts it to the left of the feed item.
What did I change?

First I needed to change the Article class to parse the link. I updated the setDescription method to also check for IMAGE tags to parse, if any found then it would set the ImgLink member:


  1. public void setDescription(String description) {  
  2.  this.description = description;  
  3.    
  4.  //parse description for any image or video links  
  5.  if (description.contains("<img ")){  
  6.   String img  = description.substring(description.indexOf("<img "));  
  7.   String cleanUp = img.substring(0, img.indexOf(">")+1);  
  8.   img = img.substring(img.indexOf("src=") + 5);  
  9.   int indexOf = img.indexOf("'");  
  10.   if (indexOf==-1){  
  11.    indexOf = img.indexOf("\"");  
  12.   }  
  13.   img = img.substring(0, indexOf);  
  14.     
  15.   setImgLink(img);  
  16.     
  17.   this.description = this.description.replace(cleanUp, "");  
  18.  }  
  19. }  



I then also had to update the RssListAdapter class - this needed the necessary action to pull down the link based on our parsed URL and then inflate the ImageView in our row:

  1. if (jsonImageText.get("imageLink") != null){  
  2.  String url = (String) jsonImageText.get("imageLink");  
  3.        URL feedImage= new URL(url);  
  4.       
  5.     HttpURLConnection conn= (HttpURLConnection)feedImage.openConnection();  
  6.        InputStream is = conn.getInputStream();  
  7.        Bitmap img = BitmapFactory.decodeStream(is);  
  8.        imageView.setImageBitmap(img);  
  9. }