How to do JSON Parsing in Android?

JSON stands for JavaScript Object Notation.It is an independent data exchange format and is the best alternative for XML. All the responses from server are json encoded (if encoded i n PHP file). In order to parse them, following are the steps of JSON Parsing are:
1. For parsing a JSON object, we will create an object of class JSONObject and specify a string
containing JSON data to it.
2. An JSON file consist of different object with different key/value pair e.t.c. So JSONObject has a
seperate function for parsing each of the component of JSON file.

See the example below. It has json encoded string as:

  {
 "students": [
 {
 "name": "abc",
 "class": "xyz",
 "contact": {
 "email": "xyz@live.com",
 "phone": "1234567"
 }
 },
 {
 "name": "other student",
 "class": "other class",
 "contact": {
 "email": "abc@gmail.com",
 "phone": "456789"
 }
 }
 ]
}

You can check JSON valid string here : http://jsonlint.com

To parse this string, following is the code.

package com.example.jsonparse;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import org.json.JSONObject;
import org.json.JSONArray;
import org.json.JSONException;

import android.util.Log;

public class MainActivity extends Activity {
 
 /*
 * 
 * (non-Javadoc)
 * @see android.app.Activity#onCreate(android.os.Bundle)
 * 
 * 
 * {
 * "students":[
 * {
 * "name":"abc",
 * "class":"xyz",
 * "contact":{
 * "email":"xyz@live.com",
 * "phone":"1234567"
 * }
 * },
 * {
 * "name":"other student",
 * "class":"other class",
 * "contact":{
 * "email":"abc@gmail.com",
 * "phone":"456789"
 * }
 * }
 * ]
 * }
 * 
 * 
 */
 
 String jsonData = "{\"students\":[{ \"name\":\"abc\",\"class\":\"xyz\",\"contact\":{\"email\":\"xyz@live.com\",\"phone\":\"1234567\"}},{\"name\":\"other student\",\"class\":\"other class\",\"contact\":{\"email\":\"abc@gmail.com\",\"phone\":\"456789\"}}]}";

 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.main_layout);

 
 }


 @Override
 public boolean onCreateOptionsMenu(Menu menu) {
 
 // Inflate the menu; this adds items to the action bar if it is present.
 getMenuInflater().inflate(R.menu.main, menu);
 return true;
 }

 @Override
 public boolean onOptionsItemSelected(MenuItem item) {
 // Handle action bar item clicks here. The action bar will
 // automatically handle clicks on the Home/Up button, so long
 // as you specify a parent activity in AndroidManifest.xml.
 int id = item.getItemId();
 if (id == R.id.action_settings) {
 return true;
 }
 return super.onOptionsItemSelected(item);
 }
 
 public void onParseClick(View view)
 {
 JSONObject json = null;
 String TAG = "jsonParse";
 try {
 json = new JSONObject(jsonData);
 JSONArray myArray = json.getJSONArray("students");
 for (int i = 0 ; i < myArray.length() ; i++)
 {
 JSONObject myObj = myArray.getJSONObject(i);
 String name = myObj.getString("name");
 Log.d(TAG, "Name: "+name);
 String myclass = myObj.getString("class");
 Log.d(TAG, "Class: "+myclass);
 JSONObject contactDetails = myObj.getJSONObject("contact");
 String email = contactDetails.getString("email");
 Log.d(TAG, "Email: "+email);
 int phone = contactDetails.getInt("phone");
 Log.d(TAG,"Phone: "+phone);
 }
 }
 catch(JSONException e)
 {
 e.printStackTrace();
 return;
 }
 
 
 }
}

The output in log is:

jsonThats it. Continue to parse the json encoded response from the webserver and have fun ūüôā

Posted in Uncategorized | Leave a comment

How to Communicate With Web Server in Android?

