2016-01-09 85 views
2

我試圖使用內容觀察者捕捉傳出的SMS事件。Android:捕捉使用ContentObserver或接收器不工作的傳出短信

//TEST OBSERVER 
     ContentObserver co = new SMSoutObserver(new Handler(), getApplicationContext()); 
     ContentResolver contentResolver = getApplicationContext().getContentResolver(); 
     contentResolver.registerContentObserver(Uri.parse("content://sms/out"),true, co); 
     // END TEST OBSERVER 

public class SMSoutObserver extends ContentObserver { 

    private Context mCtx; 

    public SMSoutObserver(Handler handler, Context ctx) { 
     super(handler); 
     mCtx = ctx; 
    } 

    @Override 
    public void onChange(boolean selfChange) { 
     super.onChange(selfChange); 
     // save the message to the SD card here 
     Logger.d("On Change"); 
     Toast.makeText(mCtx,"TEST", Toast.LENGTH_LONG).show(); 
    } 
} 

但是,如果我在模擬器事件發送傳出消息不會被觸發。

我也嘗試過使用接收器。

<receiver android:name=".receiver.SMSReceiver" 
        android:enabled="true" 
        android:exported="true" 
        android:priority="1000"> 
      <intent-filter> 
       <action android:name="android.provider.Telephony.SMS_RECEIVED" /> 
       <action android:name="android.provider.Telephony.SMS_SENT"/> 
      </intent-filter> 
     </receiver> 

與接收機

public class SMSReceiver extends BroadcastReceiver { 

    @Override 
    public void onReceive(Context context, Intent intent) { 
     try { 

      Logger.d("SMSReceiver triggered"); 
      if (intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED")){ 
       //do something with the received sms 
       Logger.d("Incoming SMS"); 
      }else if(intent.getAction().equals("android.provider.Telephony.SMS_SENT")){ 
       //do something with the sended sms 
       Logger.d("Outgoing SMS"); 
      } 
      // Start reminder service 
      // context.startService(new Intent(context, ReminderService.class)); 
     } catch (Exception e) { 
      Logger.e("onReceive method cannot be processed"); 
      TrackingEventLogHelper.logException(e, Constants.Global.EXCEPTION, 
        Constants.ExceptionMessage.EXC_CANNOT_CANNOT_PROCESS_REBOOT_RECEIVER, true); 
     } 
    } 

} 

但這接收機僅觸發傳入的消息,而不是用於傳出。我應該如何以正確的方式在android版本> 5上進行操作。

非常感謝您的任何意見

+0

參考http://stackoverflow.com/questions/7550178/intercepting-outgoing-sms – sasikumar

+0

我試圖使用代碼從主題您提到,但沒有運氣.. – redrom

回答

1

有一個在SDK沒有"android.provider.Telephony.SMS_SENT"行動,也沒有在短信發送的任何系統範圍內的廣播,讓你的第二個方法是行不通的。

至於ContentObserver,您註冊的Uri必須是SMS提供商的基地Uri。也就是說,將Uri.parse("content://sms/out")更改爲Uri.parse("content://sms")。如果只想處理傳出消息,則必須在onChange()方法中查詢提供程序,並檢索消息的type列值,並檢查值2,該值指示發送的消息。

如果你支持的API級別低於16,那麼這將是這樣的:

private static final Uri uri = Uri.parse("content://sms"); 
private static final String COLUMN_TYPE = "type"; 
private static final int MESSAGE_TYPE_SENT = 2; 
... 

@Override 
public void onChange(boolean selfChange) { 
    Cursor cursor = null; 

    try { 
     cursor = resolver.query(uri, null, null, null, null); 

     if (cursor != null && cursor.moveToFirst()) { 
      int type = cursor.getInt(cursor.getColumnIndex(COLUMN_TYPE)); 

      if (type == MESSAGE_TYPE_SENT) { 
       // Sent message 
      } 
     } 
    } 
    finally { 
     if (cursor != null) 
      cursor.close(); 
    } 
} 

開始與API 16日,ContentObserver類提供了一個onChange()超載,將提供特定的Uri該消息作爲第二個參數,您可以比基地Uri更有效地查詢和檢查。另外,如果您的最低API級別爲19,則有幾個常量類可以替代上面示例代碼中定義的類。

作爲一個附註,發件箱的Uri"content://sms/outbox",而不是"content://sms/out"