Wednesday 24 June 2015

How to create AnalogClock and DigitalClock in Android.

Analogclock and Digitalclock views 


* The AnalogClock view displays an analog clock with two hands — one for minutes and one for hours.

* Its counterpart, the DigitalClock view, displays the time digitally. Both display the system time, and do not allow you to display a particular time.

* Hence, if you want to display the time for a particular region, you have to build your own custom views.

Using the AnalogClock and DigitalClock views are straightforward; simply declare them in your XML file (such as main.xml), 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” ​​​​>

<AnalogClock ​​
​​android:layout_width=”wrap_content” ​​
​​android:layout_height=”wrap_content” />

<DigitalClock
​​​​android:layout_width=”wrap_content” ​​
​​android:layout_height=”wrap_content” />

</LinearLayout>

Friday 19 June 2015

Android ProgressBar Example.

ProgressBar View 


* The ProgressBar view provides visual feedback of some ongoing tasks, such as when you are per- forming a task in the background.

* For example, you might be downloading some data from the Web and need to update the user about the status of the download.

* In this case, the ProgressBar view is a good choice for this task.


1 . Using Eclipse, create an Android project and name it as ProgressBarView. 

2 . Modify the main.xml file located in the res/layout folder by adding the following code 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" >
   
 <ProgressBar android:id="@+id/progressbar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        style="?android:attr/progressBarStyleHorizontal" />
       
</LinearLayout>

3 . In the MainActivity.java file, add the following statements in bold:

package com.emergingandroidtech.ProgressBarView;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.widget.ProgressBar;

public class MainActivity extends Activity {
   
    private static int progress;
    private ProgressBar progressBar;
    private int progressStatus = 0;
    private Handler handler = new Handler();
       
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
       
        progress = 0;
        progressBar = (ProgressBar) findViewById(R.id.progressbar);
        progressBar.setMax(200);
       
        //---do some work in background thread---
        new Thread(new Runnable()
        {

            public void run()
            {
                //---do some work here---
                while (progressStatus < 200)
                {
                    progressStatus = doSomeWork();
                    //---Update the progress bar---
                    handler.post(new Runnable()
                    {
                        public void run() {
                            progressBar.setProgress(progressStatus);
                        }
                    });
                }

                //---hides the progress bar---
                handler.post(new Runnable()
                {
                    public void run()
                    {
                        //---0 - VISIBLE; 4 - INVISIBLE; 8 - GONE---
                        progressBar.setVisibility(8);
                    }
                });
            }   

            //---do some long lasting work here---
            private int doSomeWork()
            {
                try {
                    //---simulate doing some work---
                    Thread.sleep(50);
                } catch (InterruptedException e)
                {
                    e.printStackTrace();
                }
                return ++progress;
            }
        }).start(); 
    }
}

4 . It shows the ProgressBar animating. After about five seconds, it will disappear.

Monday 1 June 2015

How to update an activity from BroadcastReceiver ?

Updating an Activity from a BroadcastReceiver


If you’ll want to send the SMS message back to the main activity of your application.

For example, you might wish to display the message in a TextView.

The following example demonstrates how you can do this.

Creating a View-Based Application Project


1- Add the following lines in bold to the 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/btnSendSMS" 
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="Send SMS" />   
   
<TextView
    android:id="@+id/textView1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />
   
</LinearLayout>

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

package com.emergingandroidtech.SMS;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.SmsMessage;
import android.widget.Toast;

public class SMSReceiver extends BroadcastReceiver
{
    @Override
    public void onReceive(Context context, Intent intent)
    {       
        //---get the SMS message passed in---
        Bundle bundle = intent.getExtras();       
        SmsMessage[] msgs = null;
        String str = "";           
        if (bundle != null)
        {
            //---retrieve the SMS message received---
            Object[] pdus = (Object[]) bundle.get("pdus");
            msgs = new SmsMessage[pdus.length];           
            for (int i=0; i<msgs.length; i++){
                msgs[i] = SmsMessage.createFromPdu((byte[])pdus[i]);               
                str += "SMS from " + msgs[i].getOriginatingAddress();                    
                str += " :";
                str += msgs[i].getMessageBody().toString();
                str += "\n";       
            }
            //---display the new SMS message---
            Toast.makeText(context, str, Toast.LENGTH_SHORT).show();
    
        
            //---send a broadcast intent to update the SMS received in the activity---
            Intent broadcastIntent = new Intent();
            broadcastIntent.setAction("SMS_RECEIVED_ACTION");
            broadcastIntent.putExtra("sms", str);
            context.sendBroadcast(broadcastIntent);
        }                        
    }
}

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