In order to store the data filled by an android application user on the Web Server, you have to  follow the following steps:

  1. Declare Internet permissions in the manifest by adding the following line to AndroidManifest.xml.
     <uses-permission android:name="android.permission.INTERNET"/>
  2. Create your HttpClient and HttpPost objects to execute the POST request.HttpClient myClient = new DefaultHttpClient();
     HttpPost post = new HttpPost("http://192.168.43.165/login.php");
  3. Remember not to use localhost while giving IP address of server file. As it will act as localhost of your phone rather that server, and will not allow you to do whatever you want.
  4. Set your POST data. This is done by creating and setting a list of NameValuePairs as your Http-Post’s entity. Be sure to catch the UnsupportedEncodingException thrown by HttpPost.setEntity().Execute the POST request. This returns an HttpResponse object, whose data can be extracted and parsed. Be sure to catch the ClientProtocolException and IOException thrown.
List<NameValuePair> myArgs = new ArrayList<NameValuePair>();
 myArgs.add(new BasicNameValuePair("username", "priyanka"));
 myArgs.add(new BasicNameValuePair("password", "pass"));
 post.setEntity(new UrlEncodedFormEntity(myArgs));
  1. Execute the POST request. This returns an HttpResponse object, whose data can be extracted and
    parsed. Be sure to catch the ClientProtocolException and IOException thrown.
 HttpResponse myResponse = myClient.execute(post);

Now process the response, the way you want.

Following is simple program on making HTTP connection. You can see output on Logcat.

package com.example.connect2;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;


public class MainActivity extends Activity {

 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.main_layout);
 
 }
 
 public void onConnect(View view) {
 new Thread(){
 public void run(){
 HttpClient myClient = new DefaultHttpClient();
 HttpPost post = new HttpPost("http://192.168.43.165/login.php");
 try {
 List<NameValuePair> myArgs = new ArrayList<NameValuePair>();
 myArgs.add(new BasicNameValuePair("username", "priyanka"));
 myArgs.add(new BasicNameValuePair("password", "pass"));
 post.setEntity(new UrlEncodedFormEntity(myArgs));
 HttpResponse myResponse = myClient.execute(post);
 BufferedReader br = new BufferedReader( new InputStreamReader(myResponse.getEntity().getContent()));
 String line = "";
 while ((line = br.readLine()) != null)
 {
 Log.d("mytag", line);
 
 }
 }
 catch (IOException e) {
 e.printStackTrace();
 }
 }
 }.start();
 
 }
}

main_layout.xml

<?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/connect"
 android:text="connect"
 android:onClick="onConnect"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"/>
 
</LinearLayout>

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
 package="com.example.connect2"
 android:versionCode="1"
 android:versionName="1.0" >

 <uses-sdk
 android:minSdkVersion="15"
 android:targetSdkVersion="18" />
 
 <uses-permission android:name="android.permission.INTERNET"/>

 <application
 android:allowBackup="true"
 android:icon="@drawable/ic_launcher"
 android:label="@string/app_name"
 android:theme="@style/AppTheme" >
 <activity
 android:name="com.example.connect2.MainActivity"
 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>

</manifest>

On pressing connect button, you can see this output on browser:

connectNote: Always create a new thread to do networking task. Otherwise your application would crash.

PHP file at backend is as follow:

<?php
 
/*
 * Following code authenticate the user.
 * 
 */
 
 if(isset($_POST['username']) && isset($_POST['password'])){
 $username = $_POST['username'];
 $password = $_POST['password'];
 
 require_once __DIR__ . '/db_connect.php';
 
 // connecting to database
 $db = new DB_CONNECT();
 
 //Array for JSON response
 $response = array();
 $response['success']=-1;
 $response['user_data']=array();

 $user_data = array();
 
 $login = "SELECT * FROM gcmuser WHERE user='$username' AND pass='$password';";
 $result = mysql_query($login);
 
 // Mysql_num_row is Counting table row
 $count = mysql_num_rows($result);
 // if it matches it counts to be one 1
 if($count==1)
 {
 session_start();
 $session = array();
 //On Success
 $response['success']=1;
 $session['valid_user']=$username;
 if($username=="admin"){
 $user_data['user']=$username;
 $user_data['user_type']=1;
 $session['user_type']=1;
 }
 else{
 $user_data['user']=$username;
 $user_data['user_type']=2;
 $session['user_type']=2;
 }
 array_push($response['user_data'],$user_data);
 echo json_encode($response);
 
 }
 else
 {
 // On Failure
 $response['success']=0;
 $response['user_data']=null;
 echo json_encode($response);
 
 }

 }
