Saturday, 11 April 2015

Custom Toast in Android.

Customizing Toasts

The standard Toast message window is often sufficient, but in many situations you’ll want to cus- tomize its appearance and screen position. 
You can modify a Toast by setting its display position and assigning it alternative Views or layouts.

Let’s Make a Toast
It shows how to align a Toast to the bottom of the screen using the setGravity method. 

Aligning Toast text
 
Context context = this; 
String msg = “To the bride and groom!”; 
int duration = Toast.LENGTH_SHORT; 
Toast toast = Toast.makeText(context, msg, duration); 
int offsetX = 0; 
int offsetY = 0;
 
toast.setGravity(Gravity.BOTTOM, offsetX, offsetY); 
toast.show();

When a text message just isn’t going to get the job done, you can specify a custom View or layout to use a more complex, or more visual, display. 
Using setView on a Toast object, you can specify any View (including a layout) to display using the Toast mechanism. 

For example, assigns a layout, containing the CompassView Widget  along with a TextView, to be dis- played as a Toast.

Using Views to customize a Toast
 
Context context = getApplicationContext(); 
String msg = “Cheers!”;
int duration = Toast.LENGTH_LONG; 

Toast toast = Toast.makeText(context, msg, duration); 
toast.setGravity(Gravity.TOP, 0, 0);
 
LinearLayout ll = new LinearLayout(context); 
ll.setOrientation(LinearLayout.VERTICAL);
 
TextView myTextView = new TextView(context); 
CompassView cv = new CompassView(context);
myTextView.setText(msg);
 
int lHeight = LinearLayout.LayoutParams.FILL_PARENT; 
int lWidth = LinearLayout.LayoutParams.WRAP_CONTENT;
 
ll.addView(cv, new LinearLayout.LayoutParams(lHeight, lWidth)); 
ll.addView(myTextView, new LinearLayout.LayoutParams(lHeight, lWidth));
ll.setPadding(40, 50, 0, 50);
 
toast.setView(ll); 
toast.show();

The resulting Toast will appear.

Using Toasts in Worker Threads
 
As GUI components, Toasts must be created and shown on the GUI thread; otherwise, you risk throwing a cross-thread exception.A Handler is used to ensure that the Toast is opened on the GUI thread. 

Opening a Toast on the GUI thread
 
Handler handler = new Handler();
private void mainProcessing() 
{  
Thread thread = new Thread(null, doBackgroundThreadProcessing,                            ”Background”);  
thread.start(); }
 
private Runnable doBackgroundThreadProcessing = new Runnable() 
{  
public void run() 
{    
backgroundThreadProcessing();  
};

private void backgroundThreadProcessing() 
{  
handler.post(doUpdateGUI); }
 
// Runnable that executes the update GUI method. 
private Runnable doUpdateGUI = new Runnable() 
{  
public void run() 
{    
Context context = getApplicationContext();    
String msg = “To open mobile development!”;    
int duration = Toast.LENGTH_SHORT;    
Toast.makeText(context, msg, duration).show();  
};

Wednesday, 8 April 2015

Bind Service to Activity in Android.

Binding Activities to Services

So far, you have seen how services are created and how they are called and terminated when they are done with their task. 
All the services that you have seen are simple — either they start with a counter and increment at regular intervals, or they download a fixed set of files from the Internet. 
However, real-world services are usually much more sophisticated, requiring the passing of data so that they can do the job correctly for you. 
Using the service demonstrated earlier that downloads a set of files, suppose you now want to let the calling activity determine what files to download, instead of hardcoding them in the service. 
Here is what you need to do. First, in the calling activity, you create an Intent object, specifying the service name:

​​​​​​​​Button ​btnStart​=​(Button)​findViewById(R.id.btnStartService); 
​​​​​​​​btnStart.setOnClickListener(new​View.OnClickListener()​
​​​​​​​​​​​​public ​void ​onClick(View ​v)​
​​​​​​​​​​​​​​​​Intent intent = new Intent(getBaseContext(), MyService.class); ​
​​​​​​​​​​​} 
​​​​​​​​});
 
You then create an array of URL objects and assign it to the Intent object through its putExtra() method. 
Finally, you start the service using the Intent object:
 
​​​​​​​​Button ​btnStart​=​(Button)​findViewById(R.id.btnStartService); 
​​​​​​​​btnStart.setOnClickListener(new​ View.OnClickListener()
​{ 
​​​​​​​​​​​​public ​void ​onClick(View ​v)
​{ 
​​​​​​​​​​​​​​​​Inten t​intent​=​new​Intent(getBaseContext(),​MyService.class); ​
​​​​​​​​​​​​​​​try 
​​​​​​​​​​​​​​​​​​​​URL[] urls = new URL[] 
{
​new URL(“http://www.amazon.com/somefiles.pdf”), ​
​​​​​​​​​​​​​​​​​​​​​​​​​​​new URL(“http://www.wrox.com/somefiles.pdf”), 
​​​​​​​​​​​​​​​​​​​​​​​​​​​​new URL(“http://www.google.com/somefiles.pdf”), 
​​​​​​​​​​​​​​​​​​​​​​​​​​​​new URL(“http://emergingandroidtech.blogspot.in/somefiles.pdf”)}; 

​​​​​​​​​​​​​​​​​​​​intent.putExtra(“URLs”, urls); 
​​​​​​​​​​​​​​​​} 
catch (MalformedURLException e) 
​​​​​​​​​​​​​​​​​​​​e.printStackTrace(); 
​​​​​​​​​​​​​​​​} 
​​​​​​​​​​​​​​​​startService(intent); 
​​​​​​​​​​​​} 
​​​​​​​​});
 
Note that the URL array is assigned to the Intent object as an Object array. 
On the service’s end, you need to extract the data passed in through the Intent object in the onStartCommand() method:
 
​​​​@Override ​​​
​public​ int ​onStartCommand(Intent​ intent,​int ​flags,​int ​startId)​
​​​​​​​​//​We ​want​ this ​service​ to​ continue ​running​ until ​it ​is ​explicitly 
​​​​​​​​//​stopped,​so ​return ​sticky. ​

​​​​​​​Toast.makeText(this,​“Service​Started”,​Toast.LENGTH_LONG).show();
​​​​​​​​
Object [] objUrls = (Object []) intent.getExtras().get(“URLs”); ​​​​​​
​​URL [] urls = new URL[objUrls.length]; ​​

​​​​​​for (int i=0; i<objUrls.length-1; i++) 
​​​​​​​​​​​​urls [i] = (URL) objUrls[i]; 
​​​​​​​​} 
​​​​​​​​new DoBackgroundTask().execute(urls); 
​​​​​​​​return ​START_STICKY; ​​​​
}
 
The preceding first extracts the data using the getExtras() method to return a Bundle object. 
It then uses the get() method to extract out the URL array as an Object array. 
Because in Java you cannot directly cast an array from one type to another, you have to create a loop and cast each member of the array individually. 
Finally, you execute the background task by passing the URL array into the execute() method. 
This is one way in which your activity can pass values to the service. 
As you can see, if you have relatively complex data to pass to the service, you have to do some additional work to ensure that the data is passed correctly. 
A better way to pass data is to bind the activity directly to the service so that the activity can call any public members and methods on the service directly.

Monday, 6 April 2015

Communication between Service and Activity in Android.

Communicating Between A Service And An Activity


Often a service simply executes in its own thread, independently of the activity that calls it.
This doesn’t pose any problem if you simply want the service to perform some tasks periodically and the activity does not need to be notified of the status of the service.

For example, you may have a service that periodically logs the geographical location of the device to a database.
In this case, there is no need for your service to interact with any activities, because its main purpose is to save the coordinates into a database.
However, suppose you want to monitor for a particular location. When the service logs an address that is near the location you are monitoring, it might need to communicate that information to the activity. In this case, you would need to devise a way for the service to interact with the activity.
The following example demonstrates how a service can communicate with an activity using a BroadcastReceiver.

Invoking an Activity from a Service

1 . Using the same project created in the previous post, add the following statements in bold to the MyIntentService.java file:

package ​com.emergingandroidtech.Services;
import​ java.net.MalformedURLException;
import ​java.net.URL;
import​ android.app.IntentService;
import​ android.content.Intent;
import ​android.util.Log;

public​ class ​MyIntentService ​extends​ IntentService​
{
​​​​public ​MyIntentService()​
{
​​​​​​​​super(“MyIntentServiceName”);
​​​​}
​​​​
@Override ​​
​​protected​ void​ onHandleIntent(Intent ​intent)
​{
​​​​​​​​try​
{
​​​​​​​​​​​​int ​result​= ​​​​​​​​​​​​​​​​DownloadFile(new​URL(“http://www.amazon.com/somefile.pdf”)); ​​
​​​​​​​​​​Log.d(“IntentService”,​“Downloaded​“​+​result​+​“​bytes”);
​​​​​​​​​​​​
//---send a broadcast to inform the activity
​​​​​​​​​​​​// that the file has been downloaded--- ​​​
​​​​​​​​​Intent broadcastIntent = new Intent(); ​​​​​​​​​​​​broadcastIntent.setAction(“FILE_DOWNLOADED_ACTION”); ​​​​​​​​​​​​getBaseContext().sendBroadcast(broadcastIntent);
​​​​​​​​}
​catch​(MalformedURLException​ e)​
{
​​​​​​​​​​​​e.printStackTrace(); ​​​
​​​​​}
​​​​}
​​​​
private ​int ​DownloadFile(URL ​url)
​{
​​​​​​​​try
​{
​​​​​​​​​​​​//---simulate​ taking ​some​time​ to ​download​ a ​file--- ​
​​​​​​​​​​​Thread.sleep(5000);
​​​​​​​​}
​catch​(InterruptedException ​e)​
{
​​​​​​​​​​​​e.printStackTrace();
​​​​​​​​}
​​​​​​​​return​ 100;
​​​​}
}

2 . Add the following statements in bold to the MainActivity.java file: 

package ​com.emergingandroidtech.Services;
import​ android.app.Activity;
import​ android.content.BroadcastReceiver;
import​ android.content.Context;
import​ android.content.Intent;
import​ android.os.Bundle;
import​ android.view.View;
import​ android.widget.Button;
import ​android.widget.Toast;
import android.content.IntentFilter;

public ​class ​MainActivity ​extends ​Activity​
{
​IntentFilter intentFilter;
​​​​
/**​ Called ​when ​the​ activity ​is ​first​ created.​*/
​​​​@Override
​​​​public ​void ​onCreate(Bundle ​savedInstanceState)​
{
​​​​​​​​super.onCreate(savedInstanceState); ​​
​​​​​​setContentView(R.layout.main);
​​​​​​​​
//---intent to filter for file downloaded intent--- ​​​
​​​​​intentFilter = new IntentFilter(); ​​
​​​​​​intentFilter.addAction(“FILE_DOWNLOADED_ACTION”);
​​​​​​​​
//---register the receiver---
​​​​​​​​registerReceiver(intentReceiver, intentFilter);
​​​​​​​​
Button ​btnStart​=​(Button)​findViewById(R.id.btnStartService);
​​​​​​​​btnStart.setOnClickListener(new​ View.OnClickListener()​
{ ​​​​​​​​​​​​
public ​void ​onClick(View​ v)​
{
​​​​​​​​​​​​​​​​//startService(new​Intent(getBaseContext(),​MyService.class)); ​​​
​​​​​​​​​​​​​startService(new​Intent(getBaseContext(),​MyIntentService.class));
​​​​​​​​​​​​}
​​​​​​​​});
​​​​​​​​
Button​ btnStop​=​(Button)​findViewById(R.id.btnStopService);
​​​​​​​​btnStop.setOnClickListener(new ​View.OnClickListener()
​{
​​​​​​​​​​​​public ​void ​onClick(View​ v)​
{
​​​​​​​​​​​​​​​​stopService(new​Intent(getBaseContext(),​MyService.class)); ​​
​​​​​​​​​​}
​​​​​​​​});
​​​​}
​​​​
private BroadcastReceiver intentReceiver = new BroadcastReceiver()
{
​​​​​​​​@Override
​​​​​​​​public void onReceive(Context context, Intent intent)
{
​​​​​​​​​​​​Toast.makeText(getBaseContext(), “File downloaded!”, ​​​​​​​​​​​​​​​​​​​​Toast.LENGTH_LONG).show(); ​​​​
​​​​}
​​​​};
}

3 . Click the Start Service button. After about five seconds, the Toast class will display a message indicating that the file has been downloaded.

How It Works 

To notify an activity when a service has finished its execution, you broadcast an intent using the sendBroadcast() method:

​​​​@Override
​​​​protected ​void ​onHandleIntent(Intent​ intent)
​{
​​​​​​​​try
​{
​​​​​​​​​​​​int ​result​= ​​​​​​​​​​​​​​​​DownloadFile(new​ URL(“http://www.amazon.com/somefile.pdf”));
​Log.d(“IntentService”,​“Downloaded​“​+​result​+​“​bytes”);
​​​​​​​​​​​​
//---send a broadcast to inform the activity ​​
​​​​​​​​​​// that the file has been downloaded--- ​​​​
​​​​​​​​Intent broadcastIntent = new Intent(); ​​​​​​​​​​​​broadcastIntent.setAction(“FILE_DOWNLOADED_ACTION”); ​​​​​​​​​​​​getBaseContext().sendBroadcast(broadcastIntent); ​​
​​​​​​}​
catch​(MalformedURLException ​e)​
{
​​​​​​​​​​​​e.printStackTrace(); ​​
​​​​​​}
​​​​}

The action of this intent that you are broadcasting is set to “FILE_DOWNLOADED_ACTION”, which means any activity that is listening for this intent will be invoked.
Hence, in your MainActivity.java file, you listen for this intent using the registerReceiver() method from the IntentFilter class:
​​​​
@Override
​​​​public ​void​ onCreate(Bundle​ savedInstanceState)
​{
​​​​​​​​super.onCreate(savedInstanceState);
​​​​​​​​setContentView(R.layout.main);
​​​​​​​​
//---intent to filter for file downloaded intent--- ​​​
​​​​​intentFilter = new IntentFilter(); ​​
​​​​​​intentFilter.addAction(“FILE_DOWNLOADED_ACTION”); ​​​
​​​​​
//---register the receiver---
​​​​​​​​registerReceiver(intentReceiver, intentFilter);
 ​​​​​​​​... ​​​​​​​​... ​​​​}

When the intent is received, it invokes an instance of the BroadcastReceiver class that you have defi ned:

​​​​private ​BroadcastReceiver ​intentReceiver​=​new ​BroadcastReceiver()​
{
​​​​​​​​@Override ​​
​​​​​​public ​void ​onReceive(Context​ context,​Intent​ intent)​
{ ​
​​​​​​​​​​​Toast.makeText(getBaseContext(),​“File​downloaded!”, ​​​​​​​​​​​​​​​​​​​​Toast.LENGTH_LONG).show();
​​​​​​​​} ​
​​​};
}

In this case, you displayed the message “File downloaded!” Of course, if you need to pass some data from the service to the activity, you can make use of the Intent object.

Friday, 3 April 2015

IntentService in Android example.

Executing Asynchronous tasks on Separate threads using intentService 


In earlier posts, you saw how to start a service using the startService() method and stop a service using the stopService() method.
You have also seen how you should execute long-running task on a separate thread — not the same thread as the calling activities.
It is important to note that once your service has finished executing a task, it should be stopped as soon as possible so that it does not unnecessarily hold up valuable resources.
That’s why you use the stopSelf() method to stop the service when a task has been completed. Unfortunately, a lot of developers often forgot to terminate the service when it is done performing its task.
To easily create a service that runs a task asynchronously and terminates itself when it is done, you can use the IntentService class.

The IntentService class is a base class for Service that handles asynchronous requests on demand.
It is started just like a normal service and it executes its task within a worker thread and terminates itself when the task is completed.

The following example demonstrates how to use the IntentService class.

Using the intentService Class to Auto-Stop a Service


1. Add a new class file named MyIntentService.java.

2 . Populate the MyIntentService.java file as follows:

package com.emergingandroidtech.Services;

import java.net.MalformedURLException;
import java.net.URL;

import android.app.IntentService;
import android.content.Intent;
import android.util.Log;

public class MyIntentService extends IntentService {
       
    public MyIntentService() {
        super("MyIntentServiceName");
    }   
   
    @Override
    protected void onHandleIntent(Intent intent) {       
        try {
            int result =
                DownloadFile(new URL("http://www.amazon.com/somefile.pdf"));
            Log.d("IntentService", "Downloaded " + result + " bytes");
           
            //---send a broadcast to inform the activity
            // that the file has been downloaded---
            Intent broadcastIntent = new Intent();
            broadcastIntent.setAction("FILE_DOWNLOADED_ACTION");           
            getBaseContext().sendBroadcast(broadcastIntent);

        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
    }
   
    private int DownloadFile(URL url) {       
        try {
            //---simulate taking some time to download a file---
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }       
        return 100;
    }   
}

 3 . Add the following statement in bold to the AndroidManifest.xml file: 



<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.emergingandroidtech.Services"
      android:versionCode="1"
      android:versionName="1.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".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>
        <service android:name=".MyService">
            <intent-filter>
                <action android:name="com.emergingandroidtech.MyService" />               
            </intent-filter>
        </service>
       
       
       
        <service android:name=".MyIntentService" />
    </application>
    <uses-sdk android:minSdkVersion="9" />
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
</manifest>

 4. Add the following in main.xml file.


<?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"
    >
<Button android:id="@+id/btnStartService"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="Start Service" />
       
<Button android:id="@+id/btnStopService"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="Stop Service" />
       
</LinearLayout>



5 . Add the following statement in bold to the MainActivity.java file:  

public​ class ​MainActivity ​extends​ Activity​
​​​​
/**​Called​ when ​the​ activity ​is first ​created.​*/ ​​
@Override 
​​​​public ​void ​onCreate(Bundle ​savedInstanceState)​
​​​​​​​​super.onCreate(savedInstanceState); ​
​​​​​​​setContentView(R.layout.main);
​​​​​​​​
Button ​btnStart​=​(Button)​findViewById(R.id.btnStartService); 
​​​​​​​​btnStart.setOnClickListener(new​View.OnClickListener()
​{ 
​​​​​​​​​​​​public ​void​ onClick(View​ v)
​{ 
​​​​​​​​​​​​​​​​//startService(new Intent(getBaseContext(), MyService.class)); 
​​​​​​​​​​​​​​​​startService(new Intent(getBaseContext(), MyIntentService.class)); ​
​​​​​​​​​​​} ​​​​​​​​
});
​​​​​​​​
Button ​btnStop​=​(Button)​findViewById(R.id.btnStopService); 
​​​​​​​​btnStop.setOnClickListener(new​View.OnClickListener()​
​​​​​​​​​​​​public ​void​ onClick(View​ v)​
{ ​
​​​​​​​​​​​​​​​stopService(new​Intent(getBaseContext(),​MyService.class)); ​​​​
​​​​​​​​} 
​​​​​​​​}); 
​​​​} 
}
 
5 . Click the Start Service button. After about five seconds, you should observe the following statement in the LogCat window:
 
01-17​03:05:21.244:​DEBUG/IntentService(692):​ Downloaded ​100​bytes

Monday, 30 March 2015

Run repeatedly task using timer class in android.

Performing repeated tasks in a Service

Besides performing long-running tasks in a service, you might also perform some repeated tasks in a service. For example, you may write an alarm clock service that runs persistently in the background. In this case, your service may need to periodically execute some code to check whether a prescheduled time has been reached so that an alarm can be sounded. To execute a block of code to be executed at a regular time interval, you can use the Timer class within your service.

The following Example shows you how.

Running Repeated Tasks Using the Timer Class

1 . Using the same project created in the previous post, add the following statements in bold to the MyService.java file:

package ​com.emergingandroidtech.Services;
import ​android.app.Service;
import​ android.content.Intent;
import​ android.os.AsyncTask;
import​ android.os.IBinder;
import​ android.util.Log;
import​ android.widget.Toast;
import ​java.net.URL;
import java.util.Timer;
import java.util.TimerTask;

public ​class ​MyService​ extends​ Service​
{
​​​​int counter = 0;
​​​​static final int UPDATE_INTERVAL = 1000;
​​​​private Timer timer = new Timer();
​​​​
@Override
​​​​public​ IBinder ​onBind(Intent ​arg0)
​{
​​​​​​​​return ​null;
​​​​}
​​​​
@Override
​​​​public ​int ​onStartCommand(Intent ​intent,​int ​flags,​int ​startId)​
{
​​​​​​​​//​We ​want​ this ​service​ to ​continue​r unning ​until ​it ​is ​explicitly
​​​​​​​​//​stopped,​so​r eturn ​sticky. ​
​​​​​​​Toast.makeText(this,​“Service​Started”,​Toast.LENGTH_LONG).show();
​​​​​​​​
doSomethingRepeatedly();
​​​​​​​​
return ​START_STICKY; ​​​​
}
​​​​
private void doSomethingRepeatedly()
{
​​​​​​​​timer.scheduleAtFixedRate( new TimerTask()
{
​​​​​​​​​​​​public void run()
{
​​​​​​​​​​​​​​​​Log.d(“MyService”, String.valueOf(++counter));
​​​​​​​​​​​​}
​​​​​​​​},
0,
UPDATE_INTERVAL);
​​​​}
​​​​
@Override
​​​​public ​void ​onDestroy()​
{ ​
​​​​​​​super.onDestroy();
​​​​​​​​if (timer != null)
{
​​​​​​​​​​​​timer.cancel(); ​
​​​​​​​}
​​​​​​​​Toast.makeText(this,​“Service​Destroyed”,​Toast.LENGTH_LONG).show(); ​​
​​}
}

2 . Click the Start Service button. 

3 . Observe the output displayed in the LogCat window: 

01-16​15:12:04.364:​DEBUG/MyService(495):​1
01-16​15:12:05.384:​DEBUG/MyService(495):​2
01-16​15:12:06.386:​DEBUG/MyService(495):​3
01-16​15:12:07.389:​DEBUG/MyService(495):​4
01-16​15:12:08.364:​DEBUG/MyService(495):​5
01-16​15:12:09.427:​DEBUG/MyService(495):​6
01-16​15:12:10.374:​DEBUG/MyService(495):​7

How It Works

In this example, you created a Timer object and called its scheduleAtFixedRate() method inside the doSomethingRepeatedly() method that you have defined:

​​​​private ​void ​doSomethingRepeatedly()​
{
​​​​​​​​timer.scheduleAtFixedRate(new​TimerTask()​
{
​​​​​​​​​​​​public ​void ​run()​
{
​​​​​​​​​​​​​​​​Log.d(“MyService”,​String.valueOf(++counter));
​​​​​​​​​​​​}
​​​​​​​​},
​0,
​UPDATE_INTERVAL);
​​​​}

You passed an instance of the TimerTask class to the scheduleAtFixedRate() method so that  you can execute the block of code within the run() method repeatedly. The second parameter to the scheduleAtFixedRate() method specifies the amount of time, in milliseconds, before first execution. The third parameter specifies the amount of time, in milliseconds, between subsequent executions. In the preceding example, you essentially print out the value of the counter every one second (1,000 milliseconds). The service repeatedly prints the value of counter until the service is terminated:

​​​​@Override ​
​​​public ​void ​onDestroy()​
{
​​​​​​​​super.onDestroy();
​​​​​​​​if​(timer​!=​null)
{
​​​​​​​​​​​​timer.cancel(); ​​​
​​​​​} ​
​​​​​​​Toast.makeText(this,​“Service​Destroyed”,​Toast.LENGTH_LONG).show(); ​​
​​}

For the scheduleAtFixedRate() method, your code is executed at fixed time intervals, regardless of how long each task takes. For example, if the code within your run() method takes two seconds to complete, then your second task will start immediately after the first task has ended. Similarly, if your delay is set to three seconds and the task takes two seconds to complete, then the second task will wait for one second before starting.

How to use Async Task in a Service in android ?

Performing Tasks in a Service Asynchronously


1 . Using the same project created in the previous post, add the following statements in bold to the MyService.java file:
 

package ​com.emergingandroidtech.Services;
import ​android.app.Service;
import​ android.content.Intent;
import​ android.os.IBinder;
import ​android.util.Log;
import​ android.widget.Toast;
import​ java.net.MalformedURLException;
import​ java.net.URL;
import android.os.AsyncTask;

public​ class ​MyService ​extends​ Service​
{
​​​​@Override
​​​​public​ IBinder ​onBind(Intent​ arg0)​
{
​​​​​​​​return ​null;
​​​​}
​​​​
@Override ​
​​​public​ int ​onStartCommand(Intent ​intent,​int​ flags,​int ​startId)​
{
​​​​​​​​
//​We​ want ​this ​service ​to ​continue ​running ​until​ it ​is ​explicitly
​​​​​​​​//​stopped,​so​ return ​sticky. ​​​​​​​​
Toast.makeText(this,​“Service​Started”,​Toast.LENGTH_LONG).show();
​​​​​​​​try
{
​​​​​​​​​​​​new DoBackgroundTask().execute(
​​​​​​​​​​​​​​​​​​​​new URL(“http://www.amazon.com/somefiles.pdf”),
​​​​​​​​​​​​​​​new URL(“http://www.google.com/somefiles.pdf”),
​​​​​​​​​​​​​​​​​​​​new URL(“http://emergingandroidtech.blogspot.in”)); ​​​​​​​​
}
catch (MalformedURLException e)
{
​​​​​​​​​​​​e.printStackTrace();
​​​​​​​​}
​​​​​​​​return ​START_STICKY; ​
​​​}
​​​​
@Override
​​​​public ​void ​onDestroy()
​{
​​​​​​​​super.onDestroy();
​​​​​​​​Toast.makeText(this,​“Service​Destroyed”,​Toast.LENGTH_LONG).show(); ​​​
​} ​​​​

​​​​private ​int ​DownloadFile(URL​ url)
​{
​try​
{
​​​​​​​​​​​​//---simulate​ taking ​some​time ​to ​download ​a​ file--- ​​​​​​​​​​​​
Thread.sleep(5000);
​​​​​​​​}
​catch​(InterruptedException ​e)​
{
​​​​​​​​​​​​e.printStackTrace(); ​
​​​​​​​}
​​​​​​​​//---return ​an ​arbitrary ​number​ representing ​
​​​​​​//​the ​size​ of ​the ​file ​downloaded--- ​
​​​​​​​return​ 100; ​
​​​}
​​​​
private class DoBackgroundTask extends AsyncTask<URL, Integer, Long>
{
​​​​​​​​protected Long doInBackground(URL... urls)
{
 ​​​​​​​​​​​​int count = urls.length;
​​​​​​​​​​​​long totalBytesDownloaded = 0;
​​​​​​​​​​​​for (int i = 0; i < count; i++)
{
​​​​​​​​​​​​​​​​totalBytesDownloaded += DownloadFile(urls[i]);

​​​​​​​​​​​​​​​​//---calculate percentage downloaded and
​​​​​​​​​​​​​​​​// report its progress--- ​
​​​​​​​​​​​​​​​publishProgress((int) (((i+1) / (float) count) * 100)); ​
​​​​​​​​​​​}
​​​​​​​​​​​​return totalBytesDownloaded; ​​
​​​​​​}
​​​​​​​​
protected void onProgressUpdate(Integer... progress)
{
​​​​​​​​​​​​Log.d(“Downloading files”, ​​​​​​​​​​​​​​​​​​​​String.valueOf(progress[0]) + “% downloaded”); ​​​​​​​​​​​​

Toast.makeText(getBaseContext(), ​​​​​​​​​​​​​​​​String.valueOf(progress[0]) + “% downloaded”, ​​​​​​​​​​​​​​​​Toast.LENGTH_LONG).show(); ​​​​​​​​
}
​​​​​​​​
protected void onPostExecute(Long result)
{
​​​​​​​​​​​​Toast.makeText(getBaseContext(), ​​​​​​​​​​​​​​​​​​​​“Downloaded “ + result + “ bytes”, ​​​​​​​​​​​​​​​​​​​​Toast.LENGTH_LONG).show(); ​​
​​​​​​​​​​stopSelf();
​​​​​​​​} ​
​​​}
}

2. Click the Start Service button. 
The Toast class will display a message indicating what percentage of the download is completed. 
You should see four of them: 25%, 50%, 75%, and 100%.  

3 . You will also observe the following output in the LogCat window: 

01-16​02:56:29.051:​DEBUG/Downloading​files(8844):​25%​downloaded
01-16​02:56:34.071:​DEBUG/Downloading​files(8844):​50%​downloaded
01-16​02:56:39.106:​DEBUG/Downloading​files(8844):​75%​downloaded
01-16​02:56:44.173:​DEBUG/Downloading​files(8844):​100%​downloaded

How It Works

This example illustrates one way in which you can execute a task asynchronously within your service. You do so by creating an inner class that extends the AsyncTask class. The AsyncTask class enables you to perform background execution without needing to manually handle threads and handlers. The DoBackgroundTask class extends the AsyncTask class by specifying three generic types:

​​​​private ​class ​DoBackgroundTask ​extends ​AsyncTask<URL,​Integer,​Long>​{

In this case, the three types specified are URL, Integer and Long. These three types specify the data type used by the following three methods that you implement in an AsyncTask class:

doInBackground()— This method takes an array of the first generic type specified earlier. In this case, the type is URL. This method is executed in the background thread and is where you put your long-running code. To report the progress of your task, you call the publishProgress() method, which invokes the next method, onProgressUpdate(), which you implement in an AsyncTask class. The return type of this method takes the third generic type specified earlier, which is Long in this case.

onProgressUpdate()— This method is invoked in the UI thread and is called when you call the publishProgress() method. It takes an array of the second generic type specified earlier. In this case, the type is Integer. Use this method to report the progress of the background task to the user.

onPostExecute()— This method is invoked in the UI thread and is called when the doInBackground() method has finished execution. This method takes an argument of the third generic type specified earlier, which in this case is a Long.

To download multiple files in the background, you created an instance of the DoBackgroundTask class and then called its execute() method by passing in an array of URLs:

​​​​​​​​try
​{
​​​​​​​​​​​​new​DoBackgroundTask().execute(
​​​​​​​​​​​​​​​​​​​​new​URL(“http://www.amazon.com/somefiles.pdf”),​
​​​​​​​​​​​​​​new​URL(“http://www.google.com/somefiles.pdf”),
​​​​​​​​​​​​​​​​​​​​new​URL(“http://emergingandroidtech.blogspot.in”)); ​​​​​​​​
}
​catch​(MalformedURLException ​e)
​{
​​​​​​​​​​​​//​TODO​ Auto-generated ​catch ​block ​​
​​​​​​​​​​e.printStackTrace(); ​
​​​​​​​}

The preceding causes the service to download the files in the background, and reports the progress as a percentage of files downloaded. More important, the activity remains responsive while the files are downloaded in the background, on a separate thread.
Note that when the background thread has finished execution, you need to manually call the stopSelf() method to stop the service:

​​​​​​​​protected ​void ​onPostExecute(Long​ result)
​{
​​​​​​​​​​​​Toast.makeText(getBaseContext(), ​​​​​​​​​​​​​​​​​​​​“Downloaded​“​+​result​+​“​bytes”,​ ​​​​​​​​​​​​​​​​​​​​Toast.LENGTH_LONG).show(); ​​​​​​​​​​​​stopSelf(); ​​​​​​​​
}

The stopSelf() method is the equivalent of calling the stopService() method to stop the service.

Friday, 27 March 2015

How to create your own service in android ?

Creating your Own Services

The best way to understand how a service works is by creating one. The following example shows you the steps to create a simple service.  
For now, you will learn how to start and stop a service.
 

Creating a Simple Service


1 . Using Eclipse, create a new Android project and name it Services.

2 . Add a new class file to the project and name it MyService.java. Populate it with the following code:

package ​com.emergingandroidtech.Services;

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

public class MyService extends Service {
​​​​
@Override
​​​​public IBinder onBind(Intent arg0)
{
​​​​​​​​return null;
​​​​}
​​​​
@Override ​
​​​public int onStartCommand(Intent intent, int flags, int startId)
{ ​
​​​​​​​// We want this service to continue running until it is explicitly
​​​​​​​​// stopped, so return sticky.
​​​​​​​​Toast.makeText(this, “Service Started”, Toast.LENGTH_LONG).show();
​​​​​​​​return START_STICKY; ​​​​
} ​​​​

​​​​@Override ​
​​​public void onDestroy()
{
​​​​​​​​super.onDestroy();
​Toast.makeText(this, “Service Destroyed”, Toast.LENGTH_LONG).show(); ​
​​​}
}

3 . In the AndroidManifest.xml file, add the following statement in bold: 

<?xml ​version=”1.0”​encoding=”utf-8”?>
<manifest​
xmlns:android=”http://schemas.android.com/apk/res/android”
​​​​​​package=”com.emergingandroidtech.Services”
​​​​​​android:versionCode=”1”
​​​​​​android:versionName=”1.0”> ​

​​​<application​
android:icon=”@drawable/icon”
​android:label=”@string/app_name”>

​​​​​​​​<activity
 ​android:name=”.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>

​​​​​​​​      <service android:name=”.MyService” />
​​​​</application>
​​​​<uses-sdk​
android:minSdkVersion=”9”​/>

</manifest>

4 . In the main.xml file, add the following statements in bold:

<?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” ​​​​>

<Button
android:id=”@+id/btnStartService”
​​​​android:layout_width=”fill_parent”
​​​​android:layout_height=”wrap_content” ​​
​​android:text=”Start Service” />

<Button
android:id=”@+id/btnStopService”
​​​​android:layout_width=”fill_parent”
​​​​android:layout_height=”wrap_content” ​
​​​android:text=”Stop Service” />

</LinearLayout>

5 . Add the following statements in bold to the MainActivity.java file:

package​ com.emergingandroidtech.Services;
import​ android.app.Activity;
import​ android.os.Bundle;
import android.content.Intent;
import android.view.View;
import android.widget.Button;

public ​class​ MainActivity​ extends​ Activity
​{

​​​​/**​ Called​ when​ the ​activity ​is ​first ​created.​*/

​​​​@Override
​public ​void​ onCreate(Bundle​ savedInstanceState)
​{
​​​​​​​​super.onCreate(savedInstanceState);
​​​​​​​​setContentView(R.layout.main);
​​​​​​​​
Button btnStart = (Button) findViewById(R.id.btnStartService); ​
​​​​​​​btnStart.setOnClickListener(new View.OnClickListener()
{
​​​​​​​​​​​​public void onClick(View v)
{
​​​​​​​​​​​​​​​​startService(new Intent(getBaseContext(), MyService.class)); ​
​​​​​​​​​​​}
​​​​​​​​});
​​​​​​​​
Button btnStop = (Button) findViewById(R.id.btnStopService); ​
​​​​​​​btnStop.setOnClickListener(new View.OnClickListener()
{ ​​​​​​
​​​​​​public void onClick(View v)
{
​​​​​​​​​​​​​​​​stopService(new Intent(getBaseContext(), MyService.class));
​​​​​​​​​​​​}
​​​​​​​​});

​​​​}
}

6 . Clicking the Start Service button will start the service. To stop the service, click the Stop Service button.