diff --git a/app/src/main/java/org/linphone/contacts/AndroidContact.java b/app/src/main/java/org/linphone/contacts/AndroidContact.java index c0c6e7cd9..55f11ffd2 100644 --- a/app/src/main/java/org/linphone/contacts/AndroidContact.java +++ b/app/src/main/java/org/linphone/contacts/AndroidContact.java @@ -42,13 +42,13 @@ import org.linphone.mediastream.Log; class AndroidContact implements Serializable { protected String mAndroidId, mAndroidRawId, mAndroidLookupKey; - protected boolean isAndroidIdLinphone; + protected boolean isAndroidRawIdLinphone; private transient ArrayList mChangesToCommit; protected AndroidContact() { mChangesToCommit = new ArrayList<>(); - isAndroidIdLinphone = false; + isAndroidRawIdLinphone = false; } protected String getAndroidId() { @@ -88,20 +88,33 @@ class AndroidContact implements Serializable { ContentProviderResult[] results = contentResolver.applyBatch(ContactsContract.AUTHORITY, mChangesToCommit); if (results != null && results.length > 0 && results[0] != null) { - mAndroidRawId = String.valueOf(ContentUris.parseId(results[0].uri)); - Log.i("[Contact] Contact created with RAW ID " + mAndroidRawId); + String rawId = String.valueOf(ContentUris.parseId(results[0].uri)); + if (mAndroidId == null) { + Log.i("[Contact] Contact created with RAW ID " + rawId); - final String[] projection = - new String[] {ContactsContract.RawContacts.CONTACT_ID}; - final Cursor cursor = - contentResolver.query(results[0].uri, projection, null, null, null); - if (cursor != null) { - cursor.moveToNext(); - long contactId = cursor.getLong(0); - mAndroidId = String.valueOf(contactId); - cursor.close(); - Log.i("[Contact] Contact created with ID " + mAndroidId); + final String[] projection = + new String[] {ContactsContract.RawContacts.CONTACT_ID}; + final Cursor cursor = + contentResolver.query(results[0].uri, projection, null, null, null); + if (cursor != null) { + cursor.moveToNext(); + long contactId = cursor.getLong(0); + mAndroidId = String.valueOf(contactId); + cursor.close(); + Log.i("[Contact] Contact created with ID " + mAndroidId); + } + } else { + if (rawId.equals(mAndroidRawId)) { + Log.i("[Contact] Contact with RAW ID " + rawId + " updated"); + } else { + Log.i( + "[Contact] Linphone RAW ID " + + rawId + + " created from existing RAW ID " + + mAndroidRawId); + } } + mAndroidRawId = rawId; } } catch (Exception e) { Log.e("[Contact] Exception while saving changes: " + e); @@ -131,7 +144,17 @@ class AndroidContact implements Serializable { RawContacts.AGGREGATION_MODE, RawContacts.AGGREGATION_MODE_DEFAULT) .build()); - isAndroidIdLinphone = true; + isAndroidRawIdLinphone = true; + } else { + Log.i("[Contact] Creating contact using default account type"); + addChangesToCommit( + ContentProviderOperation.newInsert(RawContacts.CONTENT_URI) + .withValue(RawContacts.ACCOUNT_TYPE, null) + .withValue(RawContacts.ACCOUNT_NAME, null) + .withValue( + RawContacts.AGGREGATION_MODE, + RawContacts.AGGREGATION_MODE_DEFAULT) + .build()); } } @@ -449,14 +472,66 @@ class AndroidContact implements Serializable { .getContext() .getResources() .getBoolean(R.bool.use_linphone_tag)) { - // TODO - /*if (mLinphoneAndroidContactId == null && findLinphoneRawContactId() == null) { - createRawLinphoneContactFromExistingAndroidContact(fullName); - isAndroidIdLinphone = true; - }*/ + if (mAndroidId != null && (mAndroidRawId == null || !isAndroidRawIdLinphone)) { + String linphoneRawId = findLinphoneRawContactId(); + if (linphoneRawId == null) { + Log.i("[Contact] Linphone RAW ID not found for contact " + mAndroidId); + createRawLinphoneContactFromExistingAndroidContact(fullName); + } else { + Log.i( + "[Contact] Linphone RAW ID found for contact " + + mAndroidId + + " : " + + linphoneRawId); + mAndroidRawId = linphoneRawId; + } + isAndroidRawIdLinphone = true; + } } } + private void createRawLinphoneContactFromExistingAndroidContact(String fullName) { + addChangesToCommit( + ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI) + .withValue( + ContactsContract.RawContacts.ACCOUNT_TYPE, + ContactsManager.getInstance().getString(R.string.sync_account_type)) + .withValue( + ContactsContract.RawContacts.ACCOUNT_NAME, + ContactsManager.getInstance().getString(R.string.sync_account_name)) + .withValue( + ContactsContract.RawContacts.AGGREGATION_MODE, + ContactsContract.RawContacts.AGGREGATION_MODE_DEFAULT) + .build()); + + addChangesToCommit( + ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) + .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) + .withValue( + ContactsContract.Data.MIMETYPE, + ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE) + .withValue( + ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, + fullName) + .build()); + + addChangesToCommit( + ContentProviderOperation.newUpdate( + ContactsContract.AggregationExceptions.CONTENT_URI) + .withValue( + ContactsContract.AggregationExceptions.TYPE, + ContactsContract.AggregationExceptions.TYPE_KEEP_TOGETHER) + .withValue( + ContactsContract.AggregationExceptions.RAW_CONTACT_ID1, + mAndroidRawId) + .withValueBackReference( + ContactsContract.AggregationExceptions.RAW_CONTACT_ID2, 0) + .build()); + + Log.i("[Contact] Creating linphone contact"); + saveChangesCommited(); + } + private String findLinphoneRawContactId() { ContentResolver resolver = LinphoneService.instance().getContentResolver(); String result = null; @@ -485,54 +560,4 @@ class AndroidContact implements Serializable { } return result; } - - /*private void createRawLinphoneContactFromExistingAndroidContact(String fullName) { - ArrayList batch = new ArrayList<>(); - - batch.add( - ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI) - .withValue( - ContactsContract.RawContacts.ACCOUNT_TYPE, - ContactsManager.getInstance().getString(R.string.sync_account_type)) - .withValue( - ContactsContract.RawContacts.ACCOUNT_NAME, - ContactsManager.getInstance().getString(R.string.sync_account_name)) - .withValue( - ContactsContract.RawContacts.AGGREGATION_MODE, - ContactsContract.RawContacts.AGGREGATION_MODE_DEFAULT) - .build()); - - batch.add( - ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) - .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) - .withValue( - ContactsContract.Data.MIMETYPE, - ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE) - .withValue( - ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, - fullName) - .build()); - - batch.add( - ContentProviderOperation.newUpdate( - ContactsContract.AggregationExceptions.CONTENT_URI) - .withValue( - ContactsContract.AggregationExceptions.TYPE, - ContactsContract.AggregationExceptions.TYPE_KEEP_TOGETHER) - .withValue( - ContactsContract.AggregationExceptions.RAW_CONTACT_ID1, - mAndroidRawId) - .withValueBackReference( - ContactsContract.AggregationExceptions.RAW_CONTACT_ID2, 0) - .build()); - Log.i("[Contact] Creating linphone contact"); - - try { - LinphoneService.instance() - .getContentResolver() - .applyBatch(ContactsContract.AUTHORITY, batch); - } catch (Exception e) { - Log.e(e); - } - }*/ } diff --git a/app/src/main/java/org/linphone/contacts/ContactsManager.java b/app/src/main/java/org/linphone/contacts/ContactsManager.java index 8e6de76c8..c27818a69 100644 --- a/app/src/main/java/org/linphone/contacts/ContactsManager.java +++ b/app/src/main/java/org/linphone/contacts/ContactsManager.java @@ -24,8 +24,10 @@ import static android.os.AsyncTask.THREAD_POOL_EXECUTOR; import android.accounts.Account; import android.accounts.AccountManager; import android.app.Activity; +import android.content.ContentProviderClient; import android.content.ContentProviderOperation; import android.content.ContentResolver; +import android.content.ContentValues; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; @@ -34,6 +36,7 @@ import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.net.Uri; +import android.os.RemoteException; import android.provider.ContactsContract; import java.util.ArrayList; import java.util.Collections; @@ -262,6 +265,31 @@ public class ContactsManager extends ContentObserver implements FriendListListen } } + private void makeContactAccountVisible() { + ContentProviderClient client = + mContext.getContentResolver() + .acquireContentProviderClient(ContactsContract.AUTHORITY_URI); + ContentValues values = new ContentValues(); + values.put( + ContactsContract.Settings.ACCOUNT_NAME, + mContext.getString(R.string.sync_account_name)); + values.put( + ContactsContract.Settings.ACCOUNT_TYPE, + mContext.getString(R.string.sync_account_type)); + values.put(ContactsContract.Settings.UNGROUPED_VISIBLE, true); + try { + client.insert( + ContactsContract.Settings.CONTENT_URI + .buildUpon() + .appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "true") + .build(), + values); + Log.i("[Contacts Manager] Contacts account made visible"); + } catch (RemoteException e) { + Log.e("[Contacts Manager] Couldn't make contacts account visible: " + e); + } + } + public void initializeSyncAccount(Activity activity) { initializeContactManager(activity); AccountManager accountManager = @@ -277,10 +305,12 @@ public class ContactsManager extends ContentObserver implements FriendListListen mContext.getString(R.string.sync_account_type)); try { accountManager.addAccountExplicitly(newAccount, null, null); + Log.i("[Contacts Manager] Contact account added"); } catch (Exception e) { Log.e("[Contacts Manager] Couldn't initialize sync account: " + e); } } + makeContactAccountVisible(); } public synchronized LinphoneContact findContactFromAddress(Address address) { diff --git a/app/src/main/res/xml/syncadapter.xml b/app/src/main/res/xml/syncadapter.xml index 7a13cfb7c..e842c323c 100644 --- a/app/src/main/res/xml/syncadapter.xml +++ b/app/src/main/res/xml/syncadapter.xml @@ -1,7 +1,7 @@