?>

db_connect.php

<?php
 
/**
 * A class file to connect to database
 */
class DB_CONNECT {
 
 // constructor
 function __construct() {
 // connecting to database
 $this->connect();
 }
 
 // destructor
 function __destruct() {
 // closing db connection
 $this->close();
 }
 
 /**
 * Function to connect with database
 */
 function connect() {
 // import database connection variables
 require_once __DIR__ . '/db_config.php';
 
 // Connecting to mysql database
 $con = mysql_connect(DB_SERVER, DB_USER, DB_PASSWORD) or die(mysql_error());
 
 // Selecing database
 $db = mysql_select_db(DB_DATABASE) or die(mysql_error()) or die(mysql_error());
 
 // returing connection cursor
 return $con;
 }
 
 /**
 * Function to close db connection
 */
 function close() {
 // closing db connection
 mysql_close();
 }
 
}
 
?>

db_config.php

<?php
 
/*
 * All database connection variables
 */
 
define('DB_USER', "root"); // db user
define('DB_PASSWORD', "priyanka"); // db password (mention your db password here)
define('DB_DATABASE', "enotice"); // database name
define('DB_SERVER', "localhost"); // db server
?>

MySQL table is gcmuser which has user and pass fields containing username and passwords.

connect2

Thats all. ūüôā

Posted in Uncategorized | 2 Comments

How to delete SQLite Database from adb command line of Android?

1) Change to directory, platform-tools.

In my case, its

cd Music/adt-bundle-linux-x86-20140321/sdk/platform-tools/

List all items in it.

ls

It will show you adb executable file also.Give the following command.

adb shell

Your command prompt will change to

root@generic:/ #

Change to the directory /data/data

root@generic:/ # cd /data/data
root@generic:/data/data # ls
com.android.backupconfirm
com.android.browser
....
com.example.enoticeapp

You can see above the list of all android packages. Change to that package whose database you want to delete.

cd com.example.enoticeapp
ls

You can see databases entry. Change to databases and list it. It will show you all databases of your app.

cd databases
ls

Remove the database by giving the command:

rm enoticeapp

And you are done!

 

Posted in Uncategorized | Leave a comment

How to create simple (unbound) Service in Android?

 

Services in Android System

1) Faceless components: A service is a component which runs in the background without direct interaction with the user. As the service has no user interface, it is not bound to the lifecycle of an activity.

2) Taking care of long running background tasks: Services are used for repetitive and potentially long running operations, i.e., Internet downloads, checking for new data, data processing, updating content providers and the like.

3) Runs on UI Thread: By default a service runs in the same process as the main thread of the application.

Therefore you need to use asynchronous processing in the service to perform resource intensive tasks in the background. A common used pattern for a service implementation is to create and run a new Thread in the service to perform the processing in the background and then to terminate the service once it has finished the processing.

Services which run in the process of the application are sometimes called local services.

4)Unaffected by activity switching: Each Service has a specific job, and they keep at it if you switch between different Activities, or even if you switch to a different application altogether.

In Android a Service is used for two main reason:

  • Implement multi-task

  • Enable Inter-Process-Communication (IPC)

A typical example of the first case is an app that required to download data from a remote server, in this case we can have Activity that interacts with a user and starts a service that accomplishes the work in background while the user can use the app and maybe when the service finishes sends a message to the user.

In the second case, we want to ‚Äúshare‚ÄĚ some common functions so that different app can re-use them. For example, we can suppose we have a service that sends an email and we want to share this service among several apps so that we don‚Äôt have to rewrite the same code. In this case we can use IPC so that the service exposes a ‚Äúremote‚ÄĚ interface that can be called by other app.

service_lifecycle

Forms of Service

A Service can have two forms:

1) Started/Unbound: In this case, an application component starts the service by calling startService() , and it would continue to run in the background, even if the original component that initiated it is destroyed. For instance, when started, a service would continue to play music in the background indefinitely.

