Play商店中有许多应用程序,这些应用程序在每个用户的末尾都显示联系人(在征得用户许可后)和公司徽标,这表示用户是否在该应用程序上。 此流程有助于邀请一组用户。 当我实现上述所有功能时,事情变得非常复杂,假设底部导航器有一个专门的操作 Contacts ,当我从已知方法(Content Resolver查询)中获取联系人时,首先它太慢了,因此我将联系人添加到sqlite数据库,但仍然很慢。 如何有效地提取联系人?。像 OYO ROOMS APP 一样,它具有专门的Bottom Nav Action Invite&earn ,该功能正是我想要的。如果有人知道如何有效地做到这一点,请告诉我。
private void fetchContactsFromSystem() {
ContentResolver cr = getContext().getContentResolver();
Cursor cursor = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, PROJECTION, null, null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC");
if (cursor != null) {
try {
final int nameIndex = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
final int numberIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
String name, number;
while (cursor.moveToNext()) {
name = cursor.getString(nameIndex);
number = cursor.getString(numberIndex);
number = number.replaceAll(" ", "");
if (!phoneNumberSet.contains(number.trim())) {
sqliteDatabaseHelper.insertData(name.trim(), number.trim());
Contact contact = new Contact();
contact.setName(name);
contact.setPhone(number);
contact.setInvited(false);
contactList.add(contact);
phoneNumberSet.add(number);
}
}
} finally {
cursor.close();
}
}
}
投影字符串数组
private static final String[] PROJECTION = new String[]{
ContactsContract.CommonDataKinds.Phone.CONTACT_ID,
ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.NUMBER
};
从sqlite获取数据
private void setUpFromSqliteDatabase(Cursor cr) {
String name, number;
boolean isInvite;
while (cr.moveToNext()) {
name = cr.getString(0);
number = cr.getString(1);
isInvite = cr.getInt(2) == 1;
Contact contact = new Contact();
contact.setName(name);
contact.setPhone(number);
contact.setInvited(isInvite);
contactList.add(contact);
}
cr.close();
}
SQLite助手类
public class SqliteDatabaseHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "contacts.db";
private static final String TABLE_NAME = "contacts";
public static final String NAME = "NAME";
public static final String PHONE_NUMBER = "PHONE_NUMBER";
public static final String IS_INVITED = "IS_INVITED";
public SqliteDatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, 1);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table " + TABLE_NAME +" (NAME TEXT, PHONE_NUMBER TEXT PRIMARY KEY, IS_INVITED INTEGER DEFAULT 0)");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS "+TABLE_NAME);
onCreate(db);
}
public boolean insertData(String name,String phone) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(NAME,name);
contentValues.put(PHONE_NUMBER,phone);
long result = db.insert(TABLE_NAME,null ,contentValues);
db.close();
return result != -1;
}
public void updateInvitedData(String phoneNumber) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put(IS_INVITED, 1);
db.update(TABLE_NAME, cv, "PHONE_NUMBER = ?",new String[] {phoneNumber});
db.close();
}
public Cursor getAllData() {
SQLiteDatabase db = this.getWritableDatabase();
return db.rawQuery("select * from "+TABLE_NAME,null);
}
}
答案 0 :(得分:0)
有几个小区域可以提高效率,主要的购买要分批处理插件。这是一个示例,说明如何修改现有代码以实现此目的。
private void fetchContactsFromSystem() {
final ContentResolver cr = getContext().getContentResolver();
final String sort = String.format("%s ASC", Phone.DISPLAY_NAME);
try(Cursor cursor = cr.query(Phone.CONTENT_URI, PROJECTION, null, null, sort)) {
if(cursor == null || !cursor.moveToFirst()) return;
final List<Contact> insert = new LinkedList<>();
final int nameIndex = cursor.getColumnIndex(Contacts.DISPLAY_NAME);
final int numberIndex = cursor.getColumnIndex(Phone.NUMBER);
do {
final String name = cursor.getString(nameIndex);
final String number = cursor.getString(numberIndex).replaceAll("\\s+","");
//"true" if number doesn't already exist in the Set
if(phoneNumberSet.add(number)) {
//Can make this immutable and pass info in constructor
final Contact contact = new Contact(name, number, false);
contactList.add(contact);
insert.add(contact);
}
} while(cursor.moveToNext());
//Conduct bulk insert of "insert" list here
bulkInsert(insert);
}
}
private void bulkInsert(List<Contact> contacts) {
final SQLiteDatabase db = sqliteDatabaseHelper.getWritableDatabase();
db.beginTransaction();
try {
for (Contact contact : contacts) {
final ContentValues cv = new ContentValues(2);
cv.put(NAME_ID, contact.name());
cv.put(NUMBER_ID, contact.number());
db.insert(TABLE_CONTACTS, null, values);
}
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
}
答案 1 :(得分:0)
如果预期的结果是一组电话,则不需要按DISPLAY_NAME
进行排序,那么SQLite中的排序通常是一项昂贵的功能。
此外,我不会将结果存储在本地SQLite中,当尝试保持本地副本和更新的Contacts DB同步时(例如,当用户添加或删除联系人时),它将导致您出现问题。