From 182888f824a45b47fca5ab2f410c800cb795de9a Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 13 Jul 2016 15:42:13 +0200 Subject: [PATCH] Added back the sync mechanism for contacts --- AndroidManifest.xml | 2 +- res/values/non_localizable_custom.xml | 2 +- src/org/linphone/ContactsManager.java | 3 +- src/org/linphone/LinphoneActivity.java | 35 ++-- src/org/linphone/LinphoneContact.java | 180 ++++++++++++++---- .../linphone/compatibility/ApiNinePlus.java | 88 --------- .../linphone/compatibility/Compatibility.java | 27 --- 7 files changed, 173 insertions(+), 164 deletions(-) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 67a847cb3..568325779 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -78,7 +78,7 @@ - + diff --git a/res/values/non_localizable_custom.xml b/res/values/non_localizable_custom.xml index 4266988c7..d938030fe 100644 --- a/res/values/non_localizable_custom.xml +++ b/res/values/non_localizable_custom.xml @@ -6,7 +6,7 @@ stun.linphone.org org.linphone - vnd.android.cursor.item/org.linphone.profile + vnd.android.cursor.item/org.linphone.profile false false diff --git a/src/org/linphone/ContactsManager.java b/src/org/linphone/ContactsManager.java index 78b7ef8b5..a0ebae3d3 100644 --- a/src/org/linphone/ContactsManager.java +++ b/src/org/linphone/ContactsManager.java @@ -174,7 +174,7 @@ public class ContactsManager extends ContentObserver { } public void initializeSyncAccount(Context context, ContentResolver contentResolver) { - initializeContactManager(context,contentResolver); + initializeContactManager(context, contentResolver); AccountManager accountManager = (AccountManager) context.getSystemService(Context.ACCOUNT_SERVICE); Account[] accounts = accountManager.getAccountsByType(context.getPackageName()); @@ -330,6 +330,7 @@ public class ContactsManager extends ContentObserver { Log.e(e); } } + public String getString(int resourceID) { return context.getString(resourceID); } diff --git a/src/org/linphone/LinphoneActivity.java b/src/org/linphone/LinphoneActivity.java index 990ccd3ff..834bb7186 100644 --- a/src/org/linphone/LinphoneActivity.java +++ b/src/org/linphone/LinphoneActivity.java @@ -103,13 +103,10 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta private static final int FIRST_LOGIN_ACTIVITY = 101; private static final int REMOTE_PROVISIONING_LOGIN_ACTIVITY = 102; private static final int CALL_ACTIVITY = 19; - private static final int PERMISSIONS_REQUEST_CONTACTS = 200; private static final int PERMISSIONS_REQUEST_RECORD_AUDIO = 201; private static final int PERMISSIONS_REQUEST_RECORD_AUDIO_INCOMING_CALL = 203; - private static final int PERMISSIONS_REQUEST_EXTERNAL_FILE_STORAGE_WRITE = 204; - private static final int PERMISSIONS_REQUEST_CAMERA = 205; private static final int PERMISSIONS_REQUEST_OVERLAY = 206; - private static final int PERMISSIONS_REQUEST_EXTERNAL_FILE_STORAGE_READ = 207; + private static final int PERMISSIONS_REQUEST_SYNC = 207; private static LinphoneActivity instance; @@ -174,9 +171,12 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta } } - //TODO rework - if (getResources().getBoolean(R.bool.use_linphone_tag) && getPackageManager().checkPermission(Manifest.permission.WRITE_SYNC_SETTINGS, getPackageName()) == PackageManager.PERMISSION_GRANTED) { - ContactsManager.getInstance().initializeSyncAccount(getApplicationContext(), getContentResolver()); + if (getResources().getBoolean(R.bool.use_linphone_tag)) { + if (getPackageManager().checkPermission(Manifest.permission.WRITE_SYNC_SETTINGS, getPackageName()) != PackageManager.PERMISSION_GRANTED) { + checkSyncPermission(); + } else { + ContactsManager.getInstance().initializeSyncAccount(getApplicationContext(), getContentResolver()); + } } else { ContactsManager.getInstance().initializeContactManager(getApplicationContext(), getContentResolver()); } @@ -1167,23 +1167,23 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta } public void checkAndRequestReadExternalStoragePermission() { - checkAndRequestPermission(Manifest.permission.READ_EXTERNAL_STORAGE, PERMISSIONS_REQUEST_EXTERNAL_FILE_STORAGE_READ); + checkAndRequestPermission(Manifest.permission.READ_EXTERNAL_STORAGE, 0); } public void checkAndRequestExternalStoragePermission() { - checkAndRequestPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE, PERMISSIONS_REQUEST_EXTERNAL_FILE_STORAGE_WRITE); + checkAndRequestPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE, 0); } public void checkAndRequestCameraPermission() { - checkAndRequestPermission(Manifest.permission.CAMERA, PERMISSIONS_REQUEST_CAMERA); + checkAndRequestPermission(Manifest.permission.CAMERA, 0); } public void checkAndRequestReadContactsPermission() { - checkAndRequestPermission(Manifest.permission.READ_CONTACTS, PERMISSIONS_REQUEST_CONTACTS); + checkAndRequestPermission(Manifest.permission.READ_CONTACTS, 0); } public void checkAndRequestWriteContactsPermission() { - checkAndRequestPermission(Manifest.permission.WRITE_CONTACTS, PERMISSIONS_REQUEST_CONTACTS); + checkAndRequestPermission(Manifest.permission.WRITE_CONTACTS, 0); } public void checkAndRequestCallPermissions(boolean isIncomingCall) { @@ -1217,6 +1217,10 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta ActivityCompat.requestPermissions(this, permissions, 0); } } + + private void checkSyncPermission() { + checkAndRequestPermission(Manifest.permission.WRITE_SYNC_SETTINGS, PERMISSIONS_REQUEST_SYNC); + } public void checkAndRequestPermission(String permission, int result) { if (getPackageManager().checkPermission(permission, getPackageName()) != PackageManager.PERMISSION_GRANTED) { @@ -1233,6 +1237,13 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta case PERMISSIONS_REQUEST_RECORD_AUDIO_INCOMING_CALL: startActivity(new Intent(this, CallIncomingActivity.class)); break; + case PERMISSIONS_REQUEST_SYNC: + if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { + ContactsManager.getInstance().initializeSyncAccount(getApplicationContext(), getContentResolver()); + } else { + ContactsManager.getInstance().initializeContactManager(getApplicationContext(), getContentResolver()); + } + break; } } diff --git a/src/org/linphone/LinphoneContact.java b/src/org/linphone/LinphoneContact.java index 600d87ac8..43453a62b 100644 --- a/src/org/linphone/LinphoneContact.java +++ b/src/org/linphone/LinphoneContact.java @@ -48,10 +48,11 @@ public class LinphoneContact implements Serializable, Comparable addresses; private transient ArrayList changesToCommit; + private transient ArrayList changesToCommit2; private boolean hasSipAddress; public LinphoneContact() { @@ -60,6 +61,7 @@ public class LinphoneContact implements Serializable, Comparable(); + changesToCommit2 = new ArrayList(); hasSipAddress = false; } @@ -138,10 +140,9 @@ public class LinphoneContact implements Serializable, Comparable 0) { + public void save() { + if (isAndroidContact() && ContactsManager.getInstance().hasContactsAccess() && changesToCommit.size() > 0) { try { ContactsManager.getInstance().getContentResolver().applyBatch(ContactsContract.AUTHORITY, changesToCommit); + createLinphoneTagIfNeeded(); } catch (Exception e) { Log.e(e); } finally { changesToCommit = new ArrayList(); + changesToCommit2 = new ArrayList(); } } + if (isLinphoneFriend()) { boolean hasAddr = false; LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull(); @@ -386,17 +432,22 @@ public class LinphoneContact implements Serializable, Comparable getAddressesAndNumbersForAndroidContact(String id) { + private List getAddressesAndNumbersForAndroidContact() { List result = new ArrayList(); ContentResolver resolver = ContactsManager.getInstance().getContentResolver(); String select = ContactsContract.Data.CONTACT_ID + " =? AND (" + ContactsContract.Data.MIMETYPE + "=? OR " + ContactsContract.Data.MIMETYPE + "=?)"; String[] projection = new String[] { ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS, ContactsContract.Data.MIMETYPE }; // PHONE_NUMBER == SIP_ADDRESS == "data1"... - Cursor c = resolver.query(ContactsContract.Data.CONTENT_URI, projection, select, new String[]{ id, ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE }, null); + Cursor c = resolver.query(ContactsContract.Data.CONTENT_URI, projection, select, new String[]{ getAndroidId(), ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE }, null); if (c != null) { while (c.moveToNext()) { String mime = c.getString(c.getColumnIndex(ContactsContract.Data.MIMETYPE)); @@ -551,12 +602,14 @@ public class LinphoneContact implements Serializable, Comparable 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, getFullName()) + .build()); + + batch.add(ContentProviderOperation.newUpdate(ContactsContract.AggregationExceptions.CONTENT_URI) + .withValue(ContactsContract.AggregationExceptions.TYPE, ContactsContract.AggregationExceptions.TYPE_KEEP_TOGETHER) + .withValue(ContactsContract.AggregationExceptions.RAW_CONTACT_ID1, androidRawId) + .withValueBackReference(ContactsContract.AggregationExceptions.RAW_CONTACT_ID2, 0) + .build()); + + if (changesToCommit2.size() > 0) { + for(ContentProviderOperation cpo : changesToCommit2) { + batch.add(cpo); + } + } + + try { + ContactsManager.getInstance().getContentResolver().applyBatch(ContactsContract.AUTHORITY, batch); + androidTagId = findLinphoneRawContactId(); + } catch (Exception e) { + Log.e(e); + } + } } diff --git a/src/org/linphone/compatibility/ApiNinePlus.java b/src/org/linphone/compatibility/ApiNinePlus.java index 70dd126cf..80c49202e 100644 --- a/src/org/linphone/compatibility/ApiNinePlus.java +++ b/src/org/linphone/compatibility/ApiNinePlus.java @@ -3,12 +3,9 @@ package org.linphone.compatibility; import java.util.ArrayList; import java.util.List; -import org.linphone.Contact; import org.linphone.LinphoneContact; -import org.linphone.LinphoneUtils; import org.linphone.R; import org.linphone.core.LinphoneAddress; -import org.linphone.mediastream.Log; import android.annotation.TargetApi; import android.content.ContentProviderOperation; @@ -195,89 +192,4 @@ public class ApiNinePlus { cursor.close(); return null; } - - //Linphone Contacts Tag - public static void addLinphoneContactTag(Context context, ArrayList ops, String newAddress, String rawContactId){ - if(rawContactId != null) { - ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) - .withValue(ContactsContract.Data.RAW_CONTACT_ID, rawContactId) - .withValue(ContactsContract.Data.MIMETYPE, context.getString(R.string.sync_mimetype)) - .withValue(ContactsContract.Data.DATA1, newAddress) - .withValue(ContactsContract.Data.DATA2, context.getString(R.string.app_name)) - .withValue(ContactsContract.Data.DATA3, newAddress) - .build() - ); - } - } - public static void updateLinphoneContactTag(Context context, ArrayList ops, String newAddress, String oldAddress, String rawContactId){ - if(rawContactId != null) { - ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI) - .withSelection(ContactsContract.Data.RAW_CONTACT_ID + "=? AND " + ContactsContract.Data.DATA1 + "=? ", new String[]{rawContactId, oldAddress}) - .withValue(ContactsContract.Data.DATA1, newAddress) - .withValue(ContactsContract.Data.DATA2, context.getString(R.string.app_name)) - .withValue(ContactsContract.Data.DATA3, newAddress) - .build()); - } - } - - public static void deleteLinphoneContactTag(ArrayList ops , String oldAddress, String rawContactId){ - if(rawContactId != null) { - String select = ContactsContract.Data.RAW_CONTACT_ID + "=? AND " - + ContactsContract.Data.DATA1 + "= ?"; - String[] args = new String[]{rawContactId, oldAddress}; - - ops.add(ContentProviderOperation.newDelete(ContactsContract.Data.CONTENT_URI) - .withSelection(select, args) - .build()); - } - } - - public static void createLinphoneContactTag(Context context, ContentResolver contentResolver, Contact contact, String rawContactId){ - ArrayList ops = new ArrayList(); - - if (contact != null) { - ops.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI) - .withValue(ContactsContract.RawContacts.AGGREGATION_MODE, ContactsContract.RawContacts.AGGREGATION_MODE_DEFAULT) - .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, context.getString(R.string.sync_account_type)) - .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, context.getString(R.string.sync_account_name)) - .build() - ); - - ops.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, contact.getName()) - .build() - ); - - List numbersOrAddresses = contact.getNumbersOrAddresses(); - for (String numberOrAddress : numbersOrAddresses) { - if (LinphoneUtils.isSipAddress(numberOrAddress)) { - if (numberOrAddress.startsWith("sip:")){ - numberOrAddress = numberOrAddress.substring(4); - } - - ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) - .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) - .withValue(ContactsContract.Data.MIMETYPE, context.getString(R.string.sync_mimetype)) - .withValue(ContactsContract.Data.DATA1, numberOrAddress) - .withValue(ContactsContract.Data.DATA2, context.getString(R.string.app_name)) - .withValue(ContactsContract.Data.DATA3, numberOrAddress) - .build() - ); - } - } - - ops.add(ContentProviderOperation.newUpdate(ContactsContract.AggregationExceptions.CONTENT_URI) - .withValue(ContactsContract.AggregationExceptions.TYPE, ContactsContract.AggregationExceptions.TYPE_KEEP_TOGETHER) - .withValue(ContactsContract.AggregationExceptions.RAW_CONTACT_ID1, rawContactId) - .withValueBackReference(ContactsContract.AggregationExceptions.RAW_CONTACT_ID2, 0).build()); - - try { - contentResolver.applyBatch(ContactsContract.AUTHORITY, ops); - } catch (Exception e) { - Log.e(e); - } - } - } } diff --git a/src/org/linphone/compatibility/Compatibility.java b/src/org/linphone/compatibility/Compatibility.java index 5857ba776..9a6f1ec5a 100644 --- a/src/org/linphone/compatibility/Compatibility.java +++ b/src/org/linphone/compatibility/Compatibility.java @@ -21,7 +21,6 @@ import java.io.InputStream; import java.util.ArrayList; import java.util.List; -import org.linphone.Contact; import org.linphone.LinphoneContact; import org.linphone.core.LinphoneAddress; import org.linphone.mediastream.Version; @@ -301,32 +300,6 @@ public class Compatibility { ApiFivePlus.deleteSipAddressFromContact(ops, oldSipAddress, contactID); } - //Linphone Contacts Tag - public static void addLinphoneContactTag(Context context, ArrayList ops, String newSipAddress, String rawContactId) { - if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) { - ApiNinePlus.addLinphoneContactTag(context, ops, newSipAddress, rawContactId); - } - } - - public static void updateLinphoneContactTag(Context context, ArrayList ops, String newSipAddress, String oldSipAddress, String rawContactId) { - if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) { - ApiNinePlus.updateLinphoneContactTag(context, ops, newSipAddress, oldSipAddress, rawContactId); - } - } - - public static void deleteLinphoneContactTag(ArrayList ops, String oldSipAddress, String rawContactId) { - if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) { - ApiNinePlus.deleteLinphoneContactTag(ops, oldSipAddress, rawContactId); - } - } - - public static void createLinphoneContactTag(Context context, ContentResolver contentResolver, Contact contact, String rawContactId) { - if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) { - ApiNinePlus.createLinphoneContactTag(context, contentResolver, contact, rawContactId); - } - } - //End of Linphone Contact Tag - public static void removeGlobalLayoutListener(ViewTreeObserver viewTreeObserver, OnGlobalLayoutListener keyboardListener) { if (Version.sdkAboveOrEqual(Version.API16_JELLY_BEAN_41)) { ApiSixteenPlus.removeGlobalLayoutListener(viewTreeObserver, keyboardListener);