Winners of the Ice Cream Sandwich VS iOS5 contest

Dear readers we are glad to announce the winners of our Ice Cream Sandwich VS iOS5 contest:

The winners of the first prize: Android a Complete Course:
Jim from http://sakiko.com/
and
Believer.

The winner of the second prize: Android a Quick Course:
Corneliu Dascalu

The winners of the third prize Android, an Enterprise Edition Vision:
Will.i.am

for the winners please contact me at m.s.ramzy@gmail.com to send you the copies of the books
thanks a lot for all the participants and good luck next time.

Reactions: 

Ice Cream Sandwich GridLayout

Android 4.0 (Ice Cream Sandwich) introduced a new type of layouts: the Gridlayout.
Gridlayout is like the <Table> tag in HTML. child widgets are arranged in Cells made of Rows and Columns.

Grid layout is a ViewGroup that can be used in constructing dashboard activities like that one in the Google Plus application:

so let's see what we can do with the GridLayout:
we'll construct a simple dashboard layout like this:
<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:rowCount="5"
    android:columnCount="3"
    >

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button 1"
        android:layout_row="0"
        android:layout_column="0"
        android:layout_marginLeft="5dp"
         />
    
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button 2"
        android:layout_row="0"
        android:layout_column="1"
        android:layout_margin="5dp" />
    
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button 3"
        android:layout_row="1"
        android:layout_column="0"
        android:layout_margin="5dp" />
    
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button 4"
        android:layout_row="1"
        android:layout_column="1"
        android:layout_margin="5dp" />
    
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button 5"
        android:layout_row="2"
        android:layout_column="0"
        android:layout_margin="5dp" />
    
    

</GridLayout>


Widgets are placed in position specified by android:layout_column and android:layout_row properties.
we can organize the widgets in a similar way by using the new Space View like this:
<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:rowCount="5"
android:columnCount="3"

>

<Space
android:layout_width="5dp"
android:layout_height="5dp"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 1"
android:layout_row="0"
android:layout_column="0"
/>
<Space
android:layout_width="5dp"
android:layout_height="5dp"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 2"
android:layout_row="0"
android:layout_column="1"
/>
<Space
android:layout_width="5dp"
android:layout_height="5dp"/>

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 3"
android:layout_row="1"
android:layout_column="0"
/>
<Space
android:layout_width="5dp"
android:layout_height="5dp"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 4"
android:layout_row="1"
android:layout_column="1"
/>
<Space
android:layout_width="5dp"
android:layout_height="5dp"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 5"
android:layout_row="2"
android:layout_column="0"
/>
<Space
android:layout_width="5dp"
android:layout_height="5dp"/>


</GridLayout>

Reactions: 

Contest: Do you think Android Ice Cream Sandwich will beat Apple iOS 5

Hello everybody.
Google will release the next major Android update: Android 4.0 (Ice cream Sandwich) along with it's next flagship phone: the Nexus Prime.

Join our Contest and have the chance to win a copy of one of these wonderful Android books:

  1. Android, A Complete Course, From Basics To Enterprise Edition.
  2. Android, A Quick Course.
  3. Android, An Enterprise Edition Vision.




all you've got to do is to drop a comment answering the following question:
Do you think Android Ice Cream Sandwich will beat Apple iOS 5 ?

the contest ends on November 7th, winners will be announced then.
waiting for your comments


Reactions: 

Symbyo Technologies: Cloud Computing and Mobile Application Development

Symbyo Technologies: Cloud Computing and Mobile Application Development

Reactions: 

Android Developers Blog: Preview of Google TV Add-on for the Android SDK

Android Developers Blog: Preview of Google TV Add-on for the Android SDK

Reactions: 

Official Google Blog: Supercharging Android: Google to Acquire Motorola Mobility

Official Google Blog: Supercharging Android: Google to Acquire Motorola Mobility

Reactions: 

Android Developing: Remove Auto focus from Edit Text

Android Developing: Remove Auto focus from Edit Text: "When start Android application, it always auto focus EditText box. Here we give explain how to remove auto focus from EditText. Add your..."

Reactions: 

Implementing Search activities

Most Android phones have a search button. this button is used to search contacts,applications or anything on the phone. We can make use of the search functionality in our apps.

In this post we're going to see how to implement search functionality to search for entries stored in a databaseand display them in a ListView.

Creating database:
our database has two tables: Countries and Names:
public class DBHelper extends SQLiteOpenHelper {

 public DBHelper(Context context) {
  super(context, "DemoDB", null, 1);
 }

 @Override
 public void onCreate(SQLiteDatabase db) {
  StringBuilder builder=new StringBuilder();
  // countries table
  builder.append("CREATE TABLE Countries ");
  builder.append("(_id INTEGER PRIMARY KEY AUTOINCREMENT,");
  builder.append("NAME TEXT) ");
  db.execSQL(builder.toString());
  // Names table
  // Virtual table for full text search
  builder.setLength(0);
  builder.append("CREATE VIRTUAL TABLE NAMES USING FTS3");
  builder.append("(");
  builder.append("name TEXT) ");  
  db.execSQL(builder.toString());
  builder=new StringBuilder();

  //dummy  data
  InsertData(db);

 }

  void InsertData(SQLiteDatabase db)
  {
   ContentValues cv=new ContentValues();
   cv.put("NAME","USA");
   db.insert("Countries", "NAME", cv);
   cv.put("NAME","UK");
   db.insert("Countries", "NAME", cv);
   cv.put("NAME","Spain");
   db.insert("Countries", "NAME", cv);
   cv.put("NAME","ITALY");
   db.insert("Countries", "NAME", cv);
   cv.put("NAME","Germany");
   db.insert("Countries", "NAME", cv);

    cv=new ContentValues();
    cv.put("name","John");
    db.insert("NAMES", "name", cv);
    cv.put("name","Jack");
    db.insert("NAMES", "name", cv);
    cv.put("name","Ann");
    db.insert("NAMES", "name", cv);
    cv.put("name","Adam");
    db.insert("NAMES", "name", cv);
    cv.put("name","Sarah");
    db.insert("NAMES", "name", cv);

  }

 @Override
 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
  // TODO Auto-generated method stub

 }
}
notice that the Names table is a VIRTUAL table. we created it as virtual to make use of Full Text Search (FTS3) feature in SQLite. this feature makes queries faster than that in regular tables.
then we add two functions to retrieve all rows from both tables:
/**
  * Return all countries
  * @return
  */
 public ArrayListgetCountries(){
  ArrayList countries=new ArrayList();
  SQLiteDatabase db=this.getReadableDatabase();
  Cursor c=db.rawQuery("select * from Countries", null);
  while(c.moveToNext()){
   String country=c.getString(1);
   countries.add(country);
  }
  c.close();
  return countries;
 }
/**
  * Return all names
  * @return
  */

 public ArrayListgetNames(){
  ArrayList names=new ArrayList();
  Cursor c=this.getReadableDatabase().rawQuery("select * FROM Names", null);
  while(c.moveToNext()){
   String name=c.getString(0);
   names.add(name);
  }
  c.close();
  return names;
 }
and another two functions to retrieve data based on a search string:
/**
  * Return all countries based on a search string
  * @return
  */
 public ArrayListgetCountriesSearch(String query){
  ArrayList countries=new ArrayList();
  SQLiteDatabase db=this.getReadableDatabase();
  Cursor c=db.rawQuery("select * from Countries where NAME LIKE '%"+query+"%'", null);
  while(c.moveToNext()){
   String country=c.getString(1);
   countries.add(country);
  }
  c.close();
  return countries;
 }
/**
  * Return all names based on a search string
  * we use the MATCH keyword to make use of the full text search
  * @return
  */
 public ArrayListgetNamesSearch(String query){
  ArrayList names=new ArrayList();
  Cursor c=this.getReadableDatabase().rawQuery("select * FROM Names WHERE name MATCH '"+query+"'", null);
  while(c.moveToNext()){
   String name=c.getString(0);
   names.add(name);
  }
  c.close();
  return names;
 }

Implementing The activity:
then we will create our activity that has a list view like this:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<ListView
android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:id="@+id/list"/>
</LinearLayout>

we load data from database like this:
public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        list=(ListView)findViewById(R.id.list);

            DBHelper helper=new DBHelper(this);
            ArrayList items=helper.getNames();
            ArrayAdapter adapter=new ArrayAdapter(this, android.R.layout.simple_list_item_1,items);
            list.setAdapter(adapter);
}

