您的位置:首页 > 移动开发 > Android开发

Android手机上监听短信的两种方式

2010-12-24 16:26 585 查看
作者:徐建祥

(netpirate@gmail.com)

日期:

2010/08/10

网址:
http://www.anymobile.org


Android
手机上监听短信有两种方式:



1、


接受系统的短信广播,操作短信内容。





优点:操作方便,适合简单的短信应用。

缺点:来信会在状态栏显示通知信息。



AndroidManifest.xml


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

code


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;


}



}

2、


应用观察者模式,监听短信数据库,操作短信内容。



优点:可以拦截来信在状态栏的显示通知,适合作短信拦截。

缺点:可以发展成
MU
,在后台悄悄的收
/
发短信。



实例如下:

SystemEventReceiver
:收到开机启动
OK
的广播后,启动
BootService
服务;收到应用发送短信的
INTENT
后,调用系统接口发送短信

BootService
:开启服务后,打开短信监听器

SMSObserver
:数据观察者,监听短信数据库

SMSHandler
:短信处理器



AndroidManifest.xml


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

code


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();


}


}


}

}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: