Android:使用ContentObserver或接收器无法捕获传出的SMS [英] Android : Catching Outgoing SMS using ContentObserver or receiver not working

查看:213
本文介绍了Android:使用ContentObserver或接收器无法捕获传出的SMS的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  //测试观察者
ContentObserver co =新SMSoutObserver(new Handler(),getApplicationContext());
ContentResolver contentResolver = getApplicationContext()。getContentResolver();
contentResolver.registerContentObserver(Uri.parse( content:// sms / out),true,co);
//结束测试观察员

 公共类SMSoutObserver扩展ContentObserver {

private Context mCtx;

公共SMSoutObserver(处理程序处理程序,上下文ctx){
super(handler);
mCtx = ctx;
}

@Override
public void onChange(boolean selfChange){
super.onChange(selfChange);
//将消息保存到SD卡在这里
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>

带接收者

 公共类SMSReceiver扩展了BroadcastReceiver {

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

Logger.d(触发了SMSReceiver);
if(intent.getAction()。equals( android.provider.Telephony.SMS_RECEIVED)){
//对收到的短信进行处理
Logger.d(传入短信 );
} else if(intent.getAction()。equals( android.provider.Telephony.SMS_SENT)){
//对发送的短信进行处理
Logger.d(传出短信);
}
//启动提醒服务
// context.startService(new Intent(context,ReminderService.class));
} catch(异常e){
Logger.e( onReceive方法无法处理);
TrackingEventLogHelper.logException(e,Constants.Global.EXCEPTION,
Constants.ExceptionMessage.EXC_CANNOT_CANNOT_PROCESS_REBOOT_RECEIVER,true);
}
}

}

但这接收方仅触发传入消息,而不触发传出消息。我也应该以正确的方式在Android版本> 5上工作。



非常感谢您的建议

解决方案

没有<$ SDK中的c $ c> android.provider.Telephony.SMS_SENT 操作,在发送SMS时也不进行任何系统范围的广播,因此您的第二种方法将无法工作。 / p>

对于 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){
游标游标= 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){
//发送消息
}
}
}
最后{
if (光标!= null)
cursor.close();
}
}

从API 16开始, ContentObserver 类提供 onChange()重载,该重载将为特定的 Uri message作为第二个参数,与基本的 Uri 相比,您可以更有效地进行查询和检查。另外,如果您的最低API级别为19,则可以使用多个带有常量的类来替代上面的示例代码中定义的那些。



另外,发件箱的 Uri content:// sms / outbox ,而不是 content :// sms / out


i trying to catch outgoing SMS event using content observer.

//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

and

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

But if i send outgoing message in emulator event is not triggered.

I tried use receiver too.

<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>

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

}

But this receiver is triggering only for incoming messages, not for outgoing. How should i do it in the right way working on android version > 5 too.

Many thanks for any advice

解决方案

There is no "android.provider.Telephony.SMS_SENT" action in the SDK, nor is there any system-wide broadcast upon an SMS send, so your second method isn't going to work.

As for the ContentObserver, the Uri you register for must be the base Uri for the SMS Provider. That is, change Uri.parse("content://sms/out") to Uri.parse("content://sms"). If you want to handle only outgoing messages, you will have to query the Provider in the onChange() method, and retrieve the type column value for the message, checking for a value of 2, which indicates a sent message.

If you're supporting an API level lower than 16, then it would be something like this:

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

Starting with API 16, the ContentObserver class offers an onChange() overload that will provide the specific Uri for the message as the second parameter, which you can query and inspect more efficiently than the base Uri. Also, if your minimum API level is 19, there are several classes with constants that you can substitute for those defined in the example code above.

As a side note, the Uri for the outbox is "content://sms/outbox", not "content://sms/out".

这篇关于Android:使用ContentObserver或接收器无法捕获传出的SMS的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