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

时间:2013-01-27 08:21:37

标签: android android-contentprovider android-contacts android-contentresolver

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

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

    ReadSMS.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", "\n\nNAME: " + 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;
    
        }
    
    }
    

    SmsMsg.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;
        }
    
    }
    

2 个答案:

答案 0 :(得分:8)

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

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

This thread讨论了如何检测新的SMS消息到达/发送,无论是来自您的应用还是其他,这可能是您真正想要的,而不是简单地检测到用户是否从您自己的应用发布了消息。服务应该执行此任务,UI活动只需要观察ContentProvider。

除此之外:我想知道用户如何向他们尚未发送消息的联系人发送消息,因为您的列表中只包含他们已向其发送消息的联系人。

答案 1 :(得分:4)

您可能需要提供更多详细信息,说明您实际上是如何接近这个方向的,特别是您有多少活动(似乎有两个)。

假设有两个,在First Activity中不要尝试捕获每条消息,只是获取所有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);