Archive

Posts Tagged ‘auto’

Create an application auto receiving new message (SMS)

July 14, 2011 27 comments

It’s quite a long time that I’ve been writing any new interesting tutorial. Today, I’ve got a little fever so I couldn’t step to workplace; so I decide to spend a little time to write a new tutorial.

The application we’re going to make today is a simple one that will receiving new messages automatically, notify and display them on a ListView. This is gonna be our simple screen:

SMS Auto Receiver

SMS Auto Receiver

A – Create the Project

Project Name: SMS Auto Receiver

Application Name: SMSAutoReceiver

Package Name: pete.android.study

Create Activity: MainActivity

Min SDK: 10

Click OK -> Done with creating project.

B – Sketch the Layout

The layout is pretty much the same as many previous articles on ListView in my blog.

+ One layout for main screen display, which is the list view

+ One layout for each item in the list view, which will be set to list view. This is where our SMS messages residing.

First, we start with layout for each item in list view.

1. List Item Layout

– First row determines the number of sender, I just make it into a LinearLayout with a constant TextView on the left with text “From: “ and right TextView gonna be used for setting incoming number.

– The second row displays the contents of message.

<?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="wrap_content">

	<LinearLayout
		android:orientation="horizontal"
		android:layout_width="fill_parent"
		android:layout_height="wrap_content"
	>
		<TextView
			android:layout_width="wrap_content"
			android:layout_height="wrap_content"
			android:text="From: "
		/>

		<TextView
			android:id="@+id/tvNumber"
			android:layout_width="wrap_content"
			android:layout_height="wrap_content"
		/>

	</LinearLayout>

	<TextView
		android:id="@+id/tvContent"
		android:layout_width="fill_parent"
		android:layout_height="wrap_content"
		android:singleLine="true"
		android:ellipsize="marquee"
	/>

</LinearLayout>

2. Main Layout

– Just a ListView, no more, no less!!!

C – Class Design – On the Idea

This is what I mapped from my mind.

Clss Diagram

Class Diagram

SmsInfo class: hold information about new message, which is also implement from interface Parcelable in order to be passed through by Intent.

SmsInfoAdapter class: the adapter manages content on ListView, extends from class ArrayAdapter<SmsInfo> for simplisticity.

SmsReceiver class: extends from class BroadcastReceiver, to handle the event when new message arrived, pass these messages to Intent and pass to launch MainActivity.

MainActivity class: is a actual class receiving list of new message (List<SmsInfo>) sending from

D – From Design to Code (w/ Passion)

1. SmsInfo.java

package pete.android.study;

import android.os.Parcel;
import android.os.Parcelable;

public class SmsInfo implements Parcelable {
	private String mNumber;
	private String mContent;

	public SmsInfo(String number, String content) {
		mNumber = number;
		mContent = content;
	}

	public SmsInfo(Parcel in) {
		String data[] = new String[2];
		in.readStringArray(data);
		mNumber = data[0];
		mContent = data[1];
	}

	public void setNumber(String number) {
		mNumber = number;
	}
	public String getNumber() {
		return mNumber;
	}

	public void setContent(String content) {
		mContent = content;
	}
	public String getContent() {
		return mContent;
	}

	@Override
	public int describeContents() {
		return 0;
	}

	@Override
	public void writeToParcel(Parcel dest, int flags) {
		dest.writeStringArray(new String[] {
			mNumber, mContent
		});

	}

	public static final Parcelable.Creator<SmsInfo> CREATOR = new Parcelable.Creator<SmsInfo> () {

		@Override
		public SmsInfo createFromParcel(Parcel source) {

			return new SmsInfo(source);
		}

		@Override
		public SmsInfo[] newArray(int size) {

			return new SmsInfo[size];
		}

	};
}

2. SmsInfoAdapter.java

package pete.android.study;

import java.util.List;

import android.app.Activity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;

public class SmsInfoAdapter extends ArrayAdapter<SmsInfo> {

	public SmsInfoAdapter(Activity a, List<SmsInfo> list) {
		super(a, 0, list);

	}