2) Bound: An Android component may bind itself to a Service using bindservice (). A bound service would run as long as the other application components are bound to it. As soon as they unbind, the service destroys itself.

An unbound activity runs indefinitely, whereas the lifespan of a bound activity depends on the application components that bind to it.

The following diagram on the left shows the lifecycle when the service is created with startService() and the diagram on the right shows the lifecycle when the service is created with bindService(): (image courtesy : android.com )

CallBacks of Service:

Callback Description
onStartCommand() The system calls this method when another component, such as an activity, requests that the service be started, by calling startService(). If you implement this method, it is your responsibility to stop the service when its work is done, by calling stopSelf() or stopService() methods.
onBind() The system calls this method when another component wants to bind with the service by calling bindService(). If you implement this method, you must provide an interface that clients use to communicate with the service, by returning an IBinder object. You must always implement this method, but if you don’t want to allow binding, then you should return null.
onUnbind() The system calls this method when all clients have disconnected from a particular interface published by the service.
onRebind() The system calls this method when new clients have connected to the service, after it had previously been notified that all had disconnected in its onUnbind(Intent).
onCreate() The system calls this method when the service is first created using onStartCommand() or onBind(). This call is required to perform one-time setup.
onDestroy() The system calls this method when the service is no longer used and is being destroyed. Your service should implement this to clean up any resources such as threads, registered listeners, receivers, etc.

onStartCommand() method has integer return type value which can be any of the following:

START_STICKY : Using this return value, if the OS kills our Service it will recreate it but the Intent that was sent to the Service isn’t redelivered. In this way the Service is always running

START_NOT_STICKY: If the OS kills the Service it won’t recreate it until the client calls explicitly onStart command

START_REDELIVER_INTENT: It is similar to the START_STICKY and in this case the Intent will be redelivered to the service.

Steps to Create a Simple Service:

This code starts and stops a simple service, plays a music in background.

1) Firstly create “raw” folder inside res folder and place music file in it. Here it is song.mp3

service1

2) Add the service in manifest file:

<service 
 android:name=".MyService"/>

3) Layout will contain two buttons play and stop. Play will start the service of playing music and Stop will stop the music.

(layout_main.xml)

<?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/button1"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:text="@string/play"/>
 <Button 
 android:id="@+id/button2"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:text="@string/stop"/>
 

</LinearLayout>

The MainActivity.java file calls the service on pressing the button:

package com.example.simpleservice;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Button;
import android.view.View;
import android.view.View.OnClickListener;

public class MainActivity extends Activity {

 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.layout_main);
 Button play,stop;
 play = (Button)findViewById(R.id.button1);
 play.setOnClickListener(new OnClickListener(){
 @Override
 public void onClick(View view){
 Intent myIntent = new Intent(MainActivity.this, MyService.class);
 startService(myIntent);
 }
 });
 
 stop=(Button)findViewById(R.id.button2);
 stop.setOnClickListener(new OnClickListener(){
 @Override
 public void onClick(View view){
 Intent myIntent = new Intent(MainActivity.this, MyService.class);
 stopService(myIntent);
 }
 });

 }
}

The main Service code resides in MyService.java file:

package com.example.simpleservice;

import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.IBinder;

public class MyService extends Service{
 String tag="MyService";
 MediaPlayer mp;
 
 @Override
 public IBinder onBind(Intent intent){
 return null;
 }
 @Override
 public void onCreate(){
 super.onCreate();
 mp = MediaPlayer.create(getApplicationContext(), R.raw.song);
 }
 
 @Override
 public int onStartCommand(Intent intent, int flags, int startId){
 mp.start();
 return START_STICKY;
 }
 
 @Override
 public void onDestroy(){
 mp.release();
 super.onDestroy();
 }

}

Its done. Click on play button to play the music and stop button to stop the music.

 

Posted in Uncategorized | Leave a comment

How to create Notifications in Android?

Notifications: A notification is a message you can display to the user outside of your application’s normal UI.

