1、 接受系统的短信广播,操作短信内容。
优点:操作方便,适合简单的短信应用。
缺点:来信会在状态栏显示通知信息。
AndroidManifest.xml:
复制代码
code:
复制代码
2、 应用观察者模式,监听短信数据库,操作短信内容。 优点:可以拦截来信在状态栏的显示通知,适合作短信拦截。缺点:可以发展成MU,在后台悄悄的收/发短信。 实例如下:SystemEventReceiver:收到开机启动OK的广播后,启动BootService服务;收到应用发送短信的INTENT后,调用系统接口发送短信BootService:开启服务后,打开短信监听器SMSObserver:数据观察者,监听短信数据库SMSHandler:短信处理器 AndroidManifest.xml:
复制代码
code:
复制代码
OVER!
- <uses-permission android:name="android.permission.SEND_SMS"></uses-permission>
- <uses-permission android:name="android.permission.RECEIVE_SMS"></uses-permission>
- <!-- Receiver -->
- <receiver android:name=".sms.SMSReceiver">
- <intent-filter>
- <action android:name="android.provider.Telephony.SMS_RECEIVED" />
- </intent-filter>
- </receiver>
- package org.anymobile.demo.sms;
- import android.content.BroadcastReceiver;
- import android.content.Context;
- import android.content.Intent;
- import android.telephony.gsm.SmsMessage;
- import android.util.Log;
- public class SMSReceiver extends BroadcastReceiver
- {
- public static final String TAG = "ImiChatSMSReceiver";
- //android.provider.Telephony.Sms.Intents
- public static final String SMS_RECEIVED_ACTION = "android.provider.Telephony.SMS_RECEIVED";
-
- @Override
- public void onReceive(Context context, Intent intent)
- {
- if (intent.getAction().equals(SMS_RECEIVED_ACTION))
- {
- SmsMessage[] messages = getMessagesFromIntent(intent);
- for (SmsMessage message : messages)
- {
- Log.i(TAG, message.getOriginatingAddress() + " : " +
- message.getDisplayOriginatingAddress() + " : " +
- message.getDisplayMessageBody() + " : " +
- message.getTimestampMillis());
- }
- }
- }
-
- public final SmsMessage[] getMessagesFromIntent(Intent intent)
- {
- Object[] messages = (Object[]) intent.getSerializableExtra("pdus");
- byte[][] pduObjs = new byte[messages.length][];
- for (int i = 0; i < messages.length; i++)
- {
- pduObjs[i] = (byte[]) messages[i];
- }
- byte[][] pdus = new byte[pduObjs.length][];
- int pduCount = pdus.length;
- SmsMessage[] msgs = new SmsMessage[pduCount];
- for (int i = 0; i < pduCount; i++)
- {
- pdus[i] = pduObjs[i];
- msgs[i] = SmsMessage.createFromPdu(pdus[i]);
- }
- return msgs;
- }
- }
- <uses-permission android:name="android.permission.READ_SMS"></uses-permission>
- <uses-permission android:name="android.permission.WRITE_SMS"></uses-permission>
- <!-- Service -->
- <service android:name=".BootService"
- android:label="@string/app_name">
- <intent-filter>
- <action android:name="org.anymobile.test.service.IMICHAT" />
- <category android:name="android.intent.category.DEFAULT" />
- </intent-filter>
- </service>
- <!-- Receiver -->
- <receiver android:name=".SystemEventReceiver">
- <intent-filter>
- <action android:name="android.intent.action.BOOT_COMPLETED" />
- </intent-filter>
- </receiver>
- package org.anymobile.demo.sms;
- import android.content.ContentUris;
- import android.content.Context;
- import android.content.Intent;
- import android.net.Uri;
- import android.os.Handler;
- import android.os.Message;
- import android.util.Log;
- public class SMSHandler extends Handler
- {
- public static final String TAG = "SMSHandler";
- private Context mContext;
-
- public SMSHandler(Context context)
- {
- super();
- this.mContext = context;
- }
-
- public void handleMessage(Message message)
- {
- Log.i(TAG, "handleMessage: " + message);
-
- MessageItem item = (MessageItem) message.obj;
- //delete the sms
- Uri uri = ContentUris.withAppendedId(SMS.CONTENT_URI, item.getId());
- mContext.getContentResolver().delete(uri, null, null);
- Log.i(TAG, "delete sms item: " + item);
- }
- }
- package org.anymobile.demo.sms;
- import android.content.ContentResolver;
- import android.database.ContentObserver;
- import android.database.Cursor;
- import android.os.Handler;
- import android.os.Message;
- import android.util.Log;
- public class SMSObserver extends ContentObserver
- {
- public static final String TAG = "SMSObserver";
-
- private static final String[] PROJECTION = new String[]
- {
- SMS._ID,//0
- SMS.TYPE,//1
- SMS.ADDRESS,//2
- SMS.BODY,//3
- SMS.DATE,//4
- SMS.THREAD_ID,//5
- SMS.READ,//6
- SMS.PROTOCOL//7
- };
- private static final String SELECTION =
- SMS._ID + " > %s" +
- // " and " + SMS.PROTOCOL + " = null" +
- // " or " + SMS.PROTOCOL + " = " + SMS.PROTOCOL_SMS + ")" +
- " and (" + SMS.TYPE + " = " + SMS.MESSAGE_TYPE_INBOX +
- " or " + SMS.TYPE + " = " + SMS.MESSAGE_TYPE_SENT + ")";
-
- private static final int COLUMN_INDEX_ID = 0;
- private static final int COLUMN_INDEX_TYPE = 1;
- private static final int COLUMN_INDEX_PHONE = 2;
- private static final int COLUMN_INDEX_BODY = 3;
- private static final int COLUMN_INDEX_PROTOCOL = 7;
- private static final int MAX_NUMS = 10;
- private static int MAX_ID = 0;
- private ContentResolver mResolver;
- private Handler mHandler;
-
- public SMSObserver(ContentResolver contentResolver, Handler handler)
- {
- super(handler);
-
- this.mResolver = contentResolver;
- this.mHandler = handler;
- }
- @Override
- public void onChange(boolean selfChange)
- {
- Log.i(TAG, "onChange : " + selfChange + "; " + MAX_ID + "; " + SELECTION);
- super.onChange(selfChange);
-
- Cursor cursor = mResolver.query(SMS.CONTENT_URI, PROJECTION,
- String.format(SELECTION, MAX_ID), null, null);
-
- int id, type, protocol;
- String phone, body;
- Message message;
- MessageItem item;
-
- int iter = 0;
- boolean hasDone = false;
-
- while (cursor.moveToNext())
- {
- id = cursor.getInt(COLUMN_INDEX_ID);
- type = cursor.getInt(COLUMN_INDEX_TYPE);
- phone = cursor.getString(COLUMN_INDEX_PHONE);
- body = cursor.getString(COLUMN_INDEX_BODY);
- protocol = cursor.getInt(COLUMN_INDEX_PROTOCOL);
-
- if (hasDone)
- {
- MAX_ID = id;
- break;
- }
- if (protocol == SMS.PROTOCOL_SMS && body != null && body.startsWith(SMS.FILTER))
- {
- hasDone = true;
-
- item = new MessageItem();
- item.setId(id);
- item.setType(type);
- item.setPhone(phone);
- item.setBody(body);
- item.setProtocol(protocol);
-
- message = new Message();
- message.obj = item;
- mHandler.sendMessage(message);
- }
- else
- {
- if (id > MAX_ID) MAX_ID = id;
- }
- if (iter > MAX_NUMS) break;
- iter ++;
- }
- }
- }
- package org.anymobile.demo.sms;
- import android.net.Uri;
- import android.provider.BaseColumns;
- public interface SMS extends BaseColumns
- {
- public static final Uri CONTENT_URI = Uri.parse("content://sms");
- public static final String FILTER = "!imichat";
-
- public static final String TYPE = "type";
- public static final String THREAD_ID = "thread_id";
- public static final String ADDRESS = "address";
- public static final String PERSON_ID = "person";
- public static final String DATE = "date";
- public static final String READ = "read";
- public static final String BODY = "body";
- public static final String PROTOCOL = "protocol";
- public static final int MESSAGE_TYPE_ALL = 0;
- public static final int MESSAGE_TYPE_INBOX = 1;
- public static final int MESSAGE_TYPE_SENT = 2;
- public static final int MESSAGE_TYPE_DRAFT = 3;
- public static final int MESSAGE_TYPE_OUTBOX = 4;
- public static final int MESSAGE_TYPE_FAILED = 5; // for failed outgoing messages
- public static final int MESSAGE_TYPE_QUEUED = 6; // for messages to send later
-
- public static final int PROTOCOL_SMS = 0;//SMS_PROTO
- public static final int PROTOCOL_MMS = 1;//MMS_PROTO
- }
- package org.anymobile.demo.sms;
- public class MessageItem implements java.io.Serializable
- {
- private static final long serialVersionUID = 1L;
-
- private int id;
- private int type;
- private int protocol;
- private String phone;
- private String body;
-
- public MessageItem()
- {}
- public int getId()
- {
- return id;
- }
- public void setId(int id)
- {
- this.id = id;
- }
- public int getType()
- {
- return type;
- }
- public void setType(int type)
- {
- this.type = type;
- }
- public int getProtocol()
- {
- return protocol;
- }
- public void setProtocol(int protocol)
- {
- this.protocol = protocol;
- }
- public String getPhone()
- {
- return phone;
- }
- public void setPhone(String phone)
- {
- this.phone = phone;
- }
- public String getBody()
- {
- return body;
- }
- public void setBody(String body)
- {
- this.body = body;
- }
-
- public String toString()
- {
- return
- "id = " + id + ";" +
- "type = " + type + ";" +
- "protocol = " + protocol + ";" +
- "phone = " + phone + ";" +
- "body = " + body;
- }
- }
- package org.anymobile.demo;
- import android.app.Service;
- import android.content.ContentResolver;
- import android.content.Intent;
- import android.database.ContentObserver;
- import android.os.Handler;
- import android.os.IBinder;
- import android.os.Process;
- import android.util.Log;
- import org.anymobile.demo.sms.SMS;
- import org.anymobile.demo.sms.SMSHandler;
- import org.anymobile.demo.sms.SMSObserver;
- public class BootService extends Service
- {
- public static final String TAG = "BootService";
-
- private ContentObserver mObserver;
- private Handler mHandler = new Handler();
-
- @Override
- public void onCreate()
- {
- Log.i(TAG, "onCreate().");
- super.onCreate();
-
- addSMSObserver();
- }
-
- public void addSMSObserver()
- {
- Log.i(TAG, "add a SMS observer. ");
-
- ContentResolver resolver = getContentResolver();
-
- Handler handler = new SMSHandler(this);
- mObserver = new SMSObserver(resolver, handler);
- resolver.registerContentObserver(SMS.CONTENT_URI, true, mObserver);
- }
- @Override
- public IBinder onBind(Intent intent)
- {
- return null;
- }
- @Override
- public void onDestroy()
- {
- Log.i(TAG, "onDestroy().");
-
- this.getContentResolver().unregisterContentObserver(mObserver);
-
- super.onDestroy();
- Process.killProcess(Process.myPid());
- System.exit(0);
- }
- }
- package org.anymobile.demo;
- import android.content.BroadcastReceiver;
- import android.content.Context;
- import android.content.Intent;
- //import android.os.Handler;
- //import android.os.Message;
- import android.telephony.gsm.SmsManager;
- import org.anymobile.demo.sms.MessageItem;
- public class SystemEventReceiver extends BroadcastReceiver
- {
- @Override
- public void onReceive(Context context, Intent intent)
- {
- if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED))
- {
- context.startService(new Intent(Globals.IMICHAT_SERVICE));
- }
- else if (intent.getAction().equals(Globals.ACTION_SEND_SMS))
- {
- MessageItem mItem =
- (MessageItem) intent.getSerializableExtra(Globals.EXTRA_SMS_DATA);
- if (mItem != null && mItem.getPhone() != null && mItem.getBody() != null)
- {
- SmsManager.getDefault()
- .sendTextMessage(mItem.getPhone(), null,
- mItem.getBody(), null, null);
- // new Thread(mTasks).start();
- }
- }
- }
- }