Handling the search dialog:
In order to handle the search dialog ourselves we need to create a xml file with search configurations such as the search dialog title, voice search capabilities, content provider for auto complete and so on. we create a file with the name searchable.xml in res/xmldirectory:
<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
    android:label="@string/app_name"
    android:hint="@string/hint"  >
</searchable>
the android:hint attribute denotes a string that acts as a water mark on the search text box.
then we need to add an Intent Filter in out app's AndroidManifest.xml file to our activity to handle the search dialog:
<activity android:name=".MainActivty"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
             <intent-filter>
            <action android:name="android.intent.action.SEARCH" />
        </intent-filter>
        <meta-data android:name="android.app.searchable"
                   android:resource="@xml/searchable"/>
        </activity>

Understanding the Search process:

when you press the search button, type some text and click on search the activit's onSearchRequested() function is called, then an Intent with the action Intent.ACTION_SEARCH is created and you activity is re-created with this intent.

the search intent has you search string as a string extra with the name SearchManager.QUERY. also it can carry a bundle of other extras with the name SearchManager.APP_DATA.

what if the device doesn't have a Search button:
not all Android devices have a search button, so we can start the search dialog manually by calling the activity's onSearchRequested() from a button or a menu item:
@Override
     public boolean onCreateOptionsMenu(Menu menu) {
     menu.add("Search").setOnMenuItemClickListener(new OnMenuItemClickListener() {

   @Override
   public boolean onMenuItemClick(MenuItem item) {
                                //launch the search dialog
    onSearchRequested();
    return true;
   }
  });
     return true;
    }

Adding extras to the search dialog:
we can pass some extra data as a bundle with our search dialog or an initial search string by overriding the activity's onSearchRequested():
@Override
    public boolean onSearchRequested() {
     Bundle bundle=new Bundle();
  bundle.putString("extra", "exttra info");
  // search initial query
  startSearch("Country", false, bundle, false);
  return true;
    }

Handling the search query:

we said before that the search query is passed as a String extra when our activity is re-created. so we can handle the searcgh string in our onCreate() like this:
@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        list=(ListView)findViewById(R.id.list);

        DBHelper helper=new DBHelper(this);
        Intent intent=getIntent();
        // if the activity is created from search
         if(intent.getAction().equals(Intent.ACTION_SEARCH)){
          // get search query
          String query=intent.getStringExtra(SearchManager.QUERY);
          ArrayList items=helper.getNamesSearch(query);
          //get extras, just for demonstration
          Bundle bundle=intent.getBundleExtra(SearchManager.APP_DATA);
             String info=bundle.getString("extra");
          Log.v("extra", info);
          //bind the list
                ArrayAdapter adapter=new ArrayAdapter(this, android.R.layout.simple_list_item_1,items);
                list.setAdapter(adapter);
         }
        //activity created normally
        else{
         ArrayList items=helper.getNames();
            ArrayAdapter adapter=new ArrayAdapter(this, android.R.layout.simple_list_item_1,items);
            list.setAdapter(adapter);
        }
        helper.close();
    }


we just extract the search string and any other extras and perform our search logic based on the search string.
and that's was all about implementing search

Reactions: 

In this post we will see how can a client application call the methods of a service defined in another application. this is achieved through Android Interface Definition Language (AIDL).

AIDL is a java like language that enables you to define an interface that both the application defining the service and the client application implement it.

the interface defines the functions that are needed to be called in the client application.

Defining the AIDL file:
AIDL syntax is similar to that of Java, we can use the following data types in AIDL:
  1. primitive data types: int, long, char, boolean,....
  2. String.
  3. CharSequence.
  4. List (ArrayList,Vector,...).

  1. the AIDL file is defined as follows:
    open a notepad file and paste the following code in it:
    package com.mina.servicedemo;
    
    // service interface
    interface IRemoteService {
        //sample method
        String sayHello(String message);
    }
    take care of the package name com.mina.servicedemo.
    we defined a methods sayHello(String message) that returns a string.
  2. save the file with the name IRemoteService and change it's extension to .aidl.
  3. copy the file to the src folder of your project.
  4. once you save and build the file, Android generates an interface java file with the name IRemoteService.java in the gen folder if the project.

Defining the Service:
now we want our service to expose this interface to client applications, so we return an implementation of the service in the onBind() method of our service:
package com.mina.servicedemo;

import com.mina.servicedemo.IRemoteService.Stub;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.widget.Toast;

public class DemoService extends Service {

 @Override
 public IBinder onBind(Intent arg0) {
  return mBinder;
 }

 // implementation of the aidl interface
 private final IRemoteService.Stub mBinder=new Stub() {

  @Override
  public String sayHello(String message) throws RemoteException {
   return "Hello "+message;

  }
 };

 }
}
the last thing to do in the service is to make its exported attribute in the AndroidManifest.xml file set to true like this:
<service android:name="DemoService" android:exported="true"></service>
our app structure can be like this:

Consuming the service at the client application:
now to our client application where we want to invoke methods from our service. the client application is a separate application with a different package name than that where the service is defined.

the client application needs a reference to the AIDL interface defined in the original applcation, this is done through the following steps:
  1. in the client applicatio create a package with the same package name of that the service is defined in: com.mina.servicedemo.
  2. copy the AIDL file in this package.
  3. save and build and a new file called IRemoteService.java is generated. your app structure should be like this:
and we invoke the servcice methods in our activity like this:
package com.mina.serviceclient;

import com.mina.servicedemo.IRemoteService;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;

public class MainActivity extends Activity {

 IRemoteService mRemoteService;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        Intent serviceIntent=new Intent();
        serviceIntent.setClassName("com.mina.servicedemo", "com.mina.servicedemo.DemoService");
        boolean ok=bindService(serviceIntent, mServiceConnection,Context.BIND_AUTO_CREATE);
        Log.v("ok", String.valueOf(ok));
    }

    private ServiceConnection mServiceConnection=new ServiceConnection() {

  @Override
  public void onServiceDisconnected(ComponentName name) {
   // TODO Auto-generated method stub

  }

  @Override
  public void onServiceConnected(ComponentName name, IBinder service) {
   // get instance of the aidl binder
   mRemoteService = IRemoteService.Stub.asInterface(service);
   try {
    String message=mRemoteService.sayHello("Mina");
    Log.v("message", message);
   } catch (RemoteException e) {
    Log.e("RemoteException", e.toString());
   }

  }
 };
}
and that's was all about calling remote services with AIDL.

Reactions: 

Official Google Blog: When patents attack Android

Official Google Blog: When patents attack Android

Reactions: 

Android Story: From [x] cube Labs

Reactions: 

Symbyo Technologies: The Android Invasion Continues!!

Symbyo Technologies: The Android Invasion Continues!!

Reactions: 

Android Services


Android Service is used for long-running processes that do not require user interaction, such as calling a web service and parsing response. Or processes that need to be running even if the application that started the service is not on the foreground such as playing mp3 files in a music player.

we need to distinguish between A Service and a Thread or an AsyncTask: Threads or Async task perform their tasks in a background thread thus they do not block the main thread, while a service performs it's work in the main thread. so if a service is performing an intensive task such as calling a web service, it may block the main thread until it finishes. So for intensive tasks a service should run it's work in a background thread.

A service runs in the same process of the application and keeps running until stopped by itself, stopped by the user or killed by the system if it needs memory.

Creating a service:

to create a service we create a class that extends android.app.Service and it would be like this:
public class DemoService extends Service {

 @Override
 public IBinder onBind(Intent arg0) {
  // TODO Auto-generated method stub
  return null;
 }

}
next we need to define our service in our AndroidManifest.xml file:
<service android:name="DemoService"></service>
The service life cycle has the following events
  • onCreate(): called when the service is created.
  • onStart(): Called when the service starts by a call to startService(Intent intent).
  • onDestroy(): Called as the service is terminates.

Calling a service:

A service can be called from an activity in two ways:
  1. By calling startService(Intent intent).
  2. By binding to the service through an Binder object.

calling startService(Intent intent):

to start a service from an activity using this method, we create an intent and start the service like this:
Intent intent=new Intent(this,DemoService.class);
startService(intent);
the startService(intent) method causes the onStart() method of the service to be called, so the service can execute it's work like this:
public class DemoService extends Service {

 @Override
 public IBinder onBind(Intent arg0) {
  // TODO Auto-generated method stub
  return null;
 }

