Added a custom setting to allow fetching all device contacts + added debu logs
This commit is contained in:
parent
6ba56bb8f2
commit
35a2010488
16 changed files with 133 additions and 75 deletions
|
@ -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,33 +208,16 @@ 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()) {
|
||||
void updateNativeContactWithPresenceInfo(String value) {
|
||||
if (!isLinphoneAddressMimeEntryAlreadyExisting(value)) {
|
||||
Log.d("[Contact] Adding presence information " + value);
|
||||
addChangesToCommit(
|
||||
ContentProviderOperation.newInsert(Data.CONTENT_URI)
|
||||
ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
|
||||
.withValue(ContactsContract.Data.RAW_CONTACT_ID, mAndroidRawId)
|
||||
.withValue(
|
||||
ContactsContract.Data.RAW_CONTACT_ID, mAndroidRawId)
|
||||
.withValue(
|
||||
Data.MIMETYPE,
|
||||
ContactsContract.Data.MIMETYPE,
|
||||
ContactsManager.getInstance()
|
||||
.getString(
|
||||
R.string
|
||||
.linphone_address_mime_type))
|
||||
.getString(R.string.linphone_address_mime_type))
|
||||
.withValue("data1", value) // phone number
|
||||
.withValue(
|
||||
"data2",
|
||||
|
@ -244,20 +225,19 @@ class AndroidContact implements Serializable {
|
|||
.getString(R.string.app_name)) // Summary
|
||||
.withValue("data3", value) // Detail
|
||||
.build());
|
||||
saveChangesCommited();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
|
|
|
@ -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<Void, AndroidContact, Void> {
|
||||
|
||||
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<Void, AndroidContact, Void>
|
|||
|
||||
@Override
|
||||
protected Void doInBackground(Void... voids) {
|
||||
linphoneContact.updateNativeContactWithPresenceInfo(linphoneContact);
|
||||
mLinphoneContact.updateNativeContactWithPresenceInfo();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -78,12 +78,19 @@ class AsyncContactsLoader extends AsyncTask<Void, Void, AsyncContactsLoader.Asyn
|
|||
@Override
|
||||
protected AsyncContactsData doInBackground(Void... params) {
|
||||
Log.i("[Contacts Manager] Background synchronization started");
|
||||
|
||||
String selection = null;
|
||||
if (mContext.getResources().getBoolean(R.bool.fetch_contacts_from_default_directory)) {
|
||||
Log.i("[Contacts Manager] Only fetching contacts in default directory");
|
||||
selection = ContactsContract.Data.IN_DEFAULT_DIRECTORY + " == 1";
|
||||
}
|
||||
|
||||
Cursor c =
|
||||
mContext.getContentResolver()
|
||||
.query(
|
||||
ContactsContract.Data.CONTENT_URI,
|
||||
PROJECTION,
|
||||
ContactsContract.Data.IN_DEFAULT_DIRECTORY + " == 1",
|
||||
selection,
|
||||
null,
|
||||
null);
|
||||
|
||||
|
@ -141,6 +148,11 @@ class AsyncContactsLoader extends AsyncTask<Void, Void, AsyncContactsLoader.Asyn
|
|||
|
||||
LinphoneContact contact = androidContactsCache.get(id);
|
||||
if (contact == null) {
|
||||
Log.d(
|
||||
"[Contacts Manager] Creating LinphoneContact with native ID "
|
||||
+ id
|
||||
+ ", favorite flag is "
|
||||
+ starred);
|
||||
nativeIds.add(id);
|
||||
contact = new LinphoneContact();
|
||||
contact.setAndroidId(id);
|
||||
|
|
|
@ -358,11 +358,18 @@ public class ContactsManager extends ContentObserver implements FriendListListen
|
|||
public synchronized LinphoneContact findContactFromAddress(Address address) {
|
||||
if (address == null) return null;
|
||||
Core core = LinphoneManager.getCore();
|
||||
|
||||
Friend lf = core.findFriend(address);
|
||||
if (lf != null) {
|
||||
return (LinphoneContact) lf.getUserData();
|
||||
}
|
||||
return findContactFromPhoneNumber(address.getUsername());
|
||||
|
||||
String username = address.getUsername();
|
||||
if (android.util.Patterns.PHONE.matcher(username).matches()) {
|
||||
return findContactFromPhoneNumber(username);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public synchronized LinphoneContact findContactFromPhoneNumber(String phoneNumber) {
|
||||
|
|
|
@ -37,6 +37,7 @@ import org.linphone.core.FriendList;
|
|||
import org.linphone.core.PresenceBasicStatus;
|
||||
import org.linphone.core.PresenceModel;
|
||||
import org.linphone.core.SubscribePolicy;
|
||||
import org.linphone.core.tools.Log;
|
||||
|
||||
public class LinphoneContact extends AndroidContact
|
||||
implements Serializable, Comparable<LinphoneContact> {
|
||||
|
@ -208,18 +209,18 @@ public class LinphoneContact extends AndroidContact
|
|||
boolean found = false;
|
||||
// Check for duplicated phone numbers but with different formats
|
||||
for (LinphoneNumberOrAddress number : mAddresses) {
|
||||
if (!number.isSIPAddress()) {
|
||||
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())) {
|
||||
|| (noa.getNormalizedPhone().equals(number.getValue()))) {
|
||||
Log.d("[Linphone Contact] Duplicated entry detected: " + noa);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
if (noa.isSIPAddress()) {
|
||||
|
@ -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());
|
||||
|
|
|
@ -89,4 +89,8 @@ public class LinphoneNumberOrAddress implements Serializable, Comparable<Linphon
|
|||
public String getNormalizedPhone() {
|
||||
return mNormalizedPhone != null ? mNormalizedPhone : mValue;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return (isSIPAddress() ? "sip:" : "tel:") + getNormalizedPhone();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -110,6 +110,7 @@
|
|||
<bool name="hide_invite_contact">false</bool>
|
||||
<bool name="generate_text_avatar">true</bool>
|
||||
<bool name="only_show_address_username_if_matches_default_domain">true</bool>
|
||||
<bool name="fetch_contacts_from_default_directory">true</bool> <!-- Recommended -->
|
||||
|
||||
<!-- Side Menu -->
|
||||
<bool name="hide_assistant_from_side_menu">false</bool>
|
||||
|
|
Loading…
Reference in a new issue