Подтвердить что ты не робот

Android получает sms из Inbox, оптимизированный способ читать все сообщения и группировать их

Привет, я внедряю приложение SMS, теперь могу получить все сообщения с их соответствующей контактной информацией, такими как отображаемое имя, фото uri.. и отображать их в специальном списке, где по щелчку элемента вы попадаете в соответствующее обсуждение. Здесь мои проблемы - время, необходимое для синхронизации всех этих сообщений,

  • Мне нужно оптимизировать это время.
  • Каждый раз, когда я отправляю новое сообщение в виде обсуждения и возвращаюсь к недавним чатам, мне нужно только обновлять конкретный элемент, а не весь список.

Здесь мой код:

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

}
4b9b3361

Ответ 1

POJO-хранилище не является отличным подходом, поскольку они должны постоянно оставаться в памяти или перезагружаться, вызывая боль и медлительность.

В этом случае вам необходимо создать службу, которая обновляет базу данных sqlite, и представить ее как ContentProvider. Sqlite db должен содержать только структуру, которая не предоставляется Android, т.е. Иерархия контактов/потоков, и любые данные, которые вы можете отображать в своем списке, например текст самого последнего сообщения.

В этом разделе обсуждается, как обнаружить новые приёмы и отправки SMS-сообщений, будь то из вашего приложения или другого, что, вероятно, вы действительно хотите, а не просто обнаружив, что пользователь отправил сообщение из вашего собственного приложения. Служба должна выполнить эту задачу, для работы с пользовательским интерфейсом необходимо только наблюдать ContentProvider.

Кроме того: интересно, как пользователь отправит сообщение контакту, которому еще не отправил сообщение, поскольку ваш список содержит только те контакты, на которые они отправили сообщения.

Ответ 2

Вам может потребоваться более подробное описание того, как вы на самом деле приближаетесь к направлению, в частности, сколько действий у вас есть (кажется, их два).

Предполагая, что есть два из них, в First Activity не пытайтесь поймать каждое сообщение, просто получите все thread_Ids и адреса.

Затем, когда пользователь нажимает на любой из элементов списка, выполняйте другой поток, чтобы прочитать все сообщения, принадлежащие этому потоку.

используйте следующее:

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

для чтения inbox и получения thread_Ids и адреса и сохранения их в некоторый java-модальный класс, т.е. DTO

и заполнить список, и по мере того, как пользователь нажимает на какой-либо элемент, передайте thread_id, а затем запросите, как это, чтобы получить весь разговор i.e. thread.

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