 @Override
 public void onStart(Intent intent, int startId) {
  super.onStart(intent, startId);
  doSomething();
 }

 public void doSomething(){
  // do some work
 }

}
the service will keep running until it stops itself via stop stopSelf() after finishing work:
@Override
 public void onStart(Intent intent, int startId) {
  super.onStart(intent, startId);
  doSomething();
  stopSelf();
 }
or it can be stopped from the activity via stopService(Intent intent).

Binding to a service through an Binder object:

As the service runs in the same process of the application the service has only one instance (singleton) instance running. you may want to keep reference to this instance to perform periodical tasks or to call the service methods themselves.

to make the service bind-able we extends Binder class and return an instance of it in the service's onBind(Intent intent) method:
public class DemoService extends Service {

 private final IBinder binder = new LocalBinder();
 @Override
 public IBinder onBind(Intent arg0) {
  return binder;
 }

 public class LocalBinder extends Binder {
  DemoService getService() {
            return DemoService.this;
        }
    }

 @Override
 public void onStart(Intent intent, int startId) {
  super.onStart(intent, startId);
  doSomething();
  stopSelf();
 }

 public void doSomething(){
  // do something
 }

}
then we bind the service from our activity by first creating a ServiceConnection object to handle the service connection/disconnection then binding to the service by an intent like this:
public class MainActivity extends Activity {

 DemoService mService;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }

    ServiceConnection serviceConn=new ServiceConnection() {

                /**
                * service unbound, release from memory
                **/
  @Override
  public void onServiceDisconnected(ComponentName name) {
   mService=null;
  }

                /**
                * service is bound, start it's work
                **/
  @Override
  public void onServiceConnected(ComponentName name, IBinder service) {
   mService=((LocalBinder)service).getService();
   mService.doSomething();

  }
 };

    @Override
    protected void onResume() {
     super.onResume();
        // bind to the service by an intent
     Intent intent=new Intent(this,DemoService.class);
        // AUTO CREATE: creates the service and gives it an importance so that it won't be killed
        // unless any process bound to it (our activity in this case) is killed to
     bindService(intent, serviceConn, Context.BIND_AUTO_CREATE);
    }

    @Override
    protected void onDestroy() {
     super.onDestroy();
        / unbind the service whena ctivity is destroyed
     unbindService(serviceConn);
    }
}
notice that we unbind the service in the activity's onDestroy() method to disconnect from the service and stop it from executing any further

and that's was all about Android services, stay tuned for another Android tutorial.

Reactions: 

Parsing JSON respone:


if we have a JSON web service response like this:
"persons"
[
{
"person"{
"firstName": "John",
     "lastName": "Smith",
     "age": 25
}
}
{
"person"{
"firstName": "Catherine",
     "lastName": "Jones",
     "age": 35
}
}
]
this response is a JSON Array with the name "persons", this array consists of "person" JSON Objects.
to parse such a reponse:
public ArrayList<Person> getMessage(String response){
  JSONObject jsonResponse;
  ArrayList<Person> arrPersons=new ArrayList<Person>;
  try {
   // obtain the reponse
   jsonResponse = new JSONObject(response);
   // get the array
   JSONArray persons=jsonResponse.optJSONArray("persons");
   // iterate over the array and retrieve single person instances
   for(int i=0;i<persons.length();i++){
    // get person object
    JSONObject person=persons.getJSONObject(i);
    // get first name
    String firstname=person.optString("firstname");
    // get last name
    String lastname=person.optString("lastname");
    // get the age
    int age=person.optInt("age");

    // construct the object and add it to the arraylist
    Person p=new Person();
    p.firstName=firstname;
    p.lastName=lastname;
    p.age=age;
    arrPersons.add(p);
   }

  } catch (JSONException e) {

   e.printStackTrace();
  }

  return arrPersons;
 }

notice that we used the methods optJSONArray,optString,optInt instead of using getString,getInt because the opt methods return empty strings or zero integers if no elements are found. while the get methods throw an exception if the element is not found.

Reactions: 

Parsing XML wit SAX parser

Android provides org.xml.sax package that has that provides the event-driven SAX parser.
to parse the previous response with SAX parser, we have to create a class extending DefaultHandler and override the following methods:
  1. startDocument(): invoked when the xml document is open, there we can initialize any member variables.
  2. startElement(String uri, String localName, String qName, Attributes attributes): invoked when the parser encounters a xml node, here we can initialize specific instances of our person object.
  3. endElement(String uri, String localName, String Name): invoked when the parser reaches the closing of a xml tag. here the element value would have been completely read.
  4. characters(char[] ch, int start, int length): this method is called when the parser reads characters of a node value.
we want to parse this xml response:
<?xml version="1.0"?>
<person>
    <firstname>Jack</firstname>
    <lastname>smith</lastname>
    <age>28</age>
</person>
so our parsing class will be like this:
/**
  * SAX parser to parse persons response
  */
 public class PersonParser extends DefaultHandler
 {

  // arraylist to store person objects
  ArrayList persons;
  // temporary person object
  Person tempPerson;
  // string builder acts as a buffer
  StringBuilder builder;

  /**
   * Initialize the arraylist
   * @throws SAXException
   */
  @Override
  public void startDocument() throws SAXException {
   pesons=new ArrayList();

  }

  /**
   * Initialize the temp person object which will hold the parsed in//fo
   * and the string builder that will store the read characters
   * @param uri
   * @param localName
   * @param qName
   * @param attributes
   * @throws SAXException
   */
  @Override
  public void startElement(String uri, String localName, String qName,
    Attributes attributes) throws SAXException {

   if(localName.equalsIgnoreCase.equals("person")){
    tempPerson=new Person();
    builder=new StringBuilder();
   }

  }
  /**
   * Finished reading the person tag, add it to arraylist
   * @param uri
   * @param localName
   * @param qName
   * @throws SAXException
   */
  @Override
  public void endElement(String uri, String localName, String qName)
    throws SAXException {
   // finished reading a person, add it to the arraylist
   if(localName.toLowerCase().equals("person"))
   {
    this.persons.add(tempPerson);
   }
   // finished reading "firstname" tag assign it to the temp person
   else if(localName.toLowerCase().equals("firstname")){
    tempPerson.firstName=builder.toString();
   }
   // finished reading "lastname" tag assign it to the temp person
   else if(localName.toLowerCase().equals("lastname")){
    tempPerson.lastName=builder.toString();
   }
   // finished reading "age" tag assign it to the temp person
   else if(localName.toLowerCase().equals("age")){
    tempPerson.age=Integer.parseInt(builder.toString());
   }
  }

  /**
   * Read the value of each tag
   * @param ch
   * @param start
   * @param length
   * @throws SAXException
   */
  @Override
  public void characters(char[] ch, int start, int length)
    throws SAXException {
   // read the characters and append them to the buffer
   String tempString=new String(ch, start, length);
    builder.append(tempString);
  }
 }
the code is pretty easy, the parser iterates over each node, you check the current node name and take an action.

then we call the parser like this:
public ArrayList getPersons(final String response) throws ParserConfigurationException, SAXException, IOException
 {
  BufferedReader br=new BufferedReader(new StringReader(response));
  InputSource is=new InputSource(br);
  PersonParser parser=new PersonParser();
  SAXParserFactory factory=SAXParserFactory.newInstance();
     SAXParser sp=factory.newSAXParser();
     XMLReader reader=sp.getXMLReader();
     reader.setContentHandler(parser);
     reader.parse(is);
     ArrayList persons=parser.persons;

  return persons;

 }

Reactions: 

Parsing XML wit DOM parser


Android offers three types of XML parsers:
  1. DOM Parser.
  2. Pull Parser.
  3. SAX Parser.
we'll demonstrate each using the following xml example:
<?xml version="1.0"?>
<person>
    <firstname>Jack</firstname>
    <lastname>smith</lastname>
    <age>28</age>
</person>
which we need to parse to create an object from Person class:
public class Person{
     public String firstName;
     public String lastName;
     public int age;
    }
