Android:使用 ContentObserver 或接收器不工作来捕捉传出的短信

Posted

技术标签:

【中文标题】Android:使用 ContentObserver 或接收器不工作来捕捉传出的短信【英文标题】:Android : Catching Outgoing SMS using ContentObserver or receiver not working 【发布时间】:2016-04-14 00:59:26 【问题描述】:

我尝试使用内容观察器捕捉传出的 SMS 事件。

//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 上工作。

非常感谢您的建议

【问题讨论】:

参考***.com/questions/7550178/intercepting-outgoing-sms 我尝试使用您提到的主题中的代码,但没有运气.. 【参考方案1】:

SDK 中没有 "android.provider.Telephony.SMS_SENT" 操作,在 SMS 发送时也没有任何系统范围的广播,因此您的第二种方法不起作用。

对于ContentObserver,您注册的Uri 必须是SMS Provider 的基础Uri。即,将Uri.parse("content://sms/out") 更改为Uri.parse("content://sms")。如果您只想处理传出消息,则必须在onChange() 方法中查询提供程序,并检索消息的type 列值,检查值2,它表示已发送消息。

如果您支持低于 16 的 API 级别,那么它将是这样的:

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"

【讨论】:

以上是关于Android:使用 ContentObserver 或接收器不工作来捕捉传出的短信的主要内容,如果未能解决你的问题,请参考以下文章

Android之SharedPreferences使用

想要使用cordova/android禁用android的HardBack按钮

如何在Mac中使用Android SDK

何时使用“?android”或“@android”?

Android 安装包优化Android 中使用 SVG 图片 ( 使用 appcompat 支持库兼容 5.0 以下版本的 Android 系统使用矢量图 )

Android Handler使用