	@Override
	public View getView(int pos, View convertView, ViewGroup parent) {

		ViewHolder holder = null;
		if(convertView == null) {
			Activity a = (Activity)getContext();
			LayoutInflater inflater = a.getLayoutInflater();
			holder = new ViewHolder();
			convertView = inflater.inflate(R.layout.listitem, null);
			holder.tvNumber = (TextView)convertView.findViewById(R.id.tvNumber);
			holder.tvContent = (TextView)convertView.findViewById(R.id.tvContent);
			convertView.setTag(holder);
		} else {
			holder = (ViewHolder)convertView.getTag();
		}

		SmsInfo entry = getItem(pos);
		if(entry != null) {
			holder.tvNumber.setText(entry.getNumber());
			holder.tvContent.setText(entry.getContent());
		}

		return convertView;
	}

	static class ViewHolder {
		TextView tvNumber;
		TextView tvContent;
	}
}

3. SmsReceiver.java

package pete.android.study;

import java.util.ArrayList;
import java.util.List;

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

public class SmsReceiver extends BroadcastReceiver {
	static ArrayList<SmsInfo> listSms = new ArrayList<SmsInfo>();
	@Override
	public void onReceive(Context context, Intent intent) {
		// get SMS map from intent
        Bundle extras = intent.getExtras();
        // a notification message
        String messages = "";
        if ( extras != null ) {
            // get array data from SMS
            Object[] smsExtra = (Object[]) extras.get( "pdus" ); // "pdus" is the key

            for ( int i = 0; i < smsExtra.length; ++i ) {
            	// get sms message
            	SmsMessage sms = SmsMessage.createFromPdu((byte[])smsExtra[i]);
            	// get content and number
            	String body = sms.getMessageBody();
            	String address = sms.getOriginatingAddress();
            	// create display message
            	messages += "SMS from " + address + " :\n";
            	messages += body + "\n";

            	// store in the list
                listSms.add(new SmsInfo(address, body));
            }

            // better check size before continue
            if(listSms.size() > 0) {
            	// notify new arriving message
            	Toast.makeText( context, messages, Toast.LENGTH_SHORT ).show();
            	// set data to send
	            Intent data = new Intent(context, MainActivity.class);
	            // new activity
	            data.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

	            data.putParcelableArrayListExtra("ListSMS", listSms);
	            // start
	            context.startActivity(data);
            }
        }
    }
}

4. MainActivity.java

package pete.android.study;

import java.util.ArrayList;

import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;

public class MainActivity extends Activity {
    ListView mListData;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        mListData = (ListView)findViewById(R.id.lvData);
        // receive list incoming messages
        ArrayList<SmsInfo> listSms = getIntent().getParcelableArrayListExtra("ListSMS");
        // check condition
        if(listSms != null && listSms.size() > 0) {
        	// set dat to list
        	SmsInfoAdapter adapter = new SmsInfoAdapter(this, listSms);
	        mListData.setAdapter(adapter);
        }
    }
}

E – Additional Config

We need to set uses-permission to receive SMS and register our SMSReceiver in order to make it work.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="pete.android.study"
      android:versionCode="1"
      android:versionName="1.0">
    <uses-sdk android:minSdkVersion="10" />
	<uses-permission android:name="android.permission.RECEIVE_SMS" />

    <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>
</manifest>

F – Get the Sample Project by Pete

Click to browse Trunk from GoogleCode.

 

G – Final Words

– Hope you enjoy and learn something from this article 🙂

– Feel free to suggest, comment below!

 

Cheers,

Pete Houston

Auto-close dialog after a specific time

July 13, 2011 10 comments

Not like Toast which is auto closed after 1-2 seconds, Dialog by default is not auto closed and doesn’t have any settings for auto closing.

In case you want your Dialog to auto-close after a time, then you may use a Timer to handle this task. Here a sample:

import java.util.Timer;
import java.util.TimerTask;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.Button;

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

        // get button
        Button btnShow = (Button)findViewById(R.id.btn_show);
        btnShow.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                AlertDialog.Builder builder = new AlertDialog.Builder(v.getContext());
                builder.setTitle("Auto-closing Dialog");
                builder.setMessage("After 2 second, this dialog will be closed automatically!");
                builder.setCancelable(true);

                final AlertDialog dlg = builder.create();

                dlg.show();

                final Timer t = new Timer();
                t.schedule(new TimerTask() {
                    public void run() {
                        dlg.dismiss(); // when the task active then close the dialog
                        t.cancel(); // also just top the timer thread, otherwise, you may receive a crash report
                    }
                }, 2000); // after 2 second (or 2000 miliseconds), the task will be active.

            }
        });
    }
}

I guess it’s easy enough for you to understand, right?

Hope you learn something from it!

 

Cheers,

Pete Houston