在Android中收听外发短信或发送框

时间:2011-04-27 18:09:56

标签: android sms

我正在开发一个应用程序,它将所有传入和传出的短信存储在SD卡的文本文件中。

我能够使用广播接收器收听传入的消息。我发现收听外发短信非常困难。

我在某种程度上知道需要设置发送的盒子或发件箱上的内容观察者,但我不知道该怎么做。

如何做到这一点?

4 个答案:

答案 0 :(得分:47)

基本上,你必须注册一个内容观察者......就像这样:

ContentResolver contentResolver = context.getContentResolver();
contentResolver.registerContentObserver(Uri.parse("content://sms/out"),true, yourObserver);

yourObserver是一个对象(new YourObserver(new Handler())),可能如下所示:

class YourObserver extends ContentObserver {

    public YourObserver(Handler handler) {
        super(handler);
    }

    @Override
    public void onChange(boolean selfChange) {
        super.onChange(selfChange);
        // save the message to the SD card here
    }
}

那么,你究竟如何获得短信的内容?您必须使用Cursor

// save the message to the SD card here
Uri uriSMSURI = Uri.parse("content://sms/out");
Cursor cur = this.getContentResolver().query(uriSMSURI, null, null, null, null);
 // this will make it point to the first record, which is the last SMS sent
cur.moveToNext();
String content = cur.getString(cur.getColumnIndex("body"));
// use cur.getColumnNames() to get a list of all available columns...
// each field that compounds a SMS is represented by a column (phone number, status, etc.)
// then just save all data you want to the SDcard :)

答案 1 :(得分:5)

这是我解决这个问题的方法

  1. 创建从其他活动调用的服务
  2. 在其中创建内容观察者

     @Override
     public int onStartCommand(Intent intent, int flag, int startId) {
     MyObserver myObserver = new MyObserver(new Handler());
     ContentResolver contentResolver = this.getApplicationContext().getContentResolver();
     contentResolver.registerContentObserver(Uri.parse("content://sms/sent"), true, myObserver);
     return START_STICKY;
     }
    
  3. 创建观察者类

    class MyObserver extends ContentObserver {
    
    public MyObserver(Handler handler) {
        super(handler);
    }
    
    @Override
    public void onChange(boolean selfChange) {
        super.onChange(selfChange);
        Uri uriSMSURI = Uri.parse("content://sms/sent");
        Cursor cur = getContentResolver().query(uriSMSURI, null, null, null, null);
        cur.moveToNext();
        String content = cur.getString(cur.getColumnIndex("body"));
        String smsNumber = cur.getString(cur.getColumnIndex("address"));
        if (smsNumber == null || smsNumber.length() <= 0) {
            smsNumber = "Unknown";
        }
        cur.close();
    
        if(smsChecker( "OutgoingSMS to " + smsNumber + ": " + content)) {
            //save data into database/sd card here
        }
    }
    }
    
  4. 我添加了一个方法smsChecker()来检查新消息是否与上一条消息相同

    public boolean smsChecker(String sms) {
    boolean flagSMS = true;
    
    if (sms.equals(lastSMS)) {
        flagSMS = false;
    }
    else {
        lastSMS = sms;
    }
    //if flagSMS = true, those 2 messages are different
    return flagSMS;
    }
    
  5. 如果我没有弄错的话,如果我们只想检查所有发送的消息,我们使用“content:// sms / sent”,如果我们只想查看发件箱内的所有消息,请使用“content:// sms / out”,如果我们要查看所有消息,请选择“content:// sms”。

答案 2 :(得分:2)

这是我的版本,已在Android 6.0 +中验证

if (scrollTop > 5) {
  $('#menu').addClass('darkerbg');
}
else {
  $('#menu').removeClass('darkerbg');
}

将此代码放在应启用观察者的位置

class smsObserver extends ContentObserver {

    private String lastSmsId;

    public smsObserver(Handler handler) {
        super(handler);
    }

    @Override
    public void onChange(boolean selfChange) {
        super.onChange(selfChange);
        Uri uriSMSURI = Uri.parse("content://sms/sent");
        Cursor cur = getContentResolver().query(uriSMSURI, null, null, null, null);
        cur.moveToNext();
        String id = cur.getString(cur.getColumnIndex("_id"));
        if (smsChecker(id)) {
            String address = cur.getString(cur.getColumnIndex("address"));
            // Optional: Check for a specific sender
            if (address.equals(phoneNumber)) {
                String message = cur.getString(cur.getColumnIndex("body"));
                // Use message content for desired functionality
            }
        }
    }

    // Prevent duplicate results without overlooking legitimate duplicates
    public boolean smsChecker(String smsId) {
        boolean flagSMS = true;

        if (smsId.equals(lastSmsId)) {
            flagSMS = false;
        }
        else {
            lastSmsId = smsId;
        }

        return flagSMS;
    }
}

这假设您正在使用某项活动。请记住,您需要一个Context参考来从服务或接收者中调用ContentResolver contentResolver = getContentResolver(); contentResolver.registerContentObserver(Uri.parse("content://sms"), true, new smsObserver(new Handler()));

答案 3 :(得分:0)

我看到了什么问题。它在线:

 contentResolver.registerContentObserver(Uri.parse("content://sms/sent"), true, _myObserver);

您必须删除&#39; / sent&#39;并写下内容://短信&#39; 已在ContentObserver中指定它以查看已发送的短信。