Android联系人光标需要太多时间来迭代

Posted

技术标签:

【中文标题】Android联系人光标需要太多时间来迭代【英文标题】:Android Contact cursor take too much time to iterate 【发布时间】:2013-03-18 23:48:43 【问题描述】:

我想从电话联系人应用程序中获取所有联系人并插入到本地 sqlite 数据库中。 但问题是android接触光标需要时间来迭代......

代码:

private Cursor getContacts() 
        // Run query
        Uri uri = ContactsContract.Contacts.CONTENT_URI;
        String[] projection = new String[]  ContactsContract.Contacts._ID,
                ContactsContract.Contacts.DISPLAY_NAME ;
        String selection = ContactsContract.Contacts.IN_VISIBLE_GROUP + " = '"
                + ("1") + "'";
        String[] selectionArgs = null;
        String sortOrder = ContactsContract.Contacts.DISPLAY_NAME
                + " COLLATE LOCALIZED ASC";
        return managedQuery(uri, projection, selection, selectionArgs,
                sortOrder);
    

插入数据库:

long mStartTime = System.currentTimeMillis();

        int batch = 50;

        try 

            SQLiteDatabase db = this.getWritableDatabase();

            // InsertHelper insertHelper = new InsertHelper(db,
            // TABLE_USER_INFO);
            // String insertSql =
            // "INSERT INTO UserInfo (firstname,lastname,userid,serveruserid,phonenumber,emailaddress,street,state,city,country) VALUES (?,?,?,?,?,?,?,?,?,?) ";
            // SQLiteStatement sqLiteStatement = db.compileStatement(insertSql);

            if (cursor != null) 
                if (cursor.moveToFirst()) 

                    for (int i = 0; i < cursor.getCount() / batch
                            + (((cursor.getCount() % batch) > 0) ? 1 : 0); i++) 
                        mStartTime = System.currentTimeMillis();
                        StringBuilder sqlBuilder = new StringBuilder();
                        db.beginTransaction();

                        sqlBuilder
                                .append("INSERT INTO UserInfo (firstname,lastname,userid,serveruserid,phonenumber,emailaddress,street,state,city,country) ");

                        for (int j = 0; j < batch; j++) 

                            String name = cursor
                                    .getString(cursor
                                            .getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
                            long _id = cursor
                                    .getLong(cursor
                                            .getColumnIndex(ContactsContract.Contacts._ID));

                            // ADDRESS
                            Cursor address = context
                                    .getContentResolver()
                                    .query(ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_URI,
                                            null,
                                            ContactsContract.CommonDataKinds.StructuredPostal.CONTACT_ID
                                                    + " = " + _id, null, null);
                            String street = null, city = null, state = null, country = null;
                            while (address.moveToNext()) 
                                street = address
                                        .getString(address
                                                .getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.STREET));
                                city = address
                                        .getString(address
                                                .getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.CITY));
                                state = address
                                        .getString(address
                                                .getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.REGION));
                                country = address
                                        .getString(address
                                                .getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.COUNTRY));

                             // address.moveToNext()
                            address.close();

                            // PHONE NO
                            String phoneNumber = null;
                            Cursor phones = context
                                    .getContentResolver()
                                    .query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                                            null,
                                            ContactsContract.CommonDataKinds.Phone.CONTACT_ID
                                                    + " = " + _id, null, null);
                            while (phones.moveToNext()) 
                                phoneNumber = phones
                                        .getString(phones
                                                .getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                            
                            phones.close();

                            // EMAIL ID
                            String emailId = null;
                            Cursor emails = context
                                    .getContentResolver()
                                    .query(ContactsContract.CommonDataKinds.Email.CONTENT_URI,
                                            null,
                                            ContactsContract.CommonDataKinds.Email.CONTACT_ID
                                                    + " = " + _id, null, null);
                            while (emails.moveToNext()) 
                                emailId = emails
                                        .getString(emails
                                                .getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));
                            
                            emails.close();

                            // INSERT INTO DB
                            ContentValues values = new ContentValues();

                            String[] names = name.split(" ");
                            if (name != null && names.length == 1) 
                                values.put(KEY_FIRST_NAME, name);
                                values.put(KEY_LAST_NAME, "");
                             else if (name != null && names.length > 1) 
                                values.put(KEY_FIRST_NAME, names[0]);
                                values.put(KEY_LAST_NAME, names[1]);
                            

                            // Log.d(TAG, "User Id:" + _id);

                            values.put(KEY_USER_LOCAL_ID, _id);
                            values.put(KEY_SERVER_USER_ID, "0");

                            if (phoneNumber != null
                                    && !phoneNumber.equalsIgnoreCase("0")) 
                                // REPLACE "-" FROM PHONE NO
                                phoneNumber = phoneNumber.replace("-", "")
                                        .trim();
                                values.put(KEY_PH_NO, IOUtils
                                        .getFormatedPhoneNo(context,
                                                phoneNumber));
                                Log.e(TAG, "Inserting contacts into db name:"
                                        + name + " Phone:" + phoneNumber);
                            

                            if (emailId != null)
                                values.put(KEY_EMIAL, emailId);

                            if (street != null)
                                values.put(KEY_STREET, street);
                            if (state != null)
                                values.put(KEY_STATE, state);
                            if (city != null)
                                values.put(KEY_CITY, city);
                            if (country != null)
                                values.put(KEY_COUNTRY, country);

                            if (emailId == null && phoneNumber == null) 
                                // Log.d(TAG, "email,ph no not found:" + name);
                             else 

                                Log.e(TAG, "*** Name:" + name + " Email id:"
                                        + emailId + " phone:" + phoneNumber);

                                if (j == 0)
                                    sqlBuilder.append(" SELECT ");
                                else
                                    sqlBuilder.append(" UNION SELECT ");

                                sqlBuilder
                                        .append("'"
                                                + values.getAsString(
                                                        KEY_FIRST_NAME)
                                                        .replace("'", "") + "'")
                                        .append(" AS " + KEY_FIRST_NAME + ", ");
                                sqlBuilder.append(
                                        "'"
                                                + values.getAsString(
                                                        KEY_LAST_NAME).replace(
                                                        "'", "") + "'").append(
                                        " AS " + KEY_LAST_NAME + ", ");
                                sqlBuilder
                                        .append("'"
                                                + values.getAsString(KEY_USER_LOCAL_ID)
                                                + "'")
                                        .append(" AS " + KEY_USER_LOCAL_ID
                                                + ", ")

                                        //
                                        .append("'")
                                        .append((values
                                                .getAsString(KEY_SERVER_USER_ID) != null) ? values
                                                .getAsString(KEY_SERVER_USER_ID)
                                                : " ")
                                        .append("'")
                                        .append(" AS " + KEY_SERVER_USER_ID
                                                + ", ")

                                        //
                                        .append("'")
                                        .append((values.getAsString(KEY_PH_NO) != null) ? values
                                                .getAsString(KEY_PH_NO) : "")
                                        .append("'")
                                        .append(" AS " + KEY_PH_NO + ", ")

                                        //
                                        .append("'")
                                        .append((values.getAsString(KEY_EMIAL) != null) ? values
                                                .getAsString(KEY_EMIAL) : "")
                                        .append("'")
                                        .append(" AS " + KEY_EMIAL + ", ")

                                        //
                                        .append("'")
                                        .append((values.getAsString(KEY_STREET) != null) ? values
                                                .getAsString(KEY_STREET) : "")
                                        .append("'")
                                        .append(" AS " + KEY_STREET + ", ")

                                        //
                                        .append("'")
                                        .append((values.getAsString(KEY_STATE) != null) ? values
                                                .getAsString(KEY_STATE) : "")
                                        .append("'")
                                        .append(" AS " + KEY_STATE + ", ")
                                        //
                                        .append("'")
                                        .append((values.getAsString(KEY_CITY) != null) ? values
                                                .getAsString(KEY_CITY) : "")
                                        .append("'")
                                        .append(" AS " + KEY_CITY + ", ")

                                        //
                                        .append("'")
                                        .append((values
                                                .getAsString(KEY_COUNTRY) != null) ? values
                                                .getAsString(KEY_COUNTRY) : "")
                                        .append("'")
                                        .append(" AS " + KEY_COUNTRY);
                            
                            if (!cursor.moveToNext()) 
                                Log.d(TAG, "Cursor pos" + cursor.getPosition());
                                break;

                            
                        

                        // Log.d(TAG, "BUILDER: " + sqlBuilder.toString());
                        db.execSQL(sqlBuilder.toString());
                        db.setTransactionSuccessful();
                        db.endTransaction();
                        Log.e("Time:",
                                "operatio time"
                                        + (mStartTime - System
                                                .currentTimeMillis()));
                    
                
            

            // CLOSE DB

            db.close();
         catch (Exception e) 
            e.printStackTrace();
         finally 
            // insertHelper.c
        

插入需要 4 分钟....

请建议迭代光标的有效方法。

提前致谢。

【问题讨论】:

向我们展示你现在的表现。 【参考方案1】:

使用managedQuery(...),您可以投射查询投影(以要提取的列数组的形式)并提取更大的数据。通过这样做,您可以缓解单独查询数据库的问题。这是这个过程中最大的要求。

此外,支持包 v4 中还有新的 CursorLoader 类,用于异步加载该数据。

此外,您可以使用moveToNext() 来迭代while 循环,因为游标总是在数据“之前”开始。

【讨论】:

以上是关于Android联系人光标需要太多时间来迭代的主要内容,如果未能解决你的问题,请参考以下文章

Android联系人查询 - 光标索引超出范围

如何从 Android 联系人中的联系人 ID 获取只读帐户名称

Android 光标错误 - 确保光标已正确初始化

带有光标适配器滚动问题的android列表视图

如何检测更新的android联系人并同步到firestore

无法从 Android 获取所有联系人