Android从收件箱获取短信,优化了阅读所有消息并对其进行分组的方式



嗨,正在实施一个SMS应用程序,现在能够检索所有消息及其各自的联系信息,如显示名称,照片uri..并将它们显示在自定义列表中,在项目单击上将带您进入相应的讨论。在这里,我的问题是同步所有这些消息所花费的时间,

  1. 这次我需要优化。
  2. 每次我在讨论视图中发送新消息并返回最近的聊天时,我只需要更新特定项目,而不是整个列表。

这是我的代码:

阅读短信.java:

public class ReadSMS {
    ArrayList<HashMap<Contact, ArrayList<OneComment>>> recentChats;
    Application _context;
    public ReadSMS(Application context) {
        this._context = context;
        this.recentChats = ((ChatApplication) _context).getChats();
    }
    public ArrayList<HashMap<Contact, ArrayList<OneComment>>> getSMS() {
        // Init
        ArrayList<SmsMsg> smsMsgs = new ArrayList<SmsMsg>();
        TreeSet<Integer> threadIds = new TreeSet<Integer>();
        Uri mSmsinboxQueryUri = Uri.parse("content://sms");
        Cursor cursor = _context.getContentResolver().query(
                mSmsinboxQueryUri,
                new String[] { "_id", "thread_id", "address", "date", "body",
                        "type" }, null, null, null);
        String[] columns = new String[] { "address", "thread_id", "date",
                "body", "type" };
        if (cursor.getCount() > 0) {
            while (cursor.moveToNext()) {
                SmsMsg smsMsg = new SmsMsg();
                String address = null, displayName = null, date = null, msg = null, type = null, threadId = null;
                Uri photoUri = null;
                threadId = cursor.getString(cursor.getColumnIndex(columns[1]));
                type = cursor.getString(cursor.getColumnIndex(columns[4]));
                if (Integer.parseInt(type) == 1 || Integer.parseInt(type) == 2) {
                    address = cursor.getString(cursor
                            .getColumnIndex(columns[0]));
                    if (address.length() > 0) {
                        String[] contactData = getContactByNumber(address);
                        if (contactData != null) {
                            displayName = contactData[0];
                            if (contactData[1] != null)
                                photoUri = Uri.parse(contactData[1]);
                        }
                    } else
                        address = null;
                    date = cursor.getString(cursor.getColumnIndex(columns[2]));
                    msg = cursor.getString(cursor.getColumnIndex(columns[3]));
                    smsMsg.setDisplayName(displayName);
                    smsMsg.setThreadId(threadId);
                    smsMsg.setAddress(address);
                    smsMsg.setPhotoUri(photoUri);
                    smsMsg.setDate(date);
                    smsMsg.setMsg(msg);
                    smsMsg.setType(type);
                    // Log.e("SMS-inbox", "nnNAME: " + displayName
                    // + "nTHREAD_ID: " + threadId + "nNUMBER: "
                    // + address + "nPHOTO_URI: " + photoUri + "nTIME: "
                    // + date + "nMESSAGE: " + msg + "nTYPE: " + type);
                    smsMsgs.add(smsMsg);
                    // Add threadId to Tree
                    threadIds.add(Integer.parseInt(threadId));
                }
            }
            for (int threadId : threadIds) {
                HashMap<Contact, ArrayList<OneComment>> oneChat = new HashMap<Contact, ArrayList<OneComment>>();
                Contact con = new Contact();
                ArrayList<OneComment> oneDisc = new ArrayList<OneComment>();
                for (SmsMsg smsMsg : smsMsgs) {
                    if (Integer.parseInt(smsMsg.getThreadId()) == threadId) {
                        con.setContactName(smsMsg.getDisplayName());
                        con.setContactNumber(smsMsg.getAddress());
                        con.setContactPhotoUri(smsMsg.getPhotoUri());
                        if (Integer.parseInt(smsMsg.getType()) == 1)
                            oneDisc.add(0, new OneComment(true,
                                    smsMsg.getMsg(), smsMsg.getDisplayName(),
                                    smsMsg.getDate(), false));
                        else if (Integer.parseInt(smsMsg.getType()) == 2)
                            oneDisc.add(0,
                                    new OneComment(false, smsMsg.getMsg(),
                                            "Me", smsMsg.getDate(), false));
                    }
                }
                oneChat.put(con, oneDisc);
                // add at pos 0
                recentChats.add(0, oneChat);
            }
        }
        return recentChats;
    }
    public String[] getContactByNumber(final String number) {
        String[] data = new String[2];
        try {
            Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI,
                    Uri.encode(number));
            Cursor cur = _context.getContentResolver().query(uri,
                    new String[] { PhoneLookup.DISPLAY_NAME, PhoneLookup._ID },
                    null, null, null);
            if (cur.moveToFirst()) {
                int nameIdx = cur.getColumnIndex(PhoneLookup.DISPLAY_NAME);
                data[0] = cur.getString(nameIdx);
                String contactId = cur.getString(cur
                        .getColumnIndex(PhoneLookup._ID));
                Uri photoUri = getContactPhotoUri(Long.parseLong(contactId));
                if (photoUri != null)
                    data[1] = photoUri.toString();
                else
                    data[1] = null;
                cur.close();
                return data;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    public Uri getContactPhotoUri(long contactId) {
        Uri photoUri = ContentUris.withAppendedId(Contacts.CONTENT_URI,
                contactId);
        photoUri = Uri.withAppendedPath(photoUri,
                Contacts.Photo.CONTENT_DIRECTORY);
        return photoUri;
    }
}

短信.java POJO:

public class SmsMsg {
    private String address = null;
    private String displayName = null;
    private String threadId = null;
    private String date = null;
    private String msg = null;
    private String type = null;
    Uri photoUri = null;
    public Uri getPhotoUri() {
        return photoUri;
    }
    public void setPhotoUri(Uri photoUri) {
        this.photoUri = photoUri;
    }
    public String getDisplayName() {
        return displayName;
    }
    public void setDisplayName(String displayName) {
        this.displayName = displayName;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    public String getThreadId() {
        return threadId;
    }
    public void setThreadId(String threadId) {
        this.threadId = threadId;
    }
    public String getDate() {
        return date;
    }
    public void setDate(String date) {
        this.date = date;
    }
    public String getMsg() {
        return msg;
    }
    public void setMsg(String msg) {
        this.msg = msg;
    }
    public String getType() {
        return type;
    }
    public void setType(String type) {
        this.type = type;
    }
}

POJO 存储不是一个很好的方法,因为这些存储需要一直保留在内存中,否则重新加载会导致痛苦和缓慢。

在这种情况下,您应该创建一个更新 sqlite 数据库的服务,并将其呈现为 ContentProvider。 sqlite 数据库应仅包含 Android 未提供的结构,即您的联系人/线程层次结构,以及您可能在列表中显示的任何数据,例如最新消息的文本。

此线程讨论了如何检测新的 SMS 消息到达/发送,无论是来自你的应用还是其他应用,这可能是你真正想要的,而不是简单地检测用户从你自己的应用发布了一条消息。 服务应执行此任务,UI 活动只需要观察内容提供程序。

旁白:我想知道用户将如何向他们尚未发送消息的联系人发送消息,因为您的列表仅包含他们向其发送消息的联系人。

您可能需要提供更多细节,说明您实际上如何接近该方向,特别是您进行了多少活动(似乎有两个)。

假设其中有两个,在"第一个活动"中,不要尝试捕获每条消息,只是获取所有thread_Ids和地址。

然后,当用户单击任何列表项时,执行其他线程以读取属于该线程的所有消息。

使用以下内容:

Uri uriSMSURI = Uri.parse("content://sms/inbox");
Cursor cur = getContentResolver().query(uriSMSURI, null, null, null, null);

用于读取收件箱并获取thread_Ids和地址,并将它们存储到一些Java模式类中,即DTO

并填充列表,当用户单击任何项目时,传递thread_id然后像这样查询以获取所有对话,即线程。

Uri uriSMSURI = Uri.parse(Uri.parse("content://sms/conversations/")+ thread_id);
cursor = getContentResolver().query(uriSMSURI, null,"thread_id=?", new String[] { tid }, null);

相关内容

最新更新