2012-10-02 51 views
3

我正在嘗試檢測SMS何時發送。我在網上和StackOverflow上搜索,似乎都是相同的解決方案。 我有一個啓動的服務,並在服務我想檢測時,短信發送一個簡單的活動:爲什麼發送短信時我的ContentObserver未被調用?

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()我的服務內部方法從來沒有調用,當我發送短信。我錯過了什麼?

回答

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"); 
      } 
     } 

當收到短信則輸入= 1,當發送n SMS和它的類型6,4,最後發送時是type = 2。要小心,因爲有時onChange方法被調用很多次,如果它只有一個SMS,那麼你應該檢測它是否是相同的SMS檢查_id參數。

+1

你能告訴他們爲什麼你把**!lastID.contentEquals(cur.getString(cur.getColumnIndex(「_ id」)))** condition – OnePunchMan

1

如果您將content://sms/out替換爲content://sms/,您將看到在發送SMS但接收到ContentObserver時未調用ContentObserver。這是我的觀察員的代碼。它只在接收短信時進入onChange(布爾)。該協議當時是「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); 
+0

ContentObserver被調用時,短信發送,當它也收到:)我得到它的工作惠威解決方法 – Andres

+0

最後,我發現了一個有趣的事實:當通過代碼發送短信使用SmsManager.sendMultipartTextMessage( )'那麼SMS數據庫中沒有寫入任何SMS條目。這就是爲什麼我從未收到發送通知。但是,當試圖通過信使應用程序進行同樣的寫作併發送短信時,數據庫中有條目,並且我收到了有關它正在發送的通知。 – slash33