package com.emergingandroidtech.SMS;

import android.app.Activity;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;

import android.os.Bundle;
import android.telephony.SmsManager;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {
   
    Button btnSendSMS;       
    IntentFilter intentFilter;   
   
    private BroadcastReceiver intentReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            //---display the SMS received in the TextView---
            TextView SMSes = (TextView) findViewById(R.id.textView1);
            SMSes.setText(intent.getExtras().getString("sms"));
        }
    };
       
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);       
       
        //---intent to filter for SMS messages received---
        intentFilter = new IntentFilter();
        intentFilter.addAction("SMS_RECEIVED_ACTION");

       
       
        btnSendSMS = (Button) findViewById(R.id.btnSendSMS);       
        btnSendSMS.setOnClickListener(new View.OnClickListener()
        {
            public void onClick(View v)
            {               
                //sendSMS("5554", "Hello my friends!");
               
                Intent i = new
                    Intent(android.content.Intent.ACTION_VIEW);
                i.putExtra("address", "5556; 5558; 5560");
                i.putExtra("sms_body", "Hello my friends!");
                i.setType("vnd.android-dir/mms-sms");
                startActivity(i);
                                          
            }
        });
    }
       
    @Override
    protected void onResume() {
        //---register the receiver---
        registerReceiver(intentReceiver, intentFilter);
        super.onResume();
    }
   
    @Override
    protected void onPause() {
        //---unregister the receiver---
        unregisterReceiver(intentReceiver);
        super.onPause();
    }
       
  
   
        //---sends an SMS message to another device---
    private void sendSMS(String phoneNumber, String message)
    {    
       //...
    }

}

4. Add the following lines in Android Manifest file .

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.emergingandroidtech.SMS"
      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>

        <receiver android:name=".SMSReceiver">
            <intent-filter>
                <action android:name=
                    "android.provider.Telephony.SMS_RECEIVED" />
            </intent-filter>
        </receiver>

    </application>
    <uses-sdk android:minSdkVersion="8" />

<uses-permission android:name="android.permission.SEND_SMS"></uses-permission>
<uses-permission android:name="android.permission.RECEIVE_SMS"></uses-permission>
</manifest>

5 .Using the DDMS, send an SMS message to the emulator. It shows the Toast class displaying the message received, and the TextView showing the message received.

Friday 8 May 2015

Calling Built-In Application using Intent in android

You have seen how to call activities within your own application.
One of the key aspects of Android programming is using the intent to call activities from other applications.
In particular, your application can call the many built-in applications that are included with an Android device.
For example, if your application needs to enable a user to call a particular person saved in the Contacts application, you can simply use an Intent object to bring up the Contacts application, from which the user can select the person to call.
This enables your application to present a consistent user experience, and enables you to avoid building another application to retrieve all the contacts in the Contacts application.
The following Example demonstrates how to call some of the built-in applications commonly found on an Android device.

Calling Built-in Applications Using intents


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

2 . Add the following statements in bold to the 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/btn_webbrowser"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="Web Browser" />   
<Button
    android:id="@+id/btn_makecalls"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="Make Calls" />  
<Button
    android:id="@+id/btn_showMap"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="Show Map" />   
<Button
    android:id="@+id/btn_chooseContact"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="Choose Contact" />

 </LinearLayout>

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

package com.emergingandroidtech.Intents;

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends Activity {
   
    Button b1, b2, b3, b4 ;
    int request_Code = 1;
   
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
       
        //---Web browser button---
        b1 = (Button) findViewById(R.id.btn_webbrowser);
        b1.setOnClickListener(new OnClickListener()
        {
            public void onClick(View arg0){
                /*
                Intent i = new
                    Intent(android.content.Intent.ACTION_VIEW,
                      Uri.parse("http://emergingandroidtech.blogspot.in/"));
                */
               
                //---OR---
                Intent i = new
                Intent("android.intent.action.VIEW");               
                //Intent(android.content.Intent.ACTION_VIEW);               
                i.setData(Uri.parse("http://emergingandroidtech.blogspot.in/"));
               
                startActivity(i);               
            }
        });
       
        //---Make calls button---
        b2 = (Button) findViewById(R.id.btn_makecalls);
        b2.setOnClickListener(new OnClickListener()
        {
            public void onClick(View arg0){
                /*
                Intent i = new
                    Intent(android.content.Intent.ACTION_DIAL);
                startActivity(i);
                */
               
                //---OR---
               
                Intent i = new
                    Intent(android.content.Intent.ACTION_CALL,
                  Uri.parse("tel:+651234567"));
                startActivity(i);
                               
            }
        });  
       
        //---Show Map button---
        b3 = (Button) findViewById(R.id.btn_showMap);
        b3.setOnClickListener(new OnClickListener()
        {
            public void onClick(View arg0){
                Intent i = new
                    Intent(android.content.Intent.ACTION_VIEW,
                  Uri.parse("geo:37.827500,-122.481670"));               
                startActivity(i);               
            }
        });  
       
        //---Choose Contact button---
        b4 = (Button) findViewById(R.id.btn_chooseContact);
        b4.setOnClickListener(new OnClickListener()
        {
            public void onClick(View arg0){
                Intent i = new
                Intent(android.content.Intent.ACTION_PICK);                                       
                //i.setType(ContactsContract.Contacts.CONTENT_TYPE);
                i.setType(ContactsContract.CommonDataKinds.Phone.CONTENT_TYPE);
                startActivityForResult(i,request_Code);               
            }
        });               

            
    }
   
    public void onActivityResult(int requestCode, int resultCode, Intent data)
    {
        if (requestCode == request_Code)
        {
             if (resultCode == RESULT_OK)
               {               
                   Toast.makeText(this,data.getData().toString(),
                       Toast.LENGTH_SHORT).show();
                   Intent i = new Intent(
                           android.content.Intent.ACTION_VIEW,
                           Uri.parse(data.getData().toString()));
                   startActivity(i);
               }           
        }
    }
}

4 .Click the Web Browser button to load the Browser application on the emulator.
 

5 . Click the Make Calls button and the Phone application will load .

6 . Similarly, to load the Maps application, click the Show Map button.
 

NOTE  In order to display the Maps application, you need to run the application on an AVD that supports the Google APIs.
 

7 . Click the Choose Contact application to show a list of contacts that you can select . Selecting a contact will show details about that contact.

Sunday 19 April 2015

How to use ScrollView in Android ?

Scrollview 

* A ScrollView is a special type of FrameLayout in that it enables users to scroll through a list of views that occupy more space than the physical display.

* The ScrollView can contain only one child view or ViewGroup, which normally is a LinearLayout.

* NOTE 
-> Do not use a ListView together with the ScrollView.

-> The ListView is designed for showing a list of related information and is optimized for dealing with large lists.

The following main.xml content shows a ScrollView containing a LinearLayout, which in turn contains some Button and EditText views:

<?xml​ version=”1.0”​encoding=”utf-8”?>

<ScrollView ​​​​
android:layout_width=”fill_parent”
​android:layout_height=”fill_parent” ​
​​​xmlns:android=”http://schemas.android.com/apk/res/android” ​​​​>

​​​​<LinearLayout
​​​​​​​​android:layout_width=”fill_parent”
​​​​​​​​android:layout_height=”wrap_content” ​​
​​​​​​android:orientation=”vertical” ​​​​​​​​>

​​​​​​​​<Button
​​​​​​​​​​​​android:id=”@+id/button1” ​
​​​​​​​​​​​android:layout_width=”fill_parent” ​​
​​​​​​​​​​android:layout_height=”wrap_content” ​
​​​​​​​​​​​android:text=”Button​1” ​​​​​​​​​​​​/>