When you tell the system to issue a notification, it first appears as an icon in the notification area. To see the details of the notification, the user opens the notification drawer. Both the notification area and the notification drawer are system-controlled areas that the user can view at any time.

notify1

Notifications in the notification drawer can appear in one of two visual styles, depending on the version and the state of the drawer:

Normal view
The standard view of the notifications in the notification drawer.
Big view
A large view that’s visible when the notification is expanded. Big view is part of the expanded notification feature available as of Android 4.1.

These styles are described in the following sections.

Normal view

A notification in normal view appears in an area that’s up to 64 dp tall. Even if you create a notification with a big view style, it will appear in normal view until it’s expanded. This is an example of a normal view:

notify2

The callouts in the illustration refer to the following:

  1. Content title

  2. Large icon

  3. Content text

  4. Content info

  5. Small icon

  6. Time that the notification was issued. You can set an explicit value with setWhen(); if you don’t it defaults to the time that the system received the notification.

Big view

A notification’s big view appears only when the notification is expanded, which happens when the notification is at the top of the notification drawer, or when the user expands the notification with a gesture. Expanded notifications are available starting with Android 4.1.

The following screenshot shows an inbox-style notification:

notify3

Notice that the big view shares most of its visual elements with the normal view. The only difference is callout number 7, the details area. Each big view style sets this area in a different way. The available styles are:

Big picture style
The details area contains a bitmap up to 256 dp tall in its detail section.
Big text style
Displays a large text block in the details section.
Inbox style
Displays lines of text in the details section.

All of the big view styles also have the following content options that aren’t available in normal view:

Big content title
Allows you to override the normal view’s content title with a title that appears only in the expanded view.
Summary text
Allows you to add a line of text below the details area.

Steps to create Notification:

This example has an activity containing a button. Clicking on this button will create the notification in the notification bar. On expanding the notification, will give the details of notice and on tapping the detail will lead you to new activity.

Here are the files:

Specify a button in layout_main.xml file

<?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/button1"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:text="@string/notify"
 android:onClick="sendNotification"/>
 

</LinearLayout>

Here is the MainActivity.java code:

(Read comments inside code to have better understanding)

package com.example.simplenotification;

import android.app.Activity;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.NotificationCompat;
import android.view.View;


public class MainActivity extends Activity {

 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.layout_main);

 
 }

 public void sendNotification(View view){
 //Creating Notification Builders
 NotificationCompat.Builder myNotificationBuilder = new NotificationCompat.Builder(this);
 
 //Setting Notification properties
 myNotificationBuilder.setSmallIcon(R.drawable.ic_launcher);
 myNotificationBuilder.setContentTitle("First Notification");
 myNotificationBuilder.setContentText("This is a test notification");
 int notificationid = 3452;
 
 // Creates an explicit intent for an Activity in your app
 Intent myIntent = new Intent(this, ResultActivity.class);
 myIntent.putExtra("myNotificationId", notificationid);
 myIntent.putExtra("AnyValue", 12345);
 //myIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
  
 PendingIntent myPendingIntent = PendingIntent.getActivity(this, 0, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
 
 // start the activity when the user clicks the notification text
 myNotificationBuilder.setContentIntent(myPendingIntent);
 
 //Issue the Notification
 NotificationManager myManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
 myManager.notify(notificationid, myNotificationBuilder.build());
 }
}

The activity that  opens up on tapping the notification is:

import android.os.Bundle;
import android.widget.TextView;
import android.app.Activity;
import android.app.NotificationManager;
import android.content.Intent;

public class ResultActivity extends Activity {
 public void onCreate(Bundle savedInstanceState){
 super.onCreate(savedInstanceState);
 setContentView(R.layout.layout_result);
 TextView output = (TextView)findViewById(R.id.textView1);
 Intent myIntent = getIntent();
 int myNotificationId = myIntent.getIntExtra("myNotificationId",-1);
 
 //Removing notification from top after tap on notification
 if (myNotificationId != -1)
 {
 NotificationManager myManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
 myManager.cancel(myNotificationId);
 }
 output.setText("Data sent by first activity: "+myIntent.getIntExtra("AnyValue", -1));
 }
}

And you are done. ūüôā

 

See in code: You used pending intents. Following is the detail about pending intents.

A Pending Intent specifies an action to take in the future. It lets you pass a future Intent to another application and allow that application to execute that Intent as if it had the same permissions as your application, whether or not your application is still around when the Intent is eventually invoked.

It is a token that you give to a foreign application which allows the foreign application to use your application’s permissions to execute a predefined piece of code.
If you give the foreign application an Intent, and that application sends/broadcasts the Intent you gave, they will execute the Intent with their own permissions. But if you instead give the foreign application a Pending Intent you created using your own permission, that application will execute the contained Intent using your application’s permission.

To perform a broadcast via a pending intent so get a PendingIntent via PendingIntent.getBroadcast(). To perform an activity via an pending intent you receive the activity via PendingIntent.getActivity()

The reason it’s needed is because an Intent must be created and launched from a valid Context in your application, but there are certain cases where one is not available at the time you want to run the action because you are technically outside the application’s context (the two common examples are launching an Activity from a Notification or a BroadcastReceiver.

A PendingIntent provides a means for applications to work, even after their process exits. It€™s important to note that even after the application that created the PendingIntent has been killed, that Intent can still run. A description of an Intent and target action to perform with it. Instances of this class are created with getActivity(Context, int, Intent, int), getBroadcast(Context, int, Intent, int), getService (Context, int, Intent, int); the returned object can be handed to other applications so that they can perform the action you described on your behalf at a later time.

Ref: www.simplecodestuffs.com/what-is-pending-intent-in-android/

http://developer.android.com/guide/topics/ui/notifiers/notifications.html

 

Posted in Uncategorized | Leave a comment

How to use AsyncTask in Android?

Android implements single thread model and whenever an android application is launched, a thread is created. Assuming we are doing network operation on a button click in our application. On button click a request would be made to the server and response will be awaited. Due to single thread model of android, till the time response is awaited our screen is non-responsive. So we should avoid performing long running operations on the UI thread. This includes file and network access.

To overcome this we can create new thread and implement run method to perform this network call, so UI remains responsive.

But since Android follows single thread model and Android UI toolkit is not thread safe, so if there is a need to make some change to the UI based on the result of the operation performed, then this approach may lead some issues.

So the Android framework has given a very good pattern which is enveloped into AsyncTask.


Note: AsyncTask should ideally be used for operations that take few seconds. Some tasks keep the thread running for long time so in that case it is recommended to use java.util.concurrent package such as Executor, ThreadPoolExecutor and FutureTask.

AsyncTask :


 AsyncTask is an abstract class provided by Android which helps us to use the UI thread properly. The AsyncTask class encapsulates the creation of a background process and the synchronization with the main thread. It also supports reporting progress of the running tasks.

The most common methods you will need to implement are these:

1. onPreExecute() ‚Äď called on the UI thread before the thread starts running. This method is usually used to setup the task, for example by displaying a progress bar.

2. doInBackground(Params‚Ķ) ‚Äď this is the method that runs on the background thread. In this method you should put all the code you want the application to perform in background like Network access, file or database access.

3. onProgressUpdate() –It is called when you invoke publishProgress() in the doInBackground().

4. onPostExecute(Result) ‚Äď called on the UI thread after the background thread finishes. It takes as parameter the result received from doInBackground().

AsyncTask’s generic types


The three types used by an asynchronous task are the following:

  1. Params, the type of the parameters sent to the task upon execution.

  2. Progress, the type of the progress units published during the background computation.

  3. Result, the type of the result of the background computation.

Not all types are always used by an asynchronous task. To mark a type as unused, simply use the type Void:

private class MyTask extends AsyncTask<Void, Void, Void> { ... }

The 4 steps (Methods of AsyncTask)


When an asynchronous task is executed, the task goes through 4 steps:

  1. onPreExecute(), invoked on the UI thread before the task is executed. This step is normally used to setup the task, for instance by showing a progress bar in the user interface.

  2. doInBackground(Params...), invoked on the background thread immediately after onPreExecute() finishes executing. This step is used to perform background computation that can take a long time. The parameters of the asynchronous task are passed to this step. The result of the computation must be returned by this step and will be passed back to the last step. This step can also use publishProgress(Progress...) to publish one or more units of progress. These values are published on the UI thread, in the onProgressUpdate(Progress...) step.

  3. onProgressUpdate(Progress...), invoked on the UI thread after a call to publishProgress(Progress...). The timing of the execution is undefined. This method is used to display any form of progress in the user interface while the background computation is still executing. For instance, it can be used to animate a progress bar or show logs in a text field.

  4. onPostExecute(Result), invoked on the UI thread after the background computation finishes. The result of the background computation is passed to this step as a parameter.

Cancelling a task


A task can be cancelled at any time by invoking cancel(boolean). Invoking this method will cause subsequent calls to isCancelled() to return true. After invoking this method, onCancelled(Object), instead of onPostExecute(Object) will be invoked after doInBackground(Object[]) returns. To ensure that a task is cancelled as quickly as possible, you should always check the return value of isCancelled() periodically from doInBackground(Object[]), if possible (inside a loop for instance.)

Using the AsyncTask class


To use AsyncTask you must subclass it. AsyncTask uses generics and varargs. The parameters are the following AsyncTask <TypeOfVarArgParams , ProgressValue , ResultValue> .

An AsyncTask is started via the execute() method.

The execute() method calls the doInBackground() and the onPostExecute() method.

TypeOfVarArgParams is passed into the doInBackground() method as input, ProgressValue is used for progress information and ResultValue must be returned from doInBackground() method and is passed to onPostExecute() as a parameter.

The doInBackground() method contains the coding instruction which should be performed in a background thread. This method runs automatically in a separate Thread.

The onPostExecute() method synchronizes itself again with the user interface thread and allows it to be updated. This method is called by the framework once the doInBackground() method finishes.

Example

In this sample application I just made the process to sleep for some period of time instead of doing network operation.( Just to explain the concept of AsyncTask. This is not a realtime application)

When the user clicks on the Start AsyncTask button, we make the process to sleep for give period of time. At the same time we keep the UI thread responsive by showing the status to the user.

Layout is like this:

<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity">

<TextView
android:id="@+id/output"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world"/>

<Button
android:id="@+id/startTask"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/strBtnStart"
android:layout_below="@id/output"
android:onClick="startTask"/>

</RelativeLayout>

Main_Activity.java file is as follow:

 

package com.example.async1;

import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.TextView;

public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}

//Method called on clicking button
public void startTask(View view) {
myAsyncTask mTask = new myAsyncTask();
mTask.execute("abc","10","Hello world");
}

private class myAsyncTask extends AsyncTask<String, Integer, String> {
String mTAG = "myAsyncTask";
@Override
protected void onPreExecute() {
TextView output = (TextView)findViewById(R.id.output);
output.setText("Hello from onPreExecute");
displayProgressBar("Loading....");
}

@Override
protected String doInBackground(String...arg) {
Log.d(mTAG, "Just started doing stuff in asynctask");
try {
Thread.sleep(5000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
Log.d(mTAG, "I got "+arg.length+" arguments and they are: ");
String result = null;
for (int i = 0 ; i < arg.length ; i++ ) {
result = arg[i]+",";
Log.d(mTAG, (i+1)+" => "+arg[i]);
}

/*runOnUiThread(new Thread() {
public void run() {
TextView output = (TextView) findViewById(R.id.output);
output.setText("I am done");
}
});*/

try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
e.printStackTrace();
}

return result;
}

@Override
protected void onPostExecute(String result) {
Log.d(mTAG, "Inside onPostExecute");
TextView output = (TextView) findViewById(R.id.output);
output.setText("Result of the computation is: "+result);
}

}

}

As we know that doInBackground() method can’t update UI Thread because it runs on background. Still if we want to update UI thread inside this method, we use runOnUiThread() method that takes a new Thread as an argument, in which we can update UI Thread.

Uncomment runOnUiThread() method written inside code to see its effect.

Task: Use AsyncTask onProgressUpdate() Method.


package com.example.async1;

