【发布时间】:2012-03-01 16:41:40
【问题描述】:
我对如何确定是否从设备发送了 SMS 感兴趣。
为了在收到短信时收到通知,我们使用广播器:
android.provider.Telephony.SMS_RECEIVED
重要的是,我不会从我的应用程序发送短信,我只是应该在从设备发送短信时收听。
也许我应该听取一些内容提供商(与 SMS 有某种关联)并针对这种变化做出反应。有什么想法可以实现吗?
【问题讨论】:
标签: android
我对如何确定是否从设备发送了 SMS 感兴趣。
为了在收到短信时收到通知,我们使用广播器:
android.provider.Telephony.SMS_RECEIVED
重要的是,我不会从我的应用程序发送短信,我只是应该在从设备发送短信时收听。
也许我应该听取一些内容提供商(与 SMS 有某种关联)并针对这种变化做出反应。有什么想法可以实现吗?
【问题讨论】:
标签: android
是的,可以使用 ContentObserver 收听 SMS ContentProvider
这是我的外发短信示例:
首先向 content://sms/ 注册一个 ContetObserver
public class Smssendservice extends Service{
@Override
public void onCreate() {
SmsContent content = new SmsContent(new Handler());
// REGISTER ContetObserver
this.getContentResolver().
registerContentObserver(Uri.parse("content://sms/"), true, SMSObserver);
}
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
SMSObserver.class
public class SMSObserver extends ContentObserver {
private Handler m_handler = null;
public SMSObserver(SMSLogger handler){
super(handler);
m_handler = handler;
}
@Override
public void onChange(boolean selfChange) {
super.onChange(bSelfChange);
Uri uriSMSURI = Uri.parse("content://sms");
Cursor cur = this.getContentResolver().query(uriSMSURI, null, null,
null, null);
cur.moveToNext();
String protocol = cur.getString(cur.getColumnIndex("protocol"));
if(protocol == null) {
//the message is sent out just now
}
else {
//the message is received just now
}
}
}
}
【讨论】:
Cursor cur = this.getContentResolver().....。与getContentResolver() 有什么关系?因为 eclipse 将此显示为错误。
cur = context.getContentResolver().query(uri, cursorProjection, null, null, CallLog.Calls.DEFAULT_SORT_ORDER); 我记得有一个DEFAULT_SORT_ORDER 修复了一个错误,并被复制到其他query() 调用以防万一。
使用以下方法发送短信,并检查短信是否送达。
send.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
String phoneNo = "Phone number to sent";
String message = "Your message";
if (phoneNo.length() > 0 && message.length() > 0) {
TelephonyManager telMgr = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
int simState = telMgr.getSimState();
switch (simState) {
case TelephonyManager.SIM_STATE_ABSENT:
displayAlert();
break;
case TelephonyManager.SIM_STATE_NETWORK_LOCKED:
// do something
break;
case TelephonyManager.SIM_STATE_PIN_REQUIRED:
// do something
break;
case TelephonyManager.SIM_STATE_PUK_REQUIRED:
// do something
break;
case TelephonyManager.SIM_STATE_READY:
// do something
sendSMS(phoneNo, message); // method to send message
break;
case TelephonyManager.SIM_STATE_UNKNOWN:
// do something
break;
}
} else {
Toast.makeText(getBaseContext(),
"Please enter both phone number and message.",
Toast.LENGTH_SHORT).show();
}
}
private void displayAlert() {
// TODO Auto-generated method stub
new AlertDialog.Builder(YourActivity.this)
.setMessage("Sim card not available")
.setCancelable(false)
// .setIcon(R.drawable.alert)
.setPositiveButton("ok",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int id) {
Log.d("I am inside ok", "ok");
dialog.cancel();
}
})
.show();
}
});
private void sendSMS(String phoneNumber, String message) {
String SENT = "SMS_SENT";
String DELIVERED = "SMS_DELIVERED";
PendingIntent sentPI = PendingIntent.getBroadcast(YourActivity.this, 0,
new Intent(SENT), 0);
PendingIntent deliveredPI = PendingIntent.getBroadcast(YourActivity.this,
0, new Intent(DELIVERED), 0);
// ---when the SMS has been sent---
final String string = "deprecation";
registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context arg0, Intent arg1) {
switch (getResultCode()) {
case Activity.RESULT_OK:
Toast.makeText(YourActivity.this, "SMS sent",
Toast.LENGTH_SHORT).show();
break;
case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
Toast.makeText(YourActivity.this, "Generic failure",
Toast.LENGTH_SHORT).show();
break;
case SmsManager.RESULT_ERROR_NO_SERVICE:
Toast.makeText(YourActivity.this, "No service",
Toast.LENGTH_SHORT).show();
break;
case SmsManager.RESULT_ERROR_NULL_PDU:
Toast.makeText(YourActivity.this, "Null PDU",
Toast.LENGTH_SHORT).show();
break;
case SmsManager.RESULT_ERROR_RADIO_OFF:
Toast.makeText(getBaseContext(), "Radio off",
Toast.LENGTH_SHORT).show();
break;
}
}
}, new IntentFilter(SENT));
// ---when the SMS has been delivered---
registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context arg0, Intent arg1) {
switch (getResultCode()) {
case Activity.RESULT_OK:
Toast.makeText(YourActivity.this, "SMS delivered",
Toast.LENGTH_SHORT).show();
break;
case Activity.RESULT_CANCELED:
Toast.makeText(YourActivity.this, "SMS not delivered",
Toast.LENGTH_SHORT).show();
break;
}
}
}, new IntentFilter(DELIVERED));
SmsManager sms = SmsManager.getDefault();
sms.sendTextMessage(phoneNumber, null, message, sentPI, deliveredPI);
}
【讨论】:
想到的一件事是使用 logcat 日志。每次发送/接收 SMS 时,都会有一个特定条目。只需在调试和测试中连接您的手机,您就会观察到具体的条目。
我应该提到这个方法是在你的应用程序中完成的,所以你可以将它应用到你的代码中。
拉一下this。可能还有其他方法,但这似乎相当容易且可行。
【讨论】: