From 35a2010488d4e2fea21dedb0f894802fd9cfce67 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 1 Jul 2019 15:05:18 +0200 Subject: [PATCH] Added a custom setting to allow fetching all device contacts + added debu logs --- .../org/linphone/contacts/AndroidContact.java | 75 +++++++------------ .../contacts/AsyncContactPresence.java | 25 ++++++- .../contacts/AsyncContactsLoader.java | 16 +++- .../org/linphone/contacts/ContactAddress.java | 2 +- .../contacts/ContactDetailsFragment.java | 2 +- .../contacts/ContactEditorFragment.java | 2 +- .../linphone/contacts/ContactViewHolder.java | 2 +- .../linphone/contacts/ContactsAdapter.java | 2 +- .../linphone/contacts/ContactsFragment.java | 2 +- .../linphone/contacts/ContactsManager.java | 9 ++- .../contacts/ContactsUpdatedListener.java | 2 +- .../linphone/contacts/LinphoneContact.java | 58 +++++++++++--- .../contacts/LinphoneNumberOrAddress.java | 6 +- .../contacts/SearchContactViewHolder.java | 2 +- .../contacts/SearchContactsAdapter.java | 2 +- .../res/values/non_localizable_custom.xml | 1 + 16 files changed, 133 insertions(+), 75 deletions(-) diff --git a/app/src/main/java/org/linphone/contacts/AndroidContact.java b/app/src/main/java/org/linphone/contacts/AndroidContact.java index 95e65e860..7540bf743 100644 --- a/app/src/main/java/org/linphone/contacts/AndroidContact.java +++ b/app/src/main/java/org/linphone/contacts/AndroidContact.java @@ -2,7 +2,7 @@ package org.linphone.contacts; /* AndroidContact.java -Copyright (C) 2018 Belledonne Communications, Grenoble, France +Copyright (C) 2018 Belledonne Communications, Grenoble, France This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -34,8 +34,6 @@ import java.io.Serializable; import java.util.ArrayList; import org.linphone.LinphoneService; import org.linphone.R; -import org.linphone.core.PresenceBasicStatus; -import org.linphone.core.PresenceModel; import org.linphone.core.tools.Log; class AndroidContact implements Serializable { @@ -210,54 +208,36 @@ class AndroidContact implements Serializable { } } - public void updateNativeContactWithPresenceInfo(LinphoneContact contact) { - // creation of the raw contact with the presence information (tablet) - createRawLinphoneContactFromExistingAndroidContactIfNeeded(); - for (LinphoneNumberOrAddress noa : contact.getNumbersOrAddresses()) { - String value = noa.getValue(); - if (value == null || value.isEmpty()) { - return; - } - - // Test presence of the value - PresenceModel pm = contact.getFriend().getPresenceModelForUriOrTel(value); - // If presence is not null - if (pm != null && pm.getBasicStatus().equals(PresenceBasicStatus.Open)) { - Boolean action = hasLinphoneAddressMimeType(); - // do the action on the contact only once if it has not been done - if (action) { - if (!noa.isSIPAddress()) { - addChangesToCommit( - ContentProviderOperation.newInsert(Data.CONTENT_URI) - .withValue( - ContactsContract.Data.RAW_CONTACT_ID, mAndroidRawId) - .withValue( - Data.MIMETYPE, - ContactsManager.getInstance() - .getString( - R.string - .linphone_address_mime_type)) - .withValue("data1", value) // phone number - .withValue( - "data2", - ContactsManager.getInstance() - .getString(R.string.app_name)) // Summary - .withValue("data3", value) // Detail - .build()); - saveChangesCommited(); - } - } - } + void updateNativeContactWithPresenceInfo(String value) { + if (!isLinphoneAddressMimeEntryAlreadyExisting(value)) { + Log.d("[Contact] Adding presence information " + value); + addChangesToCommit( + ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) + .withValue(ContactsContract.Data.RAW_CONTACT_ID, mAndroidRawId) + .withValue( + ContactsContract.Data.MIMETYPE, + ContactsManager.getInstance() + .getString(R.string.linphone_address_mime_type)) + .withValue("data1", value) // phone number + .withValue( + "data2", + ContactsManager.getInstance() + .getString(R.string.app_name)) // Summary + .withValue("data3", value) // Detail + .build()); } } - private Boolean hasLinphoneAddressMimeType() { - Boolean action = true; + private boolean isLinphoneAddressMimeEntryAlreadyExisting(String value) { + boolean result = false; ContentResolver resolver = LinphoneService.instance().getContentResolver(); String[] projection = {"data1", "data3"}; String selection = - ContactsContract.Data.RAW_CONTACT_ID + "= ? AND " + Data.MIMETYPE + "= ?"; + ContactsContract.Data.RAW_CONTACT_ID + + " = ? AND " + + Data.MIMETYPE + + " = ? AND data1 = ?"; Cursor c = resolver.query( @@ -267,16 +247,17 @@ class AndroidContact implements Serializable { new String[] { mAndroidRawId, ContactsManager.getInstance() - .getString(R.string.linphone_address_mime_type) + .getString(R.string.linphone_address_mime_type), + value }, null); if (c != null) { if (c.moveToFirst()) { - action = false; + result = true; } c.close(); } - return action; + return result; } void addNumberOrAddress(String value, String oldValueToReplace, boolean isSIP) { diff --git a/app/src/main/java/org/linphone/contacts/AsyncContactPresence.java b/app/src/main/java/org/linphone/contacts/AsyncContactPresence.java index 76e52dd22..9f4198dd2 100644 --- a/app/src/main/java/org/linphone/contacts/AsyncContactPresence.java +++ b/app/src/main/java/org/linphone/contacts/AsyncContactPresence.java @@ -1,13 +1,32 @@ package org.linphone.contacts; +/* +AsyncContactPresence.java +Copyright (C) 2019 Belledonne Communications, Grenoble, France + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + import android.os.AsyncTask; public class AsyncContactPresence extends AsyncTask { - private LinphoneContact linphoneContact; + private LinphoneContact mLinphoneContact; public AsyncContactPresence(LinphoneContact linphoneContact) { - this.linphoneContact = linphoneContact; + mLinphoneContact = linphoneContact; } @Override @@ -17,7 +36,7 @@ public class AsyncContactPresence extends AsyncTask @Override protected Void doInBackground(Void... voids) { - linphoneContact.updateNativeContactWithPresenceInfo(linphoneContact); + mLinphoneContact.updateNativeContactWithPresenceInfo(); return null; } } diff --git a/app/src/main/java/org/linphone/contacts/AsyncContactsLoader.java b/app/src/main/java/org/linphone/contacts/AsyncContactsLoader.java index f67aa6cd4..f47918bc0 100644 --- a/app/src/main/java/org/linphone/contacts/AsyncContactsLoader.java +++ b/app/src/main/java/org/linphone/contacts/AsyncContactsLoader.java @@ -2,7 +2,7 @@ package org.linphone.contacts; /* AsyncContactsLoader.java -Copyright (C) 2018 Belledonne Communications, Grenoble, France +Copyright (C) 2018 Belledonne Communications, Grenoble, France This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -78,12 +78,19 @@ class AsyncContactsLoader extends AsyncTask { @@ -208,16 +209,16 @@ public class LinphoneContact extends AndroidContact boolean found = false; // Check for duplicated phone numbers but with different formats for (LinphoneNumberOrAddress number : mAddresses) { - if ((!noa.isSIPAddress() - && !number.isSIPAddress() - && noa.getNormalizedPhone().equals(number.getNormalizedPhone())) - || (noa.isSIPAddress() - && !number.isSIPAddress() - && noa.getValue().equals(number.getNormalizedPhone())) - || (number.getValue().equals(noa.getNormalizedPhone()) - || !number.isSIPAddress())) { - found = true; - break; + if (!number.isSIPAddress()) { + if ((!noa.isSIPAddress() + && noa.getNormalizedPhone().equals(number.getNormalizedPhone())) + || (noa.isSIPAddress() + && noa.getValue().equals(number.getNormalizedPhone())) + || (noa.getNormalizedPhone().equals(number.getValue()))) { + Log.d("[Linphone Contact] Duplicated entry detected: " + noa); + found = true; + break; + } } } @@ -538,24 +539,57 @@ public class LinphoneContact extends AndroidContact String data4 = c.getString(c.getColumnIndex("data4")); if (getFullName() == null) { + Log.d("[Linphone Contact] Setting display name " + displayName); setFullName(displayName); } if (ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE.equals(mime)) { + Log.d("[Linphone Contact] Found phone number " + data1 + " (" + data4 + ")"); addNumberOrAddress(new LinphoneNumberOrAddress(data1, data4)); - } else if (ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE.equals(mime) || LinphoneService.instance() .getString(R.string.linphone_address_mime_type) .equals(mime)) { + Log.d("[Linphone Contact] Found SIP address " + data1); addNumberOrAddress(new LinphoneNumberOrAddress(data1, true)); } else if (ContactsContract.CommonDataKinds.Organization.CONTENT_ITEM_TYPE.equals(mime)) { + Log.d("[Linphone Contact] Found organization " + data1); setOrganization(data1, false); } else if (ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE.equals(mime)) { + Log.d("[Linphone Contact] Found first name " + data2 + " and last name " + data3); setFirstNameAndLastName(data2, data3, false); + } else { + Log.w("[Linphone Contact] Unexpected MIME type " + mime); } } + public void updateNativeContactWithPresenceInfo() { + Log.d("[Contact] Trying to update native contact with presence information"); + // Creation of the raw contact with the presence information (tablet) + createRawLinphoneContactFromExistingAndroidContactIfNeeded(); + + for (LinphoneNumberOrAddress noa : getNumbersOrAddresses()) { + if (noa.isSIPAddress()) { + // We are only interested in SIP addresses + continue; + } + String value = noa.getValue(); + if (value == null || value.isEmpty()) { + return; + } + + // Test presence of the value + PresenceModel pm = getFriend().getPresenceModelForUriOrTel(value); + // If presence is not null + if (pm != null && pm.getBasicStatus().equals(PresenceBasicStatus.Open)) { + Log.d("[Contact] Found presence information for phone number " + value); + // Do the action on the contact only once if it has not been done yet + updateNativeContactWithPresenceInfo(value); + } + } + saveChangesCommited(); + } + public void save() { saveChangesCommited(); syncValuesFromAndroidContact(LinphoneService.instance()); diff --git a/app/src/main/java/org/linphone/contacts/LinphoneNumberOrAddress.java b/app/src/main/java/org/linphone/contacts/LinphoneNumberOrAddress.java index 47656c5bb..449cdc13d 100644 --- a/app/src/main/java/org/linphone/contacts/LinphoneNumberOrAddress.java +++ b/app/src/main/java/org/linphone/contacts/LinphoneNumberOrAddress.java @@ -2,7 +2,7 @@ package org.linphone.contacts; /* LinphoneNumberOrAddress.java -Copyright (C) 2017 Belledonne Communications, Grenoble, France +Copyright (C) 2017 Belledonne Communications, Grenoble, France This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -89,4 +89,8 @@ public class LinphoneNumberOrAddress implements Serializable, Comparablefalse true true + true false