Parsing the response with DOM Parser:
Android provides org.w3c.dom library that contains classes used to parse xml by constructing a document and
matching each node to parse the info.
to parse our example response with DOM parser, we implement a function like this
void parseByDOM(String response) throws ParserConfigurationException, SAXException, IOException{
     Person person=new Person();
     DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
     DocumentBuilder db = dbf.newDocumentBuilder();
     Document doc = db.parse(new InputSource(new StringReader(response)));
     // normalize the document
     doc.getDocumentElement().normalize();
     // get the root node
     NodeList nodeList = doc.getElementsByTagName("person");
     Node node=nodeList.item(0);
     // the  node has three child nodes
     for (int i = 0; i < node.getChildNodes().getLength(); i++) {
     Node temp=node.getChildNodes().item(i);
     if(temp.getNodeName().equalsIgnoreCase("firstname")){
      person.firstName=temp.getTextContent();
     }
     else if(temp.getNodeName().equalsIgnoreCase("lastname")){
      person.lastName=temp.getTextContent();
     }
     else if(temp.getNodeName().equalsIgnoreCase("age")){
      person.age=Integer.parseInt(temp.getTextContent());
     }

     }

     Log.e("person", person.firstName+ " "+person.lastName+" "+String.valueOf(person.age));
    }
The previous method is good, it retrieves the info correctly, but it requires that you are familiar with the xml structure so that you know the order of each xml node.

Reactions: 

RapidFire




APPLICATION: RapidFire.



DEVELOPER: Peapple Ltd

CATEGORY: Social

PRICE: Free.

REQUIRES ANDROID: 2.2 and up

CONTENT RATING: Low Maturity

With RapidFire share your messages and upload multiple photos to multiple social networks including:

Facebook

Twitter

LinkedIn

WordPress

last.fm

My Space

Tumblr








now with RapidFire share your thoughts with the whole world with the whole world with a single click:
share thoughts in one click
just write what you want and Fire...
you can send more than 140 characters to all networks including Twitter.


Sign in with your account to 11 social networks:
RapidFire social networks


RapidFire supports the following networks and blogs:

  1. Facebook.
  2. Twitter.
  3. LinkedIn.
  4. Tumblr.
  5. My Space.
  6. Google Buzz.
  7. WordPress.
  8. last. fm.
  9. Foursquare.
  10. Friendfeed.
  11. idetni.ca.
Take photos and include them with your message instantly:

RapidFire supports the following image services:
  1. YFrog.
  2. Mobypicture.
Say what you want even from your home screen:


share your thoughts even from your phone's home screen.


Upgrade to the Pro version and enjoy more features:


Geo-tagging: link your posts with your locations:


Ad-free:


And a last word for developers:
RapidFire is an excellent example of the application that can wrap many different APIs and provide an easy way to access them seamlessly. in such a case that you have multiple social networks APIs, it's important to isolate the user from the complications of each one through such an abstraction.

Reactions: 

Android Developers Blog: New Editing Features in Eclipse plug-in for Android

Android Developers Blog: New Editing Features in Eclipse plug-in for Android

Reactions: 

Connecting to a web service over a Secure Sockets Layer (SSL): protocol:

Android default HttpClinet does not support SSL connections, so if you have a secured web service, you need to connect to it via javax.net.ssl.HttpsURLConnection.
if you want to call a SSL SOAP web service:
String CallWebService(String url,
    String soapAction,
   String envelope) throws IOException  {
  URL address=new URL(url);
  URLConnection connection=address.openConnection();
  HttpsURLConnection post=(HttpsURLConnection)connection;
  post.setDoInput(true);
  post.setDoOutput(true);
  post.setRequestMethod("POST");
  post.setRequestProperty("SOAPAction", soapAction);
  post.setRequestProperty( "Content-type", "text/xml; charset=utf-8" );
  post.setRequestProperty( "Content-Length", String.valueOf(envelope.length()));
  post.setReadTimeout(4000);
  
  OutputStream outStream=post.getOutputStream();
  Writer out=new OutputStreamWriter(outStream);
  out.write(envelope);
  out.flush();
  out.close();
  
  
  InputStream inStream = post.getInputStream();
  BufferedInputStream in = new BufferedInputStream(inStream,4);
  StringBuffer buffer=new StringBuffer();
  // read 4 bytes a time
  byte[] buffArray=new byte[4];
  int c=0;
   while((c=in.read(buffArray))!=-1){
    for(int i=0;i<c;i++)
     buffer.append((char)buffArray[i]);
   }

   return buffer.toString();
 }

Reactions: 

Calling SOAP Web Services with Android APIs

One of the most common functionalities required in mobile applications is to call a web service to retrieve data. This process involves requesting the web service with parameters, receiving the response and parsing it to obtain data.
Today the most common web services types are SOAP and REST. Android does not provide a built in SOAP client, there are many third party libraries that can be used, but we'll see how to call a SOAP web service with native android APIs.

Requesting SOAP web service:
Before proceeding to the code, let's take a look at the SOAP structure:


a soap request can be something like this:

POST /InStock HTTP/1.1
Host: www.example.org
Content-Type: application/soap+xml; charset=utf-8
Content-Length: length
SOAPAction: "http://www.w3schools.com/GetItems"

<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
<soap:Header>
  <m:Trans xmlns:m="http://www.w3schools.com/transaction/"
  soap:mustUnderstand="1">234
  </m:Trans>
</soap:Header>
<soap:Body>
  <m:GetPrice xmlns:m="http://www.w3schools.com/prices">
    <m:Item>Apples</m:Item>
  </m:GetPrice>
</soap:Body></soap:Envelope>


the SOAP request/response is sent as a SOAP Envelope which consists of a SOAP Header and a SOAP Body.

  1. SOAP Header: optional component of the envelop, contains application specific information, such as authentication.
  2. SOAP Body: the actual message sent to/received from the service.
  3. The header can contain a SOAP Action which identifies the desired function to be called by the service.
Calling the service:
to call the SOAP web service you have to do the following:
First: construct the SOAP envelope manually like this:
String envelope="<?xml version=\"1.0\" encoding=\"utf-8\"?>"+
"<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"+
  "<soap:Body>"+
    "<GetItems xmlns=\"http://tempuri.org/\">"+
      "<startDate>%s</ startDate>"+
      "<getAll>%s</getAll>"+
    "</Items>"+
  "</soap:Body>"+
"</soap:Envelope>";

where %s are place holders where you substitute request parameters in like this
String requestEnvelope=String.format(envelope, "10-5-2011","true");


Second: call the web service like this:
String CallWebService(String url,
    String soapAction,
   String envelope)  {
  final DefaultHttpClient httpClient=new DefaultHttpClient();
  // request parameters
  HttpParams params = httpClient.getParams();
     HttpConnectionParams.setConnectionTimeout(params, 10000);
     HttpConnectionParams.setSoTimeout(params, 15000);
     // set parameter
  HttpProtocolParams.setUseExpectContinue(httpClient.getParams(), true);
  
  // POST the envelope
  HttpPost httppost = new HttpPost(url);
  // add headers
     httppost.setHeader("soapaction", soapAction);
     httppost.setHeader("Content-Type", "text/xml; charset=utf-8");
     
     String responseString="";
     try {
      
      // the entity holds the request
   HttpEntity entity = new StringEntity(envelope); 
   httppost.setEntity(entity);
   
   // Response handler
   ResponseHandler rh=new ResponseHandler() {
    // invoked when client receives response
    public String handleResponse(HttpResponse response)
      throws ClientProtocolException, IOException {
     
     // get response entity
     HttpEntity entity = response.getEntity();
     
     // read the response as byte array
           StringBuffer out = new StringBuffer();
           byte[] b = EntityUtils.toByteArray(entity);
           
           // write the response byte array to a string buffer
           out.append(new String(b, 0, b.length));        
           return out.toString();
    }
   };
   
   responseString=httpClient.execute(httppost, rh); 

  } 
     catch (Exception e) {
      Log.v("exception", e.toString());
  }
  
     // close the connection
  httpClient.getConnectionManager().shutdown();
  return responseString;
 }

after calling this function, you will have the response as a String, something like this:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <GetItemsResponse xmlns="http://tempuri.org/">
      <GetItemsResult>
        
        <Items>
          <Item>
            <name>string</name>
            <description>string</ description >
          </iPhoneCategory>
          <iPhoneCategory>
            <name>string</name>
            <description>string</ description >
          </ Item >
        </Items>
      </GetItemsResult>
    </ GetItemsResponse >
  </soap:Body>
</soap:Envelope>


this response needs to be parsed to extract the data.

Reactions: 

Calling REST Web Services with Android.

Requesting REST web service:   you request REST web services by calling a URL with the parameters. like this
http://example.com/resources/getitems

an example of calling a REST web service:
String callWebErvice(String serviceURL){
  // http get client
         HttpClient client=new DefaultHttpClient();
         HttpGet getRequest=new HttpGet();
         
         try {
          // construct a URI object
    getRequest.setURI(new URI(serviceURL));
   } catch (URISyntaxException e) {
    Log.e("URISyntaxException", e.toString());
   }
         
   // buffer reader to read the response
         BufferedReader in=null;
         // the service response
         HttpResponse response=null;
   try {
    // execute the request
    response = client.execute(getRequest);
   } catch (ClientProtocolException e) {
    Log.e("ClientProtocolException", e.toString());
   } catch (IOException e) {
    Log.e("IO exception", e.toString());
   }
         try {
    in=new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
   } catch (IllegalStateException e) {
    Log.e("IllegalStateException", e.toString());
   } catch (IOException e) {
    Log.e("IO exception", e.toString());
   }
         StringBuffer buff=new StringBuffer("");
         String line="";
         try {
    while((line=in.readLine())!=null)
    {
     buff.append(line);
    }
   } catch (IOException e) {
    Log.e("IO exception", e.toString());
    return e.getMessage();
   }
         
         
         try {
    in.close();
   } catch (IOException e) {
    Log.e("IO exception", e.toString());
   }
         // response, need to be parsed
         return buff.toString();
 }

Reactions: 

Official Google Blog: Coming soon: make your phone your wallet

Official Google Blog: Coming soon: make your phone your wallet

Reactions: 

Using Android Preferences

We saw before that we can persist an application's data using SQLite database. Android offers another way to store user's data through using preferences.

Android preferences is a key/value entries that store data that can be specific to a certain activity or shared among all activities within the application.
the data are stored in a xml file.

Saving Preferences

We can save preferences in three ways:

  1. Preferences can be retrieved only by a single activity.
  2. Preferences can be shared and retrieved among all activities within the application.
  3. Preferences can be shared and retrieved through all applications on the device.
Saving Activity-level preferences:
to save preferences that are accessed only from a single activity, we do it like this:
SharedPreferences prefs=getPreferences(Context.MODE_PRIVATE);
        SharedPreferences.Editor editor=prefs.edit();
        editor.putString("pref 1", "some text");
        
        editor.commit();

we get a SharedPreferences object by calling getPreferences(int mode) method which takes an integer value as a parameter, the mode value can be one of the following:

  1. Context.MODE_PRIVATE (0): a file creating mode that makes the created file only accessible by applications with the same user ID (access the file from the same application context, will desctribe later).
  2. Context.MODE_WORLD_READABLE (1): file mode makes the file readable from other applications.
  3. Context.MODE_WORLD_WRITEABLE (2): file mode allows other applications to write to the file.
then we get an instance of SharedPreferences.Editor and write the preference value with editor.putString(String key, String value) method.
shared preferences allows you to insert preferences using the following methods:
  1. editor.putBoolean(String key, boolean value).
  2. editor.putFloat(String key,float value).
  3. editor.putInt(String key, int value).
  4. editor.putLong(String key, long value)
  5. editor.putString(String key, String value)
then we call edit.commit() to save the preferences to the file. commit returns a boolean indicating the result of saving, true if successful and false if failed.

Reading preferences values:
To read preferences values:
SharedPreferences prefs=getPreferences(Context.MODE_PRIVATE);
String val=prefs.getString("pref 1", "some text");
we use sharedpreferences.getString(String key, String defaultValue) (or get boolean/float/int) to return the value stored with a specific key or defaultValue if not found.

Saving Application-level preferences:
to save preferences that can be retrieved from all activities in the application we do it like this:
SharedPreferences prefs= getSharedPreferences("demopref", Context.MODE_WORLD_READABLE);
        SharedPreferences.Editor editor=prefs.edit();
        editor.putString("demostring", "hello");
        editor.commit();

same as the code above, but the difference is that we give our preferences file a name (demopref in this case) so that other activities can reference that preferences file.
Sharing preferences across applications:


We can store preferences in one application and read them in another application, this is done reading the preferences file by loading them through the first application's context.

let's assume we have two applications:

  1. Application 1 with package name "com.mina.prefdemo".
  2. Application2 with package name "com.mina.demoapp".
If application1 creates a preferences file with the name "demopref" and inserts a String preference with the key/value "demostring/hello".

now we access this file and value from application 2 like this:
Context con;
  try {
   con = createPackageContext("com.minasamy.prefdemo", 0);
   SharedPreferences pref=con.getSharedPreferences("demopref", Context.MODE_PRIVATE);
   String x=pref.getString("demostring", "not found");
   txt.setText(x);
  } catch (NameNotFoundException e) {
   Log.e(Tag, e.toString());
  }

Creating Preferences Activities:
android provides another nice way of presenting and saving preferences. you can create Activities that extend PreferenceActivity.
PreferenceActivity is an activity that displays a set of built-in preferences related widgets that are defined in xml file.

the preference activity can be divided to several PreferenceCategory each containing a set of related preferences.
The preferences widgets that Android provide are:

  1. CheckBoxPreference: displays a check box widget.
  2. EditTextPreference: displays an EditText widget to save user prefs.
  3. RingtonePreference: displays a list with the  ringtones on the device.
  4. ListPreference: displays a list of key/value items.
each one of these preferences widgets is associated with a preference key. it's value is persisted instantly as the widget selection changes.

we can construct our preferences screen xml (saved in res/xml directory) layout like this:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
  xmlns:android="http://schemas.android.com/apk/res/android">
    <PreferenceCategory 
    android:title="Catogory one" 
    android:summary="sample summary">
        <CheckBoxPreference
         android:title="Enable" 
         android:key="pref_enable" 
         android:summary="enables a preference"/>
        <EditTextPreference 
        android:summary="Edit text prefrence" 
        android:title="Edit" 
        android:key="pref_edit"/>
        
        
    </PreferenceCategory>
    <PreferenceCategory 
    android:title="Category2" 
    android:summary="sample summary">
        <RingtonePreference 
        android:key="pref_ring" 
        android:title="Ringtones preference"/>
        
        <ListPreference 
        android:key="pref_list" 
        android:title="List Preference" 
        android:dialogTitle="List Pref Dialog" 
        android:entries="@array/pref_items" 
        android:entryValues="@array/pref_items_values"/>
    </PreferenceCategory>


then from our activity:
public class PrefActivity extends PreferenceActivity {
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  addPreferencesFromResource(R.xml.prefs);
  
 }
}

and the activity will look like this:





the ListPreference can be associated with String array resources as it's key/value entries
<string-array name="pref_items">
    <item>Item1</item>
    <item>Item2</item>
    <item>Item3</item>
    <item>Item4</item>
    <item>Item5</item>
    </string-array>
    
    <string-array name="pref_items_values">
    <item>1</item>
    <item>2</item>
    <item>3</item>
    <item>4</item>
    <item>5</item>
    </string-array>


to reference the preference widgets programmatically:
EditTextPreference pref_edit=(EditTextPreference)findPreference("pref_edit");

Reactions: 

The Difference between Handler and AsyncTask


After we saw both Handlers and AsyncTasks a question may evolve: what's the difference between the two and when to use one of them over the other ?

The Handler is associated with the application's main thread. it handles and schedules messages and runnables sent from background threads to the app main thread.

AsyncTask provides a simple method to handle background threads in order to update the UI without blocking it by time consuming operations.

The answer is that both can be used to update the UI from background threads, the difference would be in your execution scenario. You may consider using handler it you want to post delayed messages or send messages to the <strong>MessageQueue</strong> in a specific order.

You may consider using AsyncTask if you want to exchange parameters (thus updating UI) between the app main thread and background thread in an easy convinient way.

Reactions: 

Google to Unveil Service to Let Users Stream Their Music

Google will announce today on Google I/O 2011 it's long anticipated Cloud-based music service.

Reactions: 

Threading in Android part 2: Async Tasks

In the previous post we saw one way to deal with threads in Android, which is by using Handlers. In this post we'll see how to use another technique which is using AsyncTask class.

AsyncTask is an abstract class that provides several methods managing the interaction between the UI thread and the background thread. it's implementation is by creating a sub class that extends AsyncTask and implementing the different protected methods it provides.

Let's demonstrate how to user AsyncTask by creating a simple activity that has two buttons and a progress bar:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:orientation="vertical"
  >
  <Button
  android:id="@+id/btn"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:text="Show Progress"
  ></Button>
  <ProgressBar
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:id="@+id/progress"
  style="?android:attr/progressBarStyleHorizontal"
  ></ProgressBar>
  <Button
  android:id="@+id/btnCancel"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:text="Cancel"
  ></Button>
