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

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

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

这是我的代码:

ReadSMS.java:

public class ReadSMS { ArrayList<HashMap<Contact, ArrayList>> recentChats; Application _context; public ReadSMS(Application context) { this._context = context; this.recentChats = ((ChatApplication) _context).getChats(); } public ArrayList<HashMap<Contact, ArrayList>> getSMS() { // Init ArrayList smsMsgs = new ArrayList(); TreeSet threadIds = new TreeSet(); 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> oneChat = new HashMap<Contact, ArrayList>(); Contact con = new Contact(); ArrayList oneDisc = new ArrayList(); 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; } } 

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

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

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

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

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

假设有两个,在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);