​​​​​​​​<Button ​​​​​​​​​​​​
android:id=”@+id/button2” ​​
​​​​​​​​​​android:layout_width=”fill_parent” ​​
​​​​​​​​​​android:layout_height=”wrap_content” ​​
​​​​​​​​​​android:text=”Button​2” ​​​​​​​​​​​​/> ​​​​​​​​<Button ​​​​​​​​​​​​android:id=”@+id/button3” ​​​​​​​​​​​​android:layout_width=”fill_parent” ​​​​​​​​​​​​android:layout_height=”wrap_content” ​​​​​​​​​​​​android:text=”Button​3” ​​​​​​​​​​​​/> ​​​​​​​​<EditText ​​​​​​​​​​​​android:id=”@+id/txt” ​​​​​​​​​​​​android:layout_width=”fill_parent” ​​​​​​​​​​​​android:layout_height=”300px” ​​​​​​​​​​​​/> ​​​​​​​​<Button ​​​​​​​​​​​​android:id=”@+id/button4” ​​​​​​​​​​​​android:layout_width=”fill_parent” ​​​​​​​​​​​​android:layout_height=”wrap_content” ​​​​​​​​​​​​android:text=”Button​4” ​​​​​​​​​​​​/> ​​​​​​​​<Button ​​​​​​​​​​​​android:id=”@+id/button5” ​​​​​​​​​​​​android:layout_width=”fill_parent” ​​​​​​​​​​​​android:layout_height=”wrap_content” ​​​​​​​​​​​​android:text=”Button​5” ​​​​​​​​​​​​/> ​​​​</LinearLayout> </ScrollView>
Figure 3-12 shows the ScrollView enabling the users to drag the screen upward to reveal the views located at the bottom of the screen.

Tuesday 14 April 2015

Dynamically update option menu items in Android.

Updating Menu Items Dynamically


By overriding your Activity’s onPrepareOptionsMenu method, you can modify a Menu based on an application’s current state immediately before the Menu is displayed.

This lets you dynamically disable/enable Menu Items, set visibility, and modify text.

Note that the onPrepareOptionsMenu method is triggered whenever the menu button is clicked, the overflow menu displayed, or the Action Bar is created.


To modify Menu Items dynamically, you can either record a reference to them from within the onCreateOptionsMenu method when they’re created, or you can use the findItem method on the Menu object, where onPrepareOptionsMenu is overridden.

Modifying Menu Items dynamically


@Override 
public boolean onPrepareOptionsMenu(Menu menu) 
{  
     super.onPrepareOptionsMenu(menu);
  
           MenuItem menuItem = menu.findItem(MENU_ITEM);
           [ ... modify Menu Items ... ]
 
    return true; 
}

Monday 13 April 2015

Bluetooth Communication Android.

Bluetooth Communications

The Android Bluetooth communications APIs are wrappers around RFCOMM, the Bluetooth radio frequency communications protocol. RFCOMM supports RS232 serial communication over the Logical Link Control and Adaptation Protocol (L2CAP) layer.
 
In practice, this alphabet soup provides a mechanism for opening communication sockets between two paired Bluetooth devices.
 
Before your application can communicate between devices, the devices must be paired (bonded). If users attempt to connect two unpaired devices, they will be prompted to pair them before the connection is established.
 
You can establish an RFCOMM communication channel for bidirectional communications using the following classes. 

BluetoothServerSocket — Used to establish a listening socket for initiating a link between devices. To establish a handshake, one device acts as a server to listen for, and accept, incoming connection requests. 

BluetoothSocket — Used to create a new client to connect to a listening Bluetooth Server Socket. Also returned by the Bluetooth Server Socket after a connection is established. 
Once a connection is established, Bluetooth Sockets are used by both the server and client to transfer data streams.
 
When creating an application that uses Bluetooth as a peer-to-peer transport layer, you’ll need to implement both a Bluetooth Server Socket to listen for connections and a Bluetooth Socket to initiate a new channel and handle communications.


When connected, the Bluetooth Server Socket returns a Bluetooth Socket that’s then used by the server device to send and receive data. This server-side Bluetooth Socket is used in exactly the same way as the client socket. The designations of server and client are relevant only to how the connec- tion is established; they don’t affect how data fl ows after that connection is made.

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