</LinearLayout>
Here we have two buttons: one to start progress and the other to stop it.

Creating the AsyncTask sub class:
The first step in implementing AsyncTask is to create a sub class like this:
class ProgressTask extends AsyncTask<Params, Progress, Result>{
}
The AsyncTask declaration has three Varargs parameters which are:
  1. Params: parameter info passed to be used by the AsyncTask.
  2. Progress: the type of progress that the task accomplishes.
  3. The result returned after the AsyncTask finishes.
These parameters are of type Varargs which provide the flexibility to pass dynamic sized arrays as parameters.

In our example our class will be like this:
class ProgressTask extends AsyncTask<Integer, Integer, Void>{
}

The parameter and the progress are of type Integer and the result is Void as our tasks does not return anthing (returns null).
The second step is overriding the protected methods defined by the AsyncTask class that handle the execution life cycle of the AsyncTask.

We have five methods to implement which are:
  1. onPreExecute: the first method called in the AsyncTask, called on the UI thread.
  2. doInBackground: the method that executes the time consuming tasks and publish the task progress, executed in background thread.
  3. onProgressUpdate: method that updates the progress of the AsyncTask, run on the UI thread.
  4. onPostExecute: the final method that gets called after doInBackground finishes, here we can update the UI with the results of the AsyncTask.
  5. onCancelled: gets called if the AsyncTask.cancel() methods is called, terminating the execution of the AsyncTask.

Starting the AsyncTask:
To start the AsyncTask we create an instance of it, then call the execute() method passing the initial parameters like this:
ProgressTask task=new ProgressTask();
// start progress bar with initial progress 10
task.execute(10);
Implementing the AsyncTask:
class ProgressTask extends AsyncTask<Integer, Integer, Void>{

  @Override
  protected void onPreExecute() {
   // initialize the progress bar
   // set maximum progress to 100.
   progress.setMax(100);

  }

  @Override
  protected void onCancelled() {
   // stop the progress
   progress.setMax(0);

  }

  @Override
  protected Void doInBackground(Integer... params) {
   // get the initial starting value
   int start=params[0];
   // increment the progress
   for(int i=start;i<=100;i+=5){
    try {
     boolean cancelled=isCancelled();
     //if async task is not cancelled, update the progress
     if(!cancelled){
      publishProgress(i);
      SystemClock.sleep(1000);

     }

    } catch (Exception e) {
     Log.e("Error", e.toString());
    }

   }
   return null;
  }

  @Override
  protected void onProgressUpdate(Integer... values) {
   // increment progress bar by progress value
   progress.setProgress(values[0]);

  }

  @Override
  protected void onPostExecute(Void result) {
   // async task finished
   Log.v("Progress", "Finished");
  }

 }

Here are the steps:
  1. onPreExecute() method first gets called initializing the maximum value of the progress bar.
  2. doInBackground(Integer... params) methods gets called by obtaining the initial start value of the progress bar then incrementing the value of the progress bar every second and publishing the progress as long as the async task is not cancelled.
  3. onProgressUpdate(Integer... values) method is called each time progress is published from doInBackground, thus incrementing the progress bar.
  4. onPostExecute(Void result) is called after doInBackground finished execution.
  5. void onCancelled() is called if task.cancel(true) is called from the UI thread. it may interrupt the execution preventing onPostExecute from being executed.

The onClick handler of our buttons is like this:
@Override
 public void onClick(View v) {
  ProgressTask task=new ProgressTask();
  switch(v.getId()){
  case R.id.btn:
   task.execute(10);
   break;
  case R.id.btnCancel:
   task.cancel(true);
   break;
  }

 }

Reactions: 

Threading in Android part 1: Handlers

Multi-Threading concept is essential in most platforms. it provides maximum

utilization of the processor. threading is used when the program executes

time consuming processes (such as calling a web service) and to give a

good user experience by unblocking the UI.

Android provides threading techniques to perform time consuming tasks in a

background thread with coordination with the UI thread to update the UI.

Android provides the following methods of threading:
  1. Handlers.
  2. Async. Tasks.
Handlers:
When you create an object from the Handler class, it processes

Messages and Runnable objects associated with the

current thread MessageQueue. the message queue holds the

tasks to be executed in FIFO (First In First Out) mannser. you will need

only ine Handler per activity where the background thread will

communicate with to update the UI.

The Handler is associated with the thread from which it's been created

We can communicate with the Handler by two methods:
  1. Messages.
  2. Runnable objects.
In this post we will demonstrate how to use both using a simple example which is

updating the text of a TextView using multiple threads.

Using Messages:

the steps of using a Handler are as follows:
  1. You create a Handler object with an asscociated callback

    method to handle the received messages (it is the method where the UI update

    will be done).
  2. From the background thread you will need to send messages to the

    handler.
Here's the code of our activity:
public class MainActivity extends Activity {
TextView txt;
// our handler
 Handler handler = new Handler() {
  @Override
  public void handleMessage(Message msg) {
//display each item in a single line
  txt.setText(txt.getText()+"Item "+System.getProperty("line.separator"));
     }
 };

 /** Called when the activity is first created. */
 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
  txt=(TextView)findViewById(R.id.txt);
 }
 
 @Override
 protected void onStart() {
  super.onStart();
              // create a new thread
  Thread background=new Thread(new Runnable() {
   
   @Override
   public void run() {
    for(int i=0;i<10;i++)
    {
     try {
      Thread.sleep(1000);        b.putString("My Key", "My Value: 

"+String.valueOf(i));
// send message to the handler with the current message handler          

handler.sendMessage(handler.obtainMessage());
     } catch (Exception e) {
      Log.v("Error", e.toString());
     }
    }
   }
  });
  
  background.start();
 }
}
after running the following code the TextView will display the following,

each second a new line is written:

This example is pretty basic, it just sends the same message for a number of

times.
what if we want the message sent to hold data that's changed each time the

message is sent, the answer is to use Message.setData(Bundle bundle)

method by creating a Bundle object and adding the data to it like this:
public class MainActivity extends Activity {
 TextView txt;
 // our handler
 Handler handler = new Handler() {
  @Override
  public void handleMessage(Message msg) {
   // get the bundle and extract data by key
   Bundle b = msg.getData();
   String key = b.getString("My Key");
   txt.setText(txt.getText() + "Item " + key
   +System.getProperty("line.separator"));
  }
 };

 /** Called when the activity is first created. */
 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
  txt = (TextView) findViewById(R.id.txt);
 }

 @Override
 protected void onStart() {
  super.onStart();
  // create a new thread
  Thread background = new Thread(new Runnable() {

   @Override
   public void run() {
    for (int i = 0; i < 10; i++) {
     try {
      Thread.sleep(1000);
                                        Message msg = new Message();
      Bundle b = new Bundle();
      b.putString("My Key", "My Value: " + String.valueOf(i));
      msg.setData(b);
      // send message to the handler with the current message handler
      handler.sendMessage(msg);
           } catch (Exception e) {
      Log.v("Error", e.toString());
     }
    }
   }
  });

  background.start();
 }
}
we put a string to the bundle and send a message with that bundle. in the

handler method we receive the bundle and get the value with the predefined key.
after executing that code the text view would look like this:

Using Runnables:
another way to use Handlers is to pass them a Runnable by using the

Handler.post() method like this:
Runnable r=new Runnable() {
   
   @Override
   public void run() {
    txt.setText("Runnable");
    
   }
  };
  
  handler.post(r);

this will add the Runanble object to the message queue to be executed by

the handler.

Sending Messages in a

timely manner:
we can use handlers to send messages or post runnables at time intervals using

the following methods:

  1. handler.sendEmptyMessageAtTime(int what,long uptimeMillis):sends an
     empty message at a specific time in milli-seconds, can be defined by using the
    SystemClock.uptimeMillis() method to get the time since the device boot
     in milli-seconds and concatinating to it.
  2. handler.sendEmptyMessageDelayed(int what,long delayMillis):sends an
     empty message after a certain amount of time in milli-seconds.
  3. handler.sendMessageAtTime(Message msg,long uptimeMillis).
  4. handler.sendMessageDelayed(Message msg,long delayMillis).
  5. handler.postAtTime(Runnable r,long uptimeMillis).
  6. handler.postAtTime(Runnable r,Object token,long uptimeMillis):posts a
     runnable with an object as a distinguishing token.
  7. handler.postDelayed(Runnable r,long delayMillis).
