Question

I would like to read contacts from ContactsContract API which belongs only to Phone / SIM and would like to avoid contacts synced from other apps like facebook and gmail. I tested my code on simulator and it works fine but on real devices it doesn't returns any result.

ContentResolver cr = AndroidContext.getContext()
                    .getContentResolver();
Cursor nativeContacts = cr.query(RawContacts.CONTENT_URI,
                    new String[] { RawContacts._ID, RawContacts.VERSION, RawContacts.CONTACT_ID },
                    RawContacts.DELETED + "<> 1 AND " + RawContacts.CONTACT_ID
                            + " IS NOT NULL AND " + RawContacts.ACCOUNT_NAME + " IS NULL AND "
                            + RawContacts.ACCOUNT_TYPE + " IS NULL", null, null);

I guess on devices the account type and name for default account is not null, what is the solution?

Was it helpful?

Solution

I made the same experiences as you did and can only suggest two workarounds:

  1. Let the user make the decision. For example show him a list of all raw contacts and then let him choose which one is a phonebook contact vs. a sim contact.

  2. My experience with three different devices is that the AccountManager is not aware of the account used to store those phonecontacts. For example when you fetch an account array from the AccountManager as you did (AccountManager.getAccounts()) the "com.htc.android.pcsc" is not in the list! But you can use exactly that fact to your advantage: Exclude all known account types/names and the list you get should be the list of all phonebookcontacts/simcontacts.

Hopefully those ideas helped you :) I would like to read your thoughts about those workarounds, eventually I missed something or there is a even better workaround.

OTHER TIPS

I couldn't find the way to get the SIM account yet. But I'm using the code below to get the default account name and type.

public void getDefaultAccountNameAndType() {
    String accountType = "";
    String accountName = "";

    long rawContactId = 0;
    Uri rawContactUri = null;
    ContentProviderResult[] results = null;

    ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>(); 

    ops.add(ContentProviderOperation.newInsert(RawContacts.CONTENT_URI).withValue(RawContacts.ACCOUNT_NAME, null).withValue(RawContacts.ACCOUNT_TYPE, null).build());

    try {
        results = getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
    } catch(Exception e) {
        e.printStackTrace();
    } finally {
        ops.clear();
    }

    for (ContentProviderResult result : results) {
        rawContactUri = result.uri;
        rawContactId = ContentUris.parseId(rawContactUri);
    }

    Cursor c = getContentResolver().query(
            RawContacts.CONTENT_URI
            , new String[] {RawContacts.ACCOUNT_TYPE, RawContacts.ACCOUNT_NAME}
            , RawContacts._ID+"=?"
            , new String[] {String.valueOf(rawContactId)}
            , null);

    if(c.moveToFirst()) {
        if(!c.isAfterLast()) {
            accountType = c.getString(c.getColumnIndex(RawContacts.ACCOUNT_TYPE));
            accountName = c.getString(c.getColumnIndex(RawContacts.ACCOUNT_NAME));
        }
    }

    getContentResolver().delete(rawContactUri, null, null);

    c.close();
    c = null;

    preference.setString("contactAccountType", accountType);
    preference.setString("contactAccountName", accountName);
}

I solved this problem.

Account[] accountList = AccountManager.get(this).getAccounts();

String accountSelection = "";
for(int i = 0 ; i < accountList.length ; i++) {
  if(accountSelection.length() != 0)
    accountSelection = accountSelection + " AND ";
  accountSelection = accountSelection + ContactsContract.Groups.ACCOUNT_TYPE + " != '" +  accountList[i].type + "'";
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top