import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.TextView;

public class MainActivity extends Activity {
    private TextView output;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        output = (TextView)findViewById(R.id.output);
        
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
    
    //This function is called when button is clicked.
    public void startTask(View view) {
        myAsyncTask mTask = new myAsyncTask();
        mTask.execute("abc","10","Hello world");
    }
    
    private class myAsyncTask extends AsyncTask<String, Integer, Void> {
        String mTAG = "myAsyncTask";
        
        @Override
        protected void onPreExecute() {
            Log.d(mTAG, "Hello from onPreExecute");
            output.setText("Hello from onPreExecute");
        }
        
        @Override
        protected Void doInBackground(String...arg) {
            
            //Added sleep so that you can see Hello from onPreExecute and after that Inside doInBackground clearly.
            try{
                Thread.sleep(5000);
            }
            catch(InterruptedException e)
            {
                
                e.printStackTrace();
            }
            
            Log.d(mTAG, "Just started doing stuff in background");
            //New thread is created because this function can't update UI Thread.
            runOnUiThread(new Thread() {
                public void run() {
                    TextView output = (TextView) findViewById(R.id.output);
                    output.setText("Inside doInBackground");
                }
            });
            
            //Showing arguments passed to it by execute() method.
            Log.d(mTAG, "I got "+arg.length+" arguments and they are: ");
            for (int i = 0 ; i < arg.length ; i++ ) {
                Log.d(mTAG, (i+1)+" => "+arg[i]);
            }
            
            //Continuous BackGround Work
            for(int i=0;i<10;i++){
            try {
                Thread.sleep(5000);
            }
            catch (InterruptedException e) {
                e.printStackTrace();
            }
            publishProgress(i+1); // It calls onProgressUpdate Method.
            }
            
            return null;
        }
        
        //@Override
        protected void onProgressUpdate(Integer ... a){
                Log.d(mTAG,"Progress is "+a[0]+" % done.");
                output.setText(a[0]+"% done");
            
        }
        
        @Override
        protected void onPostExecute(Void a) {
            Log.d(mTAG, "Inside onPostExecute");
            output.setText("Work Done!");
        }
    }
    
}


References:

http://developer.android.com/reference/android/os/AsyncTask.html

http://www.vogella.com/tutorials/AndroidBackgroundProcessing/article.html

http://www.compiletimeerror.com/2013/01/why-and-how-to-use-asynctask.html

 

Posted in Uncategorized | Leave a comment

How to pass data from one activity to another in Android?

Lets suppose you have one EditText and one button in one activity and one text view in another activity.

On clicking the button, text in Edit Text of activity one should become lable/ text of text view in another activity.

For this:

Define onClick attribute of button with function to be called as value of the attribute.

<Button
....
android:onClick = login
/>

 where login is the name of function that is called when button is clicked.

 Now define Intent object inside this login() function.

 Intent myIntent = new Intent( this, DashBoard.class);

Here DashBoard is the source java file of second activity.

To pass the data, first you need to fetch the data of EditText.

 EditText mEditText= (EditText)findViewById(R.id.editText1);

 It will fetch the object of that EditText.

 String str = mEditText.getText().toString();

 Now text of EditText (id: editText1) is in string variable str.

 Now pass the data by calling putExtra() method through Intent object created above and start the second activity.

 myIntent.putExtra("myExtra", str);
 startActivity(myIntent);

Here myExtra is the name of string being passed and str is variable containing the actual string.

 In the second activity that you named DashBoard, you need to get the Intent and set string of previous activity as text of TextView of second activity.

 

Intent myIntent = getIntent();
if (myIntent.hasExtra("myExtra")){                                TextView mText = (TextView)findViewById(R.id.textView1);
mText.setText("Welcome "+myIntent.getStringExtra("myExtra")+"!"); }

 At this point, you are still not done!

 You need to add second activity name in AndroidManifest.xml file to make operating system know about the existence of second activity.

  

  <activity>
  android:name=".DashBoard"
  android:label="@string/app_name"
  />

¬†And you are done. ūüôā

Posted in Uncategorized | Leave a comment