title: Android get sms from inbox, optimized way to read all messages and group them
body: <p>Hi am implementing a SMS App, now am able to retrieve all messages with their respective contact info like display name, photo uri.. and am displaying them in a custom list where on item click takes you to respective discussion. Here my issues is the time taking to sync all these messages, </p>
  
  <ol>
  <li>I need to optimize this time. </li>
  <li>Each time i send a new message in the discussion view and go back to recent chats i need to only update the particular item, not the whole list.</li>
  </ol>
  
  <p>Here's my code:</p>
  
  <p>ReadSMS.java:</p>
  
  <pre><code>public class ReadSMS {
  
      ArrayList&lt;HashMap&lt;Contact, ArrayList&lt;OneComment&gt;&gt;&gt; recentChats;
  
      Application _context;
  
      public ReadSMS(Application context) {
          this._context = context;
          this.recentChats = ((ChatApplication) _context).getChats();
      }
  
      public ArrayList&lt;HashMap&lt;Contact, ArrayList&lt;OneComment&gt;&gt;&gt; getSMS() {
  
          // Init
          ArrayList&lt;SmsMsg&gt; smsMsgs = new ArrayList&lt;SmsMsg&gt;();
          TreeSet&lt;Integer&gt; threadIds = new TreeSet&lt;Integer&gt;();
  
          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() &gt; 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() &gt; 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&lt;Contact, ArrayList&lt;OneComment&gt;&gt; oneChat = new HashMap&lt;Contact, ArrayList&lt;OneComment&gt;&gt;();
                  Contact con = new Contact();
                  ArrayList&lt;OneComment&gt; oneDisc = new ArrayList&lt;OneComment&gt;();
  
                  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;
  
      }
  
  }
  </code></pre>
  
  <p>SmsMsg.java POJO:</p>
  
  <pre><code>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;
      }
  
  }
  </code></pre>