我正在尝试检测何时发送短信。我在网上和StackOverflow上搜索过,似乎所有的解决方案都是一样的。 我有一个简单的Activity来启动一个服务,我试图在发送SMS时检测到的服务:
MainActivity.java
import android.os.Bundle;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.util.Log;
import android.view.Menu;
public class MainActivity extends Activity {
Intent serviceIntent;
private static MyReceiver mServiceReceiver;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
@Override
protected void onPause() {
Log.i("Status","Pause");
unregisterReceiver(mServiceReceiver);
super.onPause();
}
@Override
protected void onResume() {
Log.i("Status","Resume");
// Inicio el Servicio
serviceIntent = new Intent(MainActivity.this, TrackerService.class);
startService(serviceIntent);
// Registro el broadcast del Service para obtener los datos
mServiceReceiver = new MyReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(TrackerService.mAction);
registerReceiver(mServiceReceiver, intentFilter);
super.onResume();
}
/**
* Receiver del Service, aqui se obtienen los datos que envia el Service
*/
private class MyReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context arg0, Intent arg1) {
Log.i("ServiceReceiver", "onReceive()");
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
TrackerService.java
import android.app.Service;
import android.content.ContentResolver;
import android.content.Intent;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;
public class TrackerService extends Service{
// Nombre del service
public static final String mAction = "SMSTracker";
ContentResolver content;
ContentResolver contentResolver;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("Status","Service Start");
// ContentResolver para obtener los SMS salientes
contentResolver = this.getContentResolver();
contentResolver.registerContentObserver(Uri.parse("content://sms/out"), true, new mObserver(new Handler()));
return super.onStartCommand(intent, flags, startId);
}
/**
* Observer que obtiene los SMS salientes
*/
class mObserver extends ContentObserver {
public mObserver(Handler handler) {
super(handler);
}
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
Log.i("Status","onChange");
Uri uriSMS = Uri.parse("content://sms/out");
Cursor cur = contentResolver.query(uriSMS, null, null, null, null);
Log.i("SMS", "Columns: " + cur.getColumnNames());
cur.moveToNext();
String smsText = cur.getString(cur.getColumnIndex("body"));
Log.i("SMS", "SMS Lenght: " + smsText.length());
}
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i("Status","Service Destroy");
}
@Override
public IBinder onBind(Intent intent) {
Log.i("Status","Service Bind");
return null;
}
}
清单
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="15" />
<uses-permission android:name="android.permission.RECEIVE_SMS"></uses-permission>
<uses-permission android:name="android.permission.READ_SMS"></uses-permission>
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/title_activity_main" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".TrackerService" />
</application>
根据我的LogCat,服务已启动,我可以在我的Android手机中运行服务中看到它onChange()方法我的服务内部从未在发送短信时调用。是我缺少的东西吗?
答案 0 :(得分:1)
如果您将content://sms/out
替换为content://sms/
,您会看到在发送短信但收到短信时未调用ContentObserver。这是我的观察者的代码。它只在接收SMS时输入onChange(boolean)。那时协议是“0”。
所以,我和你一样震惊:(
class SmsProviderObserver extends ContentObserver {
public SmsProviderObserver(Handler handler) {
super(handler);
}
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
Uri uriSms = Uri.parse("content://sms/");
ContentResolver cr = getContentResolver();
Cursor cur = cr.query(uriSms, null, null, null, null);
// this will make it point to the first record, which is the last
// SMS sent
if (!cur.moveToNext()) {
return; // weird!
}
String protocol = cur.getString(cur.getColumnIndex("protocol"));
if (protocol == null) {
// send
Log.i("SMS", "SMS SEND");
int threadId = cur.getInt(cur.getColumnIndex("thread_id"));
Log.i("SMS", "SMS SEND ID = " + threadId);
Cursor c = cr.query(
Uri.parse("content://sms/outbox/" + threadId), null,
null, null, null);
c.moveToNext();
int p = cur.getInt(cur.getColumnIndex("person"));
Log.i("SMS", "SMS SEND person= " + p);
// getContentResolver().delete(Uri.parse("content://sms/conversations/"
// + threadId), null, null);
} else {
// receive
Log.i("SMS", "SMS RECIEVE");
int threadIdIn = cur.getInt(cur.getColumnIndex("thread_id"));
cr.delete(
Uri.parse("content://sms/conversations/" + threadIdIn),
null, null);
}
}
}
注册观察者的代码:
ContentResolver contentResolver = getContentResolver();
mSmsObserverHandler = new Handler();
mSmsProviderObserver = new SmsProviderObserver(mSmsObserverHandler);
contentResolver.registerContentObserver(Uri.parse("content://sms/"), true, mSmsProviderObserver);
答案 1 :(得分:1)
好吧,似乎没有办法,不知道这是否是我在Android上的错误错误,但我得到了它的工作:
if( (type == 2 || type == 1) && (!lastID.contentEquals(cur.getString(cur.getColumnIndex("_id")))) ){
String protocol = cur.getString(cur.getColumnIndex("protocol"));
lastID = cur.getString(cur.getColumnIndex("_id"));
// Mensaje enviado
if(protocol == null){
Log.i("SMSStatus", "SMS Sent");
}
// Mensaje recibido
else{
Log.i("SMSStatus", "SMS received");
}
}
当收到短信时,它是type = 1,当发送短信及其类型6,4时最后发送时是type = 2.小心,因为有时onChange方法被调用很多次无关紧要它只有一条短信,所以你应该通过检查_id参数来检测它是否是同一条短信。