All the above messages return a boolean indicating whether the message or the

runnable has been placed successfully in the message queue.

Removing Call backs:
if you want to remove a runnable or a message from the message queue, you can

use the following methods:

  1. handler.removeCallbacks(Runnable r).
  2. handler.removeCallbacks(Runnable r,Object token).
  3. handler.removeCallbacksAndMessages(Object token).
  4. handler.removeMessages(int what).
  5. handler.removeMessages(int what,Object object)

Reactions: 

Forbes Blog: Open Thread: Why Won’t Android Crush Apple’s iOS? (Like The PC Crushed The Mac).

What do you think of this ?

Reactions: 

Android 3.0 (Honeycomb) Overview

Google released it's tablet-targeted Android version 3.0 (Honeycomb) with a totally new interdace and concepts.
here are the major updates:
  • API level: 11.

Action Bar:
a new concept instead of the old title bar, very si,ilar to the task bar in Windows

Fragments API:
the Fragment is a new component allowing you to construct an Activity from multiple separate activities or from several invisible worker services.


System Clipboard:
The system provides more copy-paste capabalities, allowing the user to copy text, urls, images or any user-defined type through content providers.

Drag and Drop
The drag and drop operation enables you to move data in a visualized way. giving you the control over the diferrent drag and drop events.

App widgets:
Android 3.0 supports several new widget classes for more interactive app widgets on the users Home screen, including: GridView, ListView, StackView, ViewFlipper, and AdapterViewFlipper.

Status bar notifications:
new notifications system including the ability to configure the notification layouts and notifications large icons.
Content Loaders:
new API to load data asynchronously using the Loader class.

New UI and Graphics frameworks.

for more info regadring the honeycomb sdk please refer to this link.

Reactions: 

Android Eclipse LogCat showing a singe Line only at a time

The LogCat shows different device events. In Eclipse sometimes you notice that only a single line is shown and you can't scroll to see previous events. This happens because the LogCat window gets full, so clearing it will give the window a new emty space to display the log events as usual.

Reactions: 

Android emulator too large

sometimes after installing Android sdk and launching the emulator you find that the emulator is too large that some of it may be invisible.

to correct this do the following:
  1. from  eclipse go to Run->Run configurations.
  2. from the left pane choose your project name and from the right pane choose the target tab.
  3. you will see a list of available virtual devices. choose yours and you'll find below the Additional Emulator Options section.
  4. enter the following command  -scale 0.7, where 0.7 is the ratio between the emulator size and your screen size.
  5. run the project and the emularot size will be adjusted to your screen

Reactions: 

android Conversion to Dalvik format failed with error 1

I got this error in an Android project in which I referenced anexternal JAR library.
I solved this by cleaning the project by navigating to Project->Clean and cleaning the project.

Reactions: 

SDK setup error: a folder failed to be renamed or moved

During updating your Android SDK components from eclipse (running in windows) you may receive the following error message:
a folder failed to be renamed or moved...

the message suggests that you turn of your anti-virus.
I did so but still recieved the error.
I terminated the adb.exe from the processes but still not solved.

the problem is that the update batch is rin from android.bat file inside tools directory. update requires that this folder is renamed temporarily but since Windows 7 locks it the process halts with this error.
so a workaround for this is to copy the tools folder, paste it in te sdk directory, name it tools_temp for example and run android.bat from this directory.

the update shall go smooth, after finishing delete this temp folder and launch eclipse and it will work fine.

note:
after restarting eclipse you may recieve this error
This Android SDK requires Android Developer Toolkit version 10.xxxxxxxxxx the current version is 9.xxxxxxxxxxxxxx.

this is because the ADT plugin needs to be update after updating software components, go to http://developer.android.com/sdk/eclipse-adt.html and follow the instructions and everything will work after this.

Reactions: 

Building Android Content Providers

Content providers are the way that Android applications can share info between each other. an application can ask for info from another application using content providers.

In this post we're going to create a content provider to access data from our previous Employees simple application from the SQLite post.

to remind you the database has two tables Employees and Dept

remember that any content provider must provide the following:
  1. A URi from which we can run queries.
  2. MIME type corresponding to the content.
  3. Insert() method.
  4. Update() methd.
  5. Delete() method.

Creating the content type:

first we will create a new class, I will call it EmployeesContentProvider and choose its super class to be ContentProvider. the class initially will be like this:
package mina.android.DatabaseDemo;

import android.content.ContentProvider;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;

public class EmployeesContentProvider extends ContentProvider {
DatabaseHelper db;
public static final Uri CONTENT_URI=Uri.parse("content://employees");
 @Override
 public int delete(Uri arg0, String arg1, String[] arg2) {
  // TODO Auto-generated method stub
  return 0;
 }

 @Override
 public String getType(Uri uri) {
  // TODO Auto-generated method stub
  return null;
 }

 @Override
 public Uri insert(Uri uri, ContentValues values) {
  // TODO Auto-generated method stub
  return null;
 }

 @Override
 public boolean onCreate() {
  // TODO Auto-generated method stub
  return false;
 }

 @Override
 public Cursor query(Uri uri, String[] projection, String selection,
   String[] selectionArgs, String sortOrder) {
  // TODO Auto-generated method stub
  return null;
 }

 @Override
 public int update(Uri uri, ContentValues values, String selection,
   String[] selectionArgs) {
  // TODO Auto-generated method stub
  return 0;
 }

}


we added a member of type DatabaseHelper db to hold a reference to our database.
also we added a static URi object that represents the URi of our content provider.
it has all the abstract methods implementations of the ContentProvider class. so let's check each method

onCreate() method:

the onCreate() method is the first method invoked when the content provider is created (similar to the Activity's onCreate() method). here you can load your database or check for files you may read/write to them.
the method return a Boolean. it should be true if everything is ok, otherwise it should be false.
in our case we will just reference our SQLite database:
@Override
 public boolean onCreate() {
  // TODO Auto-generated method stub
  db=new DatabaseHelper(this.getContext());
  if(db==null)
   return false;
  else
   return true;
 }

query() method:

the query() method is the method that gets invoked when a content provider data is requested by a URi.

but first let's talk a little about content providers URI.
the content provider URi has the following format:
content://Authority/[(n) path]/[instance indentifier]
explanation:
  • the URI starts with content:// scheme.
  • the authority is a unique identifier for the content provider.
  • the authority can be followed by one or more paths (optional) refer to data paths within the content.
  • there can be an instance identifier that refers to a specific data instance.
for example we can have a URi like this content://Employees/Marketing//11.
this URi has Employees as the authority, Marketing as a data path and 11 as an instance (employee) identifier.

back to our query method, we have the following parameters:
  1. Uri: the URi requested.
  2. String [] projection: representing the columns (projection) to be retrieved.
  3. String[] selection: the columns to be included in the WHERE clause.
  4. String[] selectionArgs: the values of the selection columns.
  5. String sortOrder: the ORDER BY statement.
the first step in our query method is to parse the client URi.
we expect the URi to be in one of the following forms:
  1. content://employees/: retrieves all employees.
  2. content://employees/id: retrieves a certain employee by ID.
  3. content://employess/IT: retreives employees of IT Dept.
  4. content://employess/HR: retrieves employees of HR Dept.
  5. content://employees/Sales: retreives employees of sales Dept.
so we will add some constatnt values to our class to refer to the above URis:
//authority and paths
 public static final String AUTHORITY="employees";
 public static final String ITPATH="IT";
 public static final String HRPATH="HR";
 public static final String SALESPATH="Sales";
 
 
 //URiMatcher to match client URis
 public static final int ALLEMPLOYEES=1;
 public static final int SINGLEEMPLOYEE=2;
 public static final int IT=3;
 public static final int HR=4;
 public static final int SALES=5;
then we're going to define a URiMatcher object that matches the client URi
static final UriMatcher matcher=new UriMatcher(UriMatcher.NO_MATCH);
 static{
  matcher.addURI(AUTHORITY,null,ALLEMPLOYEES);
  matcher.addURI(AUTHORITY, ITPATH, IT);
  matcher.addURI(AUTHORITY, HRPATH, HR);
  matcher.addURI(AUTHORITY, SALESPATH, SALES);
  //you can use '*' as a wild card for any text
  matcher.addURI(AUTHORITY, "#", SINGLEEMPLOYEE);
 }
the static initializer block loads the URimatcher objects with the values to match when the class initializes.
so let's write our query method:
@Override
 public Cursor query(Uri uri, String[] projection, String selection,
   String[] selectionArgs, String sortOrder) {
  SQLiteQueryBuilder builder=new SQLiteQueryBuilder();
  
  builder.setTables(DatabaseHelper.viewEmps);
  
  String order=null;
  Cursor result=null;
  if(sortOrder!=null)
   order=sortOrder;
  int match=matcher.match(uri);
  switch(match)
  {
  case ALLEMPLOYEES:
   //content://employees//id
   result=builder.query(db.getWritableDatabase(), projection, selection, selectionArgs, null, null, sortOrder);
   break;
  case SINGLEEMPLOYEE:
   //content://employees//id
   Listsegments=uri.getPathSegments();
   String empID=segments.get(0);
   result=db.getEmpByID(empID);

   break;
  case IT:
   //content://employees//IT
   result=db.getEmpByDept("IT");
   result=builder.query(db.getReadableDatabase(), projection, db.colDeptName+"=?", new String[]{"IT"}, null, null, sortOrder);
   break;
  case HR:
   //content://employees//HR
   result=db.getEmpByDept("HR");
   result=builder.query(db.getReadableDatabase(), projection, db.colDeptName+"=?", new String[]{"HR"}, null, null, sortOrder);
   break;
  case SALES:
   //content://employees//Sales
   result=db.getEmpByDept("Sales");
   result=builder.query(db.getReadableDatabase(), projection, db.colDeptName+"=?", new String[]{"Sales"}, null, null, sortOrder);
   
   break;
  
  }
  
  return result;
 }

the function just parses the URi and returns the data in a cursor.

Insert() method:
the insert methods inserts a new record to the db;
the insert method has the following form:
public Uri insert(Uri uri, ContentValues values) {
  
  return null;
 }
the method has two parameters:
  1. URi uri: the URi of the content provider, we need to check it's correct.
  2. ContentValues values: object holding the info of the new item to be inserted.
the method returns the URi of the newly inserted item to be used for further manipulations.
so here's the implentation:
@Override
 public Uri insert(Uri uri, ContentValues values) {
  int match=matcher.match(uri);
  //not the Uri we're expecting
  long newID=0;
  if(match!=1)
   throw new IllegalArgumentException("Wrong URi "+uri.toString());
  if(values!=null)
  {
   newID=db.getWritableDatabase().insert(DatabaseHelper.employeeTable, DatabaseHelper.colName, values);
   return Uri.withAppendedPath(uri, String.valueOf(newID));
   
  }
  else
   return null;
 }
we first check the Uri if it is not correct, throw an exception.
then check the content values object, if null return null otherwise insert the new item and return the URi with the id of the new item.
the Update() method:
the update method updates existing record(s) and returns the number of updated rows.
a trick rises from the fact that you need to specify whether to update a collection of records or a single record, based on the URi.
the method has the following parameters:
  1. URi uri: the URi of the content provider, we need to check it's correct.
  2. ContentValues values: object holding the info of the new item to be inserted.
  3. String Selection : the filter to match the rows to update
  4. String [] selectionArgs : the values of the filter parameters
here's the implementation of the update method:
@Override
 public int update(Uri uri, ContentValues values, String selection,
   String[] selectionArgs) {
  int match=matcher.match(uri);
  //not the Uri we're expecting
  int rows=0;
  //update single instance
  if(match==2)
  {
   if(values!=null)
   {
    Listsegments=uri.getPathSegments();
    String empID=segments.get(0);
    rows=db.getWritableDatabase().update(DatabaseHelper.employeeTable, values,DatabaseHelper.colID+"=?", new String []{empID});
    
   }
   
  }
  //update all emps in a certain dept
  else if(match==3 ||match==4||match==5)
  {
   Listsegments=uri.getPathSegments();
   String deptName=segments.get(0);
   int DeptID=db.GetDeptID(deptName);
   rows=db.getWritableDatabase().update(db.employeeTable, values,db.colDept+"=?", new String []{String.valueOf(DeptID)});
   
  }
   return rows;
 }
the Delete() method:
the delete method has the following parameters:
  1. Uri uri: the URi of the content provider.
  2. String Condition: the condition of the delete statement.
  3. String[] args: the delete condition arguments

so here's the implementation:
@Override
 public int delete(Uri uri, String where, String[] args) {
  
  int match=matcher.match(uri);
  //expecting the URi to be in the form of 
  if(match==1)
  {
   SQLiteDatabase dataBase=db.getWritableDatabase();
   return dataBase.delete(db.employeeTable, where, args);
  }
  else
  return 0;
 }
we just check for the URi and perform a delete command.
The getType() method:
the last mthod to implement is getType() method which returns the MIME type associated with the URi passed to it.
if the URi is of a group of employees, then the MIME type is a collection type, otherwise it's of an instance type
@Override
 public String getType(Uri uri) {
  int match=matcher.match(uri);
  // single employee
  if(match==2)
  {
   return "mina.android.Employee";
  }
  //collection of employees
  else
  {
   return "mina.android.Employees";
  }
 }
Modifying the Manifest.xml file:
the last thing we need to do is to add an entry in our application's manifest.xml file to register our class as a content provider class.
so add this entry just below the <application>
<provider android:name="mina.android.DatabaseDemo.EmployeesContentProvider" 
    android:authorities="employees"/>

the
when an application requests data through our content provider, Android system will search all the manifest files of all aplications on the device and when it finds such an entry, it will process the request

Testing the content provider:
now suppose you are in another activity and you want to use our activity.
Testing queries:
to make a query to retrieve all employees:
Uri empsUri=Uri.parse("content://employees");
Cursor cursor=getContentResolver().query(empsUri, null, null, null, null);Cursor cursor=getContentResolver().query(empsUri, null, null, null, null);
the cursor should have all the records.
to retrieve a certain employee by ID or all employees in a certain department:
Uri empUri=Uri.parse("content://employees//5");
Uri empDeptUri=Uri.parse("content://employees//Sales");

Inserting:
Uri empsUri=Uri.parse("content://employees");
ContentValues cvs=new ContentValues();
        cvs.put("EmployeeName", "Mark Anderson");
        cvs.put("Age", 35);
        cvs.put("Dept", 1);
        // URi of the new inserted item
        Uri newEmp=getContentResolver().insert(empsUri, cvs);

Updating:
to update a single employee:
//Uri with the id of the employee
Uri empsUri=Uri.parse("content://employees/8");
        
        Cursor cursor=getContentResolver().query(empsUri, null, null, null, null);
        txt.setText(String.valueOf(cursor.getCount()));
       
        ContentValues cvs=new ContentValues();
        cvs.put("EmployeeName", "Mina Samy mod");
        cvs.put("Age", 35);
        cvs.put("Dept", 1);
// number of rows modified
int rowsNumber=getContentResolver().update(empsUri, cvs, "EmployeeID=?", new String[]{"8"});
to update all employees in a certain department
Uri empsUri=Uri.parse("content://employees/Sales");
        
        Cursor cursor=getContentResolver().query(empsUri, null, null, null, null);
        txt.setText(String.valueOf(cursor.getCount()));
       
        ContentValues cvs=new ContentValues();
        cvs.put("EmployeeName", "mod");
        cvs.put("Age", 35);
        cvs.put("Dept", 1);
        int rowsNumber=getContentResolver().update(empsUri, cvs, "colDept=?", new String[]{"1"});

as a matter of fact, in both cases we don't need to specify the wher clause and the where parameters as they are implicitly specified in the URi. so we just can replace the update statement to be like this:
int rowsNumber=getContentResolver().update(empsUri, cvs, null,null);

Deleting:
I left the delete operation open to any criteria, you can delete a single employee or employees of a certain department or even all employees
Uri empsUri=Uri.parse("content://employees");
// delete employee of id 8
int rowsNumber=getContentResolver().delete(empsUri,"EmployeeID=?",new String[]{"8"});

Final Word:
creating a content provider for a certain type of data can be done in many ways, this example can be implemented in several variations.

another thing is that you need to create a strongly typed class for you data model to be used by clients accessing your content. in this example when I tested the query i wrote the column names of the database as strings like this: "EmployeeID" and "EmployeeName".
this is not ideal in a production release of an application. I should created a class library that holds all the info about the database to be used by other client applications.

you can download the source code for this example from here.

Reactions: