diff --git a/build.gradle b/build.gradle
index e86b4947a..c341bf0f5 100644
--- a/build.gradle
+++ b/build.gradle
@@ -13,7 +13,7 @@ dependencies {
}
android {
- compileSdkVersion 19
+ compileSdkVersion 22
buildToolsVersion "20.0.0"
sourceSets {
diff --git a/liblinphone_tester/custom_rules.xml b/liblinphone_tester/custom_rules.xml
index 6f643e8e6..0f2e0d9c0 100644
--- a/liblinphone_tester/custom_rules.xml
+++ b/liblinphone_tester/custom_rules.xml
@@ -55,7 +55,7 @@
-
+
@@ -73,6 +73,6 @@
-
+
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index 57cd2d29b..d328d0d43 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -393,7 +393,7 @@
Cet assistant va télécharger une configuration existante.
addresse où télécharger la configuration
La configuration téléchargée ne contient pas votre compte. Veuillez le remplir.
- Votre nom d\'utilisateur sera %s (les majuscules sont interdites). Acceptez-vous ?
+ Votre nom d\'utilisateur sera %s.\r\n\r\nIl peut différer de celui que vous avez choisi afin de remplir certains critères nécessaires.\r\nAcceptez-vous ?
Assistant de création de compte
Accepter
Refuser
diff --git a/res/values/non_localizable_custom.xml b/res/values/non_localizable_custom.xml
index 16fe84ca0..655403e73 100644
--- a/res/values/non_localizable_custom.xml
+++ b/res/values/non_localizable_custom.xml
@@ -33,6 +33,7 @@
false
true
true
+ true
false
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 863a82ac8..b55f1c215 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -396,7 +396,7 @@
This assistant will download an existing configuration.
provisioning url
The configuration you downloaded doesn\'t include your account. Please fill it in.
- Your username will be %s (uppercase characters are not allowed). Do you accept ?
+ Your username will be %s.\r\n\r\nIt may differ from what you entered to match some requierements.\r\nDo you accept ?
Account setup assistant
Accept
Deny
diff --git a/src/org/linphone/ChatActivity.java b/src/org/linphone/ChatActivity.java
index f37ec58cb..b486f4901 100644
--- a/src/org/linphone/ChatActivity.java
+++ b/src/org/linphone/ChatActivity.java
@@ -34,6 +34,7 @@ public class ChatActivity extends FragmentActivity {
extras.putString("SipUri", getIntent().getExtras().getString("SipUri"));
extras.putString("DisplayName", getIntent().getExtras().getString("DisplayName"));
extras.putString("PictureUri", getIntent().getExtras().getString("PictureUri"));
+ extras.putString("ThumbnailUri", getIntent().getExtras().getString("ThumbnailUri"));
ChatFragment fragment = new ChatFragment();
fragment.setArguments(extras);
diff --git a/src/org/linphone/ChatFragment.java b/src/org/linphone/ChatFragment.java
index 2820c6705..10ef4ac92 100644
--- a/src/org/linphone/ChatFragment.java
+++ b/src/org/linphone/ChatFragment.java
@@ -20,24 +20,29 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
+import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Calendar;
import java.util.List;
+
import org.linphone.compatibility.Compatibility;
import org.linphone.core.LinphoneAddress;
import org.linphone.core.LinphoneBuffer;
import org.linphone.core.LinphoneChatMessage;
import org.linphone.core.LinphoneChatMessage.LinphoneChatMessageListener;
-import org.linphone.core.LinphoneChatMessage.State;
import org.linphone.core.LinphoneChatRoom;
import org.linphone.core.LinphoneContent;
import org.linphone.core.LinphoneCore;
+import org.linphone.core.LinphoneChatMessage.State;
+import org.linphone.core.LinphoneCoreException;
import org.linphone.core.LinphoneCoreFactory;
import org.linphone.core.LinphoneCoreListenerBase;
import org.linphone.mediastream.Log;
import org.linphone.ui.AvatarWithShadow;
import org.linphone.ui.BubbleChat;
+import android.support.v4.content.CursorLoader;
import android.annotation.SuppressLint;
import android.app.Activity;
@@ -52,10 +57,10 @@ import android.graphics.Rect;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
+import android.os.Environment;
import android.os.Parcelable;
import android.provider.MediaStore;
import android.support.v4.app.Fragment;
-import android.support.v4.content.CursorLoader;
import android.text.Editable;
import android.text.InputType;
import android.text.TextWatcher;
@@ -84,6 +89,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
private static final int MENU_DELETE_MESSAGE = 0;
private static final int MENU_COPY_TEXT = 6;
private static final int MENU_RESEND_MESSAGE = 7;
+ private static final int SIZE_MAX = 2048;
private LinphoneChatRoom chatRoom;
private String sipUri;
@@ -334,6 +340,20 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
}
private void displayChatHeader(String displayName, String pictureUri) {
+ LinphoneAddress lAddress;
+ try {
+ lAddress = LinphoneCoreFactory.instance().createLinphoneAddress(sipUri);
+ Contact contact = ContactsManager.getInstance().findContactWithAddress(getActivity().getContentResolver(), lAddress);
+ if (contact != null) {
+ LinphoneUtils.setImagePictureFromUri(getActivity(), contactPicture.getView(), contact.getPhotoUri(), contact.getThumbnailUri(), R.drawable.unknown_small);
+
+ } else {
+ contactPicture.setImageResource(R.drawable.unknown_small);
+ }
+ } catch (LinphoneCoreException e) {
+ e.printStackTrace();
+ }
+
if (displayName == null && getResources().getBoolean(R.bool.only_display_username_if_unknown) && LinphoneUtils.isSipAddress(sipUri)) {
contactName.setText(LinphoneUtils.getUsernameFromAddress(sipUri));
} else if (displayName == null) {
@@ -342,11 +362,6 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
contactName.setText(displayName);
}
- if (pictureUri != null) {
- LinphoneUtils.setImagePictureFromUri(getActivity(), contactPicture.getView(), Uri.parse(pictureUri), R.drawable.unknown_small);
- } else {
- contactPicture.setImageResource(R.drawable.unknown_small);
- }
}
public void changeDisplayedChat(String newSipUri, String displayName, String pictureUri) {
@@ -526,6 +541,14 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
@Override
protected byte[] doInBackground(Bitmap... params) {
Bitmap bm = params[0];
+
+ if (bm.getWidth() > bm.getHeight() && bm.getWidth() > SIZE_MAX) {
+ bm = Bitmap.createScaledBitmap(bm, SIZE_MAX, (SIZE_MAX * bm.getHeight()) / bm.getWidth(), false);
+ } else if (bm.getHeight() > bm.getWidth() && bm.getHeight() > SIZE_MAX) {
+
+ bm = Bitmap.createScaledBitmap(bm, (SIZE_MAX * bm.getWidth()) / bm.getHeight(), SIZE_MAX, false);
+ }
+
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
@@ -601,6 +624,9 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
private void pickImage() {
List cameraIntents = new ArrayList();
Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
+ File file = new File(Environment.getExternalStorageDirectory(), getString(R.string.temp_photo_name) + Calendar.getInstance().getTime());
+ imageToUploadUri = Uri.fromFile(file);
+ captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageToUploadUri);
cameraIntents.add(captureIntent);
Intent galleryIntent = new Intent();
diff --git a/src/org/linphone/ChatListFragment.java b/src/org/linphone/ChatListFragment.java
index 9b9dc6116..e6a8b7e8d 100644
--- a/src/org/linphone/ChatListFragment.java
+++ b/src/org/linphone/ChatListFragment.java
@@ -356,7 +356,7 @@ public class ChatListFragment extends Fragment implements OnClickListener, OnIte
Log.e("Chat view cannot parse address",e);
return view;
}
- Contact lContact = ContactsManager.getInstance().findContactWithAddress(address);
+ Contact lContact = ContactsManager.getInstance().findContactWithAddress(getActivity().getContentResolver(), address);
String message = "";
if (useNativeAPI) {
@@ -365,7 +365,7 @@ public class ChatListFragment extends Fragment implements OnClickListener, OnIte
if (history != null && history.length > 0) {
for (int i = history.length - 1; i >= 0; i--) {
LinphoneChatMessage msg = history[i];
- if (msg.getText() != null && msg.getText().length() > 0) {
+ if (msg.getText() != null && msg.getText().length() > 0 && msg.getFileTransferInformation() == null) {
message = msg.getText();
break;
}
diff --git a/src/org/linphone/Contact.java b/src/org/linphone/Contact.java
index 4352bc21d..bbb4ebf13 100644
--- a/src/org/linphone/Contact.java
+++ b/src/org/linphone/Contact.java
@@ -37,6 +37,7 @@ public class Contact implements Serializable {
private String id;
private String name;
private transient Uri photoUri;
+ private transient Uri thumbnailUri;
private transient Bitmap photo;
private List numbersOrAddresses;
private boolean hasFriends;
@@ -46,23 +47,26 @@ public class Contact implements Serializable {
this.id = id;
this.name = name;
this.photoUri = null;
+ this.thumbnailUri = null;
this.hasFriends = false;
}
- public Contact(String id, String name, Uri photo) {
+ public Contact(String id, String name, Uri photo, Uri thumbnail) {
super();
this.id = id;
this.name = name;
this.photoUri = photo;
+ this.thumbnailUri = thumbnail;
this.photo = null;
this.hasFriends = false;
}
- public Contact(String id, String name, Uri photo, Bitmap picture) {
+ public Contact(String id, String name, Uri photo, Uri thumbnail, Bitmap picture) {
super();
this.id = id;
this.name = name;
this.photoUri = photo;
+ this.thumbnailUri = thumbnail;
this.photo = picture;
this.hasFriends = false;
}
@@ -83,6 +87,10 @@ public class Contact implements Serializable {
public Uri getPhotoUri() {
return photoUri;
}
+
+ public Uri getThumbnailUri() {
+ return thumbnailUri;
+ }
public Bitmap getPhoto() {
return photo;
@@ -96,7 +104,7 @@ public class Contact implements Serializable {
public void refresh(ContentResolver cr) {
this.numbersOrAddresses = Compatibility.extractContactNumbersAndAddresses(id, cr);
- for(LinphoneFriend friend : LinphoneManager.getLc().getFriendList()) {
+ for(LinphoneFriend friend : LinphoneManager.getLcIfManagerNotDestroyedOrNull().getFriendList()) {
if (friend.getRefKey().equals(id)) {
hasFriends = true;
this.numbersOrAddresses.add(friend.getAddress().asStringUriOnly());
diff --git a/src/org/linphone/ContactsManager.java b/src/org/linphone/ContactsManager.java
index bdfb75f2f..9fbc50d84 100644
--- a/src/org/linphone/ContactsManager.java
+++ b/src/org/linphone/ContactsManager.java
@@ -26,11 +26,14 @@ import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.ContactsContract;
+
import org.linphone.compatibility.Compatibility;
import org.linphone.core.LinphoneAddress;
+import org.linphone.core.LinphoneCore;
import org.linphone.core.LinphoneCoreException;
import org.linphone.core.LinphoneCoreFactory;
import org.linphone.core.LinphoneFriend;
+import org.linphone.core.LinphoneProxyConfig;
import org.linphone.mediastream.Log;
import java.util.ArrayList;
@@ -101,7 +104,7 @@ public class ContactsManager {
}
//Contacts
- public void createNewContact(ArrayList ops, String firstName, String lastName){
+ public void createNewContact(ArrayList ops, String firstName, String lastName) {
int contactID = 0;
ops.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
@@ -117,7 +120,7 @@ public class ContactsManager {
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, firstName)
.withValue(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME, lastName)
- .withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, getDisplayName(firstName,lastName))
+ .withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, getDisplayName(firstName, lastName))
.build()
);
}
@@ -125,8 +128,8 @@ public class ContactsManager {
public void updateExistingContact(ArrayList ops, Contact contact, String firstName, String lastName) {
if (getDisplayName(firstName, lastName) != null) {
- String select = ContactsContract.Data.CONTACT_ID + "=? AND " + ContactsContract.Data.MIMETYPE + "='" + ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE + "'" ;
- String[] args = new String[] { String.valueOf(contact.getID()) };
+ String select = ContactsContract.Data.CONTACT_ID + "=? AND " + ContactsContract.Data.MIMETYPE + "='" + ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE + "'";
+ String[] args = new String[]{String.valueOf(contact.getID())};
ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
.withSelection(select, args)
@@ -145,12 +148,13 @@ public class ContactsManager {
}
LinphoneFriend friend = LinphoneCoreFactory.instance().createLinphoneFriend(sipUri);
- if(friend != null) {
+ if (friend != null) {
friend.edit();
+ friend.enableSubscribes(false);
friend.setRefKey(contact.getID());
friend.done();
try {
- LinphoneManager.getLc().addFriend(friend);
+ LinphoneManager.getLcIfManagerNotDestroyedOrNull().addFriend(friend);
return true;
} catch (LinphoneCoreException e) {
e.printStackTrace();
@@ -170,8 +174,8 @@ public class ContactsManager {
oldSipUri = "sip:" + oldSipUri;
}
- LinphoneFriend friend = LinphoneManager.getLc().findFriendByAddress(oldSipUri);
- if(friend != null) {
+ LinphoneFriend friend = LinphoneManager.getLcIfManagerNotDestroyedOrNull().findFriendByAddress(oldSipUri);
+ if (friend != null) {
friend.edit();
try {
friend.setAddress(LinphoneCoreFactory.instance().createLinphoneAddress(newSipUri));
@@ -187,36 +191,59 @@ public class ContactsManager {
sipUri = "sip:" + sipUri;
}
- LinphoneFriend friend = LinphoneManager.getLc().findFriendByAddress(sipUri);
+ LinphoneFriend friend = LinphoneManager.getLcIfManagerNotDestroyedOrNull().findFriendByAddress(sipUri);
if (friend != null) {
- LinphoneManager.getLc().removeFriend(friend);
+ LinphoneManager.getLcIfManagerNotDestroyedOrNull().removeFriend(friend);
return true;
}
return false;
}
public void removeAllFriends(Contact contact) {
- for(LinphoneFriend friend : LinphoneManager.getLc().getFriendList()){
- if(friend.getRefKey().equals(contact.getID())) {
- LinphoneManager.getLc().removeFriend(friend);
+ for (LinphoneFriend friend : LinphoneManager.getLcIfManagerNotDestroyedOrNull().getFriendList()) {
+ if (friend.getRefKey().equals(contact.getID())) {
+ LinphoneManager.getLcIfManagerNotDestroyedOrNull().removeFriend(friend);
}
}
}
public Contact findContactWithDisplayName(String displayName) {
- String[] projection = { ContactsContract.Data.CONTACT_ID, ContactsContract.Data.DISPLAY_NAME };
+ String[] projection = {ContactsContract.Data.CONTACT_ID, ContactsContract.Data.DISPLAY_NAME};
String selection = new StringBuilder()
.append(ContactsContract.Data.DISPLAY_NAME)
.append(" = ?").toString();
- Cursor c = contentResolver.query(ContactsContract.Data.CONTENT_URI,projection,selection,
+ Cursor c = contentResolver.query(ContactsContract.Data.CONTENT_URI, projection, selection,
new String[]{displayName}, null);
if (c != null) {
if (c.moveToFirst()) {
- Contact contact = Compatibility.getContact(contentResolver,c,c.getPosition());
+ Contact contact = Compatibility.getContact(contentResolver, c, c.getPosition());
c.close();
- if(contact != null) {
+ if (contact != null) {
+ return contact;
+ } else {
+ return null;
+ }
+ }
+ c.close();
+ }
+ return null;
+ }
+
+ public Contact getContact(String id, ContentResolver contentResolver){
+ String[] projection = {ContactsContract.Data.CONTACT_ID, ContactsContract.Data.DISPLAY_NAME};
+ String selection = new StringBuilder()
+ .append(ContactsContract.Data.CONTACT_ID)
+ .append(" = ?").toString();
+
+ Cursor c = contentResolver.query(ContactsContract.Data.CONTENT_URI, projection, selection, new String[]{id}, null);
+ if(c!=null){
+ if (c.moveToFirst()) {
+ Contact contact = Compatibility.getContact(contentResolver, c, c.getPosition());
+ c.close();
+
+ if (contact != null) {
return contact;
} else {
return null;
@@ -229,8 +256,11 @@ public class ContactsManager {
public List getContactsId(){
List ids = new ArrayList();
- if(LinphoneManager.getLc().getFriendList() == null) return null;
- for(LinphoneFriend friend : LinphoneManager.getLc().getFriendList()) {
+ if(LinphoneManager.getLcIfManagerNotDestroyedOrNull().getFriendList() == null) return null;
+ for(LinphoneFriend friend : LinphoneManager.getLcIfManagerNotDestroyedOrNull().getFriendList()) {
+ friend.edit();
+ friend.enableSubscribes(false);
+ friend.done();
if(!ids.contains(friend.getRefKey())){
ids.add(friend.getRefKey());
}
@@ -241,15 +271,18 @@ public class ContactsManager {
//End linphone Friend
public boolean removeContactTagIsNeeded(Contact contact){
- contact.refresh(contentResolver);
- boolean onlyNumbers = true;
- for(String address: contact.getNumbersOrAddresses()){
- if(LinphoneUtils.isSipAddress(address)){
- onlyNumbers = false;
+ LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
+ if (lc != null) {
+ LinphoneProxyConfig lpc = lc.createProxyConfig();
+ contact.refresh(contentResolver);
+ for (String address : contact.getNumbersOrAddresses()) {
+ if (!lpc.isPhoneNumber(address)) {
+ return false;
+ }
}
+ return true;
}
-
- return onlyNumbers;
+ return false;
}
public void removeLinphoneContactTag(Contact contact){
@@ -270,12 +303,84 @@ public class ContactsManager {
}
}
- public Contact findContactWithAddress(LinphoneAddress address){
- for(Contact contact : contactList){
- if(contact.getNumbersOrAddresses().contains(address.asStringUriOnly()) || contact.getNumbersOrAddresses().contains(address.getUserName())){
- return contact;
+ private Contact checkPhoneQueryResult(ContentResolver contentResolver, Cursor c, String columnPhone, String columnId, String username) {
+ boolean contactFound = false;
+
+ if (c != null) {
+ while (!contactFound && c.moveToNext()) {
+ String phone = c.getString(c.getColumnIndex(columnPhone));
+ if (phone.equals(username)) {
+ contactFound = true;
+ } else {
+ String normalizedUsername = null;
+ LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
+ if (lc != null) {
+ LinphoneProxyConfig lpc = lc.getDefaultProxyConfig();
+ if (lpc != null) {
+ normalizedUsername = lpc.normalizePhoneNumber(phone);
+ }
+ }
+
+ if (normalizedUsername != null && normalizedUsername.equals(username)) {
+ contactFound = true;
+ }
+ }
+
+ if(contactFound){
+ Contact contact = getContact(c.getString(c.getColumnIndex(columnId)), contentResolver);
+ c.close();
+ return contact;
+ }
+ }
+ c.close();
+ }
+ return null;
+ }
+
+ public Contact findContactWithAddress(ContentResolver contentResolver, LinphoneAddress address){
+ String sipUri = address.asStringUriOnly();
+ if (sipUri.startsWith("sip:"))
+ sipUri = sipUri.substring(4);
+
+ if(LinphoneManager.getLcIfManagerNotDestroyedOrNull().getFriendList() != null && LinphoneManager.getLcIfManagerNotDestroyedOrNull().getFriendList().length > 0) {
+ for (LinphoneFriend friend : LinphoneManager.getLcIfManagerNotDestroyedOrNull().getFriendList()) {
+ if (friend.getAddress().equals(address)) {
+ return getContact(friend.getRefKey(), contentResolver);
+ }
}
}
+
+ //Find Sip address
+ Contact contact;
+ String [] projection = new String[] {ContactsContract.Data.CONTACT_ID, ContactsContract.Data.DISPLAY_NAME};
+ String selection = new StringBuilder()
+ .append(ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS)
+ .append(" = ?").toString();
+
+ Cursor cur = contentResolver.query(ContactsContract.Data.CONTENT_URI, projection, selection,
+ new String[]{sipUri}, null);
+ if (cur != null) {
+ if (cur.moveToFirst()) {
+ contact = Compatibility.getContact(contentResolver, cur, cur.getPosition());
+ cur.close();
+
+ if (contact != null) {
+ return contact;
+ }
+ }
+ cur.close();
+ }
+
+ //Find number
+ Uri lookupUri = Uri.withAppendedPath(android.provider.ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(address.getUserName()));
+ projection = new String[] {ContactsContract.PhoneLookup._ID,ContactsContract.PhoneLookup.NUMBER,ContactsContract.PhoneLookup.DISPLAY_NAME };
+ Cursor c = contentResolver.query(lookupUri, projection, null, null, null);
+ contact = checkPhoneQueryResult(contentResolver, c, ContactsContract.PhoneLookup.NUMBER, ContactsContract.PhoneLookup._ID, address.getUserName());
+
+ if (contact != null) {
+ return contact;
+ }
+
return null;
}
@@ -425,7 +530,7 @@ public class ContactsManager {
contact.refresh(contentResolver);
//Add tag to Linphone contact if it not existed
- if (LinphoneActivity.instance().getResources().getBoolean(R.bool.use_linphone_tag)) {
+ if (LinphoneActivity.isInstanciated() && LinphoneActivity.instance().getResources().getBoolean(R.bool.use_linphone_tag)) {
if (!isContactHasLinphoneTag(contact, contentResolver)) {
Compatibility.createLinphoneContactTag(context, contentResolver, contact,
findRawContactID(contentResolver, String.valueOf(contact.getID())));
@@ -438,13 +543,12 @@ public class ContactsManager {
if (contactCursor != null) {
for (int i = 0; i < contactCursor.getCount(); i++) {
Contact contact = Compatibility.getContact(contentResolver, contactCursor, i);
-
if (contact == null)
continue;
//Remove linphone contact tag if the contact has no sip address
- if (LinphoneActivity.instance().getResources().getBoolean(R.bool.use_linphone_tag)) {
- if (removeContactTagIsNeeded(contact) && isContactHasLinphoneTag(contact, contentResolver)) {
+ if (LinphoneActivity.isInstanciated() && LinphoneActivity.instance().getResources().getBoolean(R.bool.use_linphone_tag)) {
+ if (removeContactTagIsNeeded(contact) && findRawLinphoneContactID(contact.getID()) != null) {
removeLinphoneContactTag(contact);
}
}
diff --git a/src/org/linphone/EditContactFragment.java b/src/org/linphone/EditContactFragment.java
index eed7b0f70..b63bd5cad 100644
--- a/src/org/linphone/EditContactFragment.java
+++ b/src/org/linphone/EditContactFragment.java
@@ -102,6 +102,7 @@ public class EditContactFragment extends Fragment {
try {
getActivity().getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
addLinphoneFriendIfNeeded();
+ removeLinphoneTagIfNeeded();
contactsManager.prepareContactsInBackground();
} catch (Exception e) {
e.printStackTrace();
@@ -415,6 +416,21 @@ public class EditContactFragment extends Fragment {
}
}
}
+
+ private void removeLinphoneTagIfNeeded(){
+ if(!isNewContact) {
+ boolean areAllSipFielsEmpty = true;
+ for (NewOrUpdatedNumberOrAddress nounoa : numbersAndAddresses) {
+ if (!nounoa.isSipAddress && (nounoa.oldNumberOrAddress != null && !nounoa.oldNumberOrAddress.equals("") || nounoa.newNumberOrAddress != null && !nounoa.newNumberOrAddress.equals(""))) {
+ areAllSipFielsEmpty = false;
+ break;
+ }
+ }
+ if (areAllSipFielsEmpty && contactsManager.findRawLinphoneContactID(contact.getID()) != null) {
+ contactsManager.removeLinphoneContactTag(contact);
+ }
+ }
+ }
class NewOrUpdatedNumberOrAddress {
private String oldNumberOrAddress;
diff --git a/src/org/linphone/HistoryDetailFragment.java b/src/org/linphone/HistoryDetailFragment.java
index 7d0eae6d8..ceea76b21 100644
--- a/src/org/linphone/HistoryDetailFragment.java
+++ b/src/org/linphone/HistoryDetailFragment.java
@@ -23,6 +23,7 @@ import java.util.Calendar;
import org.linphone.core.LinphoneAddress;
import org.linphone.core.LinphoneCoreException;
import org.linphone.core.LinphoneCoreFactory;
+import org.linphone.mediastream.Log;
import org.linphone.ui.AvatarWithShadow;
import android.annotation.SuppressLint;
@@ -112,12 +113,12 @@ public class HistoryDetailFragment extends Fragment implements OnClickListener {
LinphoneAddress lAddress;
try {
lAddress = LinphoneCoreFactory.instance().createLinphoneAddress(sipUri);
- Contact contact = ContactsManager.getInstance().findContactWithAddress(lAddress);
+ Contact contact = ContactsManager.getInstance().findContactWithAddress(getActivity().getContentResolver(), lAddress);
if (contact != null) {
- LinphoneUtils.setImagePictureFromUri(view.getContext(), contactPicture.getView(),contact.getPhotoUri(), R.drawable.unknown_small);
+ LinphoneUtils.setImagePictureFromUri(view.getContext(), contactPicture.getView(),contact.getPhotoUri(), contact.getThumbnailUri(), R.drawable.unknown_small);
view.findViewById(R.id.addContactRow).setVisibility(View.GONE);
} else {
- LinphoneUtils.setImagePictureFromUri(view.getContext(), contactPicture.getView(),null ,R.drawable.unknown_small);
+ LinphoneUtils.setImagePictureFromUri(view.getContext(), contactPicture.getView(),null, null ,R.drawable.unknown_small);
}
} catch (LinphoneCoreException e) {
e.printStackTrace();
diff --git a/src/org/linphone/HistoryFragment.java b/src/org/linphone/HistoryFragment.java
index 6f7c2ee97..3a3b87ddc 100644
--- a/src/org/linphone/HistoryFragment.java
+++ b/src/org/linphone/HistoryFragment.java
@@ -178,7 +178,7 @@ public class HistoryFragment extends Fragment implements OnClickListener, OnChil
address = log.getTo();
}
- Contact contact = ContactsManager.getInstance().findContactWithAddress(address);
+ Contact contact = ContactsManager.getInstance().findContactWithAddress(getActivity().getContentResolver(), address);
String sipUri = address.asStringUriOnly();
if (contact == null) {
if (getResources().getBoolean(R.bool.only_display_username_if_unknown) && LinphoneUtils.isSipAddress(sipUri)) {
diff --git a/src/org/linphone/HistorySimpleFragment.java b/src/org/linphone/HistorySimpleFragment.java
index 266a84d78..aa5abdeff 100644
--- a/src/org/linphone/HistorySimpleFragment.java
+++ b/src/org/linphone/HistorySimpleFragment.java
@@ -392,7 +392,7 @@ public class HistorySimpleFragment extends Fragment implements OnClickListener,
callDirection.setImageBitmap(outgoingCall);
}
- Contact c = ContactsManager.getInstance().findContactWithAddress(address);
+ Contact c = ContactsManager.getInstance().findContactWithAddress(getActivity().getContentResolver(), address);
String displayName = null;
final String sipUri = address.asStringUriOnly();
if(c != null){
diff --git a/src/org/linphone/InCallActivity.java b/src/org/linphone/InCallActivity.java
index 052cfd18c..181d1e677 100644
--- a/src/org/linphone/InCallActivity.java
+++ b/src/org/linphone/InCallActivity.java
@@ -1299,11 +1299,11 @@ public class InCallActivity extends FragmentActivity implements OnClickListener
// Image Row
LinearLayout imageView = (LinearLayout) inflater.inflate(R.layout.active_call_image_row, container, false);
- Contact contact = ContactsManager.getInstance().findContactWithAddress(lAddress);
+ Contact contact = ContactsManager.getInstance().findContactWithAddress(imageView.getContext().getContentResolver(), lAddress);
if(contact != null) {
- displayOrHideContactPicture(imageView, contact.getPhotoUri(), false);
+ displayOrHideContactPicture(imageView, contact.getPhotoUri(), contact.getThumbnailUri(), false);
} else {
- displayOrHideContactPicture(imageView, null, false);
+ displayOrHideContactPicture(imageView, null, null, false);
}
callsList.addView(imageView);
@@ -1326,7 +1326,7 @@ public class InCallActivity extends FragmentActivity implements OnClickListener
private void setContactName(LinearLayout callView, LinphoneAddress lAddress, String sipUri, Resources resources) {
TextView contact = (TextView) callView.findViewById(R.id.contactNameOrNumber);
- Contact lContact = ContactsManager.getInstance().findContactWithAddress(lAddress);
+ Contact lContact = ContactsManager.getInstance().findContactWithAddress(callView.getContext().getContentResolver(), lAddress);
if (lContact == null) {
if (resources.getBoolean(R.bool.only_display_username_if_unknown) && LinphoneUtils.isSipAddress(sipUri)) {
contact.setText(lAddress.getUserName());
@@ -1366,10 +1366,10 @@ public class InCallActivity extends FragmentActivity implements OnClickListener
return isCallPaused || isInConference;
}
- private void displayOrHideContactPicture(LinearLayout callView, Uri pictureUri, boolean hide) {
+ private void displayOrHideContactPicture(LinearLayout callView, Uri pictureUri, Uri thumbnailUri, boolean hide) {
AvatarWithShadow contactPicture = (AvatarWithShadow) callView.findViewById(R.id.contactPicture);
if (pictureUri != null) {
- LinphoneUtils.setImagePictureFromUri(callView.getContext(), contactPicture.getView(), Uri.parse(pictureUri.toString()), R.drawable.unknown_small);
+ LinphoneUtils.setImagePictureFromUri(callView.getContext(), contactPicture.getView(), Uri.parse(pictureUri.toString()), thumbnailUri, R.drawable.unknown_small);
}
callView.setVisibility(hide ? View.GONE : View.VISIBLE);
}
diff --git a/src/org/linphone/IncomingCallActivity.java b/src/org/linphone/IncomingCallActivity.java
index fa04b0ad9..713c009d0 100644
--- a/src/org/linphone/IncomingCallActivity.java
+++ b/src/org/linphone/IncomingCallActivity.java
@@ -124,8 +124,9 @@ public class IncomingCallActivity extends Activity implements LinphoneSliderTrig
}
LinphoneAddress address = mCall.getRemoteAddress();
// May be greatly sped up using a drawable cache
- Contact contact = ContactsManager.getInstance().findContactWithAddress(address);
- LinphoneUtils.setImagePictureFromUri(this, mPictureView.getView(), contact != null ? contact.getPhotoUri() : null, R.drawable.unknown_small);
+ Contact contact = ContactsManager.getInstance().findContactWithAddress(getContentResolver(), address);
+ LinphoneUtils.setImagePictureFromUri(this, mPictureView.getView(), contact != null ? contact.getPhotoUri() : null,
+ contact != null ? contact.getThumbnailUri() : null, R.drawable.unknown_small);
// To be done after findUriPictureOfContactAndSetDisplayName called
mNameView.setText(contact != null ? contact.getName() : "");
diff --git a/src/org/linphone/LinphoneActivity.java b/src/org/linphone/LinphoneActivity.java
index 3f3990067..2b0e8bf18 100644
--- a/src/org/linphone/LinphoneActivity.java
+++ b/src/org/linphone/LinphoneActivity.java
@@ -518,7 +518,7 @@ public class LinphoneActivity extends FragmentActivity implements OnClickListene
Log.e("Cannot display history details",e);
return;
}
- Contact c = ContactsManager.getInstance().findContactWithAddress(lAddress);
+ Contact c = ContactsManager.getInstance().findContactWithAddress(getContentResolver(), lAddress);
String displayName = c != null ? c.getName() : null;
String pictureUri = c != null && c.getPhotoUri() != null ? c.getPhotoUri().toString() : null;
@@ -611,9 +611,15 @@ public class LinphoneActivity extends FragmentActivity implements OnClickListene
Log.e("Cannot display chat",e);
return;
}
- Contact contact = ContactsManager.getInstance().findContactWithAddress(lAddress);
+ Contact contact = ContactsManager.getInstance().findContactWithAddress(getContentResolver(), lAddress);
String displayName = contact != null ? contact.getName() : null;
- String pictureUri = contact != null && contact.getPhotoUri() != null ? contact.getPhotoUri().toString() : null;
+
+ String pictureUri = null;
+ String thumbnailUri = null;
+ if(contact != null && contact.getPhotoUri() != null){
+ pictureUri = contact.getPhotoUri().toString();
+ thumbnailUri = contact.getThumbnailUri().toString();
+ }
if (isTablet()){
if (currentFragment == FragmentsAvailable.CHATLIST || currentFragment == FragmentsAvailable.CHAT){
@@ -624,9 +630,10 @@ public class LinphoneActivity extends FragmentActivity implements OnClickListene
} else {
Bundle extras = new Bundle();
extras.putString("SipUri", sipUri);
- if (lAddress.getDisplayName() != null) {
+ if (contact != null) {
extras.putString("DisplayName", displayName);
extras.putString("PictureUri", pictureUri);
+ extras.putString("ThumbnailUri", thumbnailUri);
}
changeCurrentFragment(FragmentsAvailable.CHAT, extras);
}
@@ -639,7 +646,8 @@ public class LinphoneActivity extends FragmentActivity implements OnClickListene
intent.putExtra("SipUri", sipUri);
if (contact != null) {
intent.putExtra("DisplayName", contact.getName());
- intent.putExtra("PictureUri", contact.getPhotoUri());
+ intent.putExtra("PictureUri", pictureUri);
+ intent.putExtra("ThumbnailUri", thumbnailUri);
}
startOrientationSensor();
startActivityForResult(intent, CHAT_ACTIVITY);
diff --git a/src/org/linphone/LinphoneManager.java b/src/org/linphone/LinphoneManager.java
index 78e9ec489..3ebd4d8c8 100644
--- a/src/org/linphone/LinphoneManager.java
+++ b/src/org/linphone/LinphoneManager.java
@@ -715,7 +715,7 @@ public class LinphoneManager implements LinphoneCoreListener {
}
try {
- Contact contact = ContactsManager.getInstance().findContactWithAddress(from);
+ Contact contact = ContactsManager.getInstance().findContactWithAddress(mServiceContext.getContentResolver(),from);
if (!mServiceContext.getResources().getBoolean(R.bool.disable_chat__message_notification)) {
if(contact != null) {
LinphoneService.instance().displayMessageNotification(from.asStringUriOnly(), contact.getName(), textMessage);
diff --git a/src/org/linphone/LinphoneService.java b/src/org/linphone/LinphoneService.java
index 9d9c93110..45284019d 100644
--- a/src/org/linphone/LinphoneService.java
+++ b/src/org/linphone/LinphoneService.java
@@ -312,7 +312,7 @@ public final class LinphoneService extends Service {
LinphoneAddress address = LinphoneCoreFactory.instance().createLinphoneAddress(userName,domain,null);
address.setDisplayName(displayName);
- Contact contact = ContactsManager.getInstance().findContactWithAddress(address);
+ Contact contact = ContactsManager.getInstance().findContactWithAddress(getContentResolver(), address);
Uri pictureUri = contact != null ? contact.getPhotoUri() : null;
Bitmap bm = null;
try {
@@ -390,7 +390,7 @@ public final class LinphoneService extends Service {
Uri pictureUri = null;
try {
- Contact contact = ContactsManager.getInstance().findContactWithAddress(LinphoneCoreFactory.instance().createLinphoneAddress(fromSipUri));
+ Contact contact = ContactsManager.getInstance().findContactWithAddress(getContentResolver(), LinphoneCoreFactory.instance().createLinphoneAddress(fromSipUri));
if (contact != null)
pictureUri = contact.getPhotoUri();
} catch (LinphoneCoreException e1) {
diff --git a/src/org/linphone/LinphoneUtils.java b/src/org/linphone/LinphoneUtils.java
index be4e956dd..e0491885f 100644
--- a/src/org/linphone/LinphoneUtils.java
+++ b/src/org/linphone/LinphoneUtils.java
@@ -56,6 +56,7 @@ import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Build;
+import android.provider.MediaStore;
import android.telephony.TelephonyManager;
import android.util.TypedValue;
import android.view.KeyEvent;
@@ -156,7 +157,7 @@ public final class LinphoneUtils {
}
- public static void setImagePictureFromUri(Context c, ImageView view, Uri uri, int notFoundResource) {
+ public static void setImagePictureFromUri(Context c, ImageView view, Uri uri, Uri tUri, int notFoundResource) {
if (uri == null) {
view.setImageResource(notFoundResource);
return;
@@ -167,7 +168,17 @@ public final class LinphoneUtils {
view.setImageBitmap(bm);
} else {
if (Version.sdkAboveOrEqual(Version.API06_ECLAIR_201)) {
- view.setImageURI(uri);
+ Bitmap bm = null;
+ try {
+ bm = MediaStore.Images.Media.getBitmap(c.getContentResolver(),uri);
+ } catch (IOException e) {
+ if(tUri != null){
+ view.setImageURI(tUri);
+ }
+ }
+ if(bm != null) {
+ view.setImageBitmap(bm);
+ }
} else {
@SuppressWarnings("deprecation")
Bitmap bitmap = android.provider.Contacts.People.loadContactPhoto(c, uri, notFoundResource, null);
diff --git a/src/org/linphone/compatibility/ApiFivePlus.java b/src/org/linphone/compatibility/ApiFivePlus.java
index 5fcc12100..11ce8f0db 100644
--- a/src/org/linphone/compatibility/ApiFivePlus.java
+++ b/src/org/linphone/compatibility/ApiFivePlus.java
@@ -216,7 +216,8 @@ public class ApiFivePlus {
String id = cursor.getString(cursor.getColumnIndex(Data.CONTACT_ID));
String name = getContactDisplayName(cursor);
- Uri photo = getContactPictureUri(id);
+ Uri thumbnail = getContactPictureUri(id);
+ Uri photo = getContactPhotoUri(id);
InputStream input = getContactPictureInputStream(cr, id);
Contact contact;
@@ -228,7 +229,7 @@ public class ApiFivePlus {
try {
bm = BitmapFactory.decodeStream(input);
} catch (OutOfMemoryError oome) {}
- contact = new Contact(id, name, photo, bm);
+ contact = new Contact(id, name, photo, thumbnail, bm);
}
return contact;
@@ -248,6 +249,11 @@ public class ApiFivePlus {
}
private static Uri getContactPictureUri(String id) {
+ Uri person = ContentUris.withAppendedId(Contacts.CONTENT_URI, Long.parseLong(id));
+ return Uri.withAppendedPath(person, Contacts.Photo.CONTENT_DIRECTORY);
+ }
+
+ private static Uri getContactPhotoUri(String id) {
Uri person = ContentUris.withAppendedId(Contacts.CONTENT_URI, Long.parseLong(id));
return Uri.withAppendedPath(person, Contacts.Photo.DISPLAY_PHOTO);
}
diff --git a/src/org/linphone/setup/WizardFragment.java b/src/org/linphone/setup/WizardFragment.java
index 271206504..571f56bdb 100644
--- a/src/org/linphone/setup/WizardFragment.java
+++ b/src/org/linphone/setup/WizardFragment.java
@@ -24,6 +24,7 @@ import java.util.regex.Pattern;
import org.linphone.LinphoneManager;
import org.linphone.LinphoneService;
import org.linphone.R;
+import org.linphone.core.LinphoneProxyConfig;
import android.accounts.Account;
import android.accounts.AccountManager;
@@ -65,6 +66,17 @@ public class WizardFragment extends Fragment {
private char[] acceptedChars = new char[]{ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.', '_', '-' };
+ private char[] acceptedCharsForPhoneNumbers = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '+' };
+ private String inputFilterCharacters;
+
+ private String getUsername() {
+ String username = this.username.getText().toString();
+ if (getResources().getBoolean(R.bool.allow_only_phone_numbers_in_wizard)) {
+ LinphoneProxyConfig lpc = LinphoneManager.getLc().createProxyConfig();
+ username = lpc.normalizePhoneNumber(username);
+ }
+ return username.toLowerCase(Locale.getDefault());
+ }
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
@@ -73,12 +85,17 @@ public class WizardFragment extends Fragment {
username = (EditText) view.findViewById(R.id.setup_username);
ImageView usernameOkIV = (ImageView) view.findViewById(R.id.setup_username_ok);
addXMLRPCUsernameHandler(username, usernameOkIV);
+
+ inputFilterCharacters = new String(acceptedChars);
+ if (getResources().getBoolean(R.bool.allow_only_phone_numbers_in_wizard)) {
+ inputFilterCharacters = new String(acceptedCharsForPhoneNumbers);
+ }
InputFilter filter = new InputFilter(){
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
if (end > start) {
for (int index = start; index < end; index++) {
- if (!new String(acceptedChars).contains(String.valueOf(source.charAt(index)))) {
+ if (!inputFilterCharacters.contains(String.valueOf(source.charAt(index)))) {
return "";
}
}
@@ -110,20 +127,16 @@ public class WizardFragment extends Fragment {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setPositiveButton(R.string.button_ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
- createAccount(username.getText().toString().toLowerCase(Locale.getDefault()), password.getText().toString(), email.getText().toString(), false);
+ createAccount(getUsername(), password.getText().toString(), email.getText().toString(), false);
}
});
builder.setNegativeButton(R.string.button_cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
}
});
- if(!username.getText().toString().equals(username.getText().toString().toLowerCase(Locale.getDefault()))){
- builder.setMessage(getString(R.string.setup_confirm_username).replace("%s", username.getText().toString().toLowerCase(Locale.getDefault())));
- AlertDialog dialog = builder.create();
- dialog.show();
- } else {
- createAccount(username.getText().toString().toLowerCase(Locale.getDefault()), password.getText().toString(), email.getText().toString(), false);
- }
+ builder.setMessage(getString(R.string.setup_confirm_username).replace("%s", getUsername()));
+ AlertDialog dialog = builder.create();
+ dialog.show();
}
});
@@ -143,7 +156,11 @@ public class WizardFragment extends Fragment {
}
private boolean isUsernameCorrect(String username) {
- return username.matches("^[a-zA-Z]+[a-zA-Z0-9.\\-_]{2,}$");
+ if (getResources().getBoolean(R.bool.allow_only_phone_numbers_in_wizard)) {
+ return username.matches("^(\\+)?(\\d-)?(\\d{3}-)?(\\d{3}-)?\\d{4,}$");
+ } else {
+ return username.matches("^[a-zA-Z]+[a-zA-Z0-9.\\-_]{2,}$");
+ }
}
private void isUsernameRegistred(String username, final ImageView icon) {
@@ -278,6 +295,10 @@ public class WizardFragment extends Fragment {
usernameOk = false;
String username = field.getText().toString().toLowerCase(Locale.getDefault());
if (isUsernameCorrect(username)) {
+ if (getResources().getBoolean(R.bool.allow_only_phone_numbers_in_wizard)) {
+ LinphoneProxyConfig lpc = LinphoneManager.getLc().createProxyConfig();
+ username = lpc.normalizePhoneNumber(username);
+ }
isUsernameRegistred(username, icon);
} else {
errorMessage.setText(R.string.wizard_username_incorrect);
diff --git a/src/org/linphone/ui/BubbleChat.java b/src/org/linphone/ui/BubbleChat.java
index 0c768fea2..b75169fd7 100644
--- a/src/org/linphone/ui/BubbleChat.java
+++ b/src/org/linphone/ui/BubbleChat.java
@@ -95,6 +95,7 @@ public class BubbleChat {
private ImageView statusView;
private LinphoneChatMessage nativeMessage;
private LinphoneChatMessage.LinphoneChatMessageListener fileTransferListener;
+ private static final int SIZE_MAX = 2048;
@SuppressLint("InflateParams")
public BubbleChat(final Context context, LinphoneChatMessage message, LinphoneChatMessage.LinphoneChatMessageListener listener) {
@@ -173,6 +174,13 @@ public class BubbleChat {
bm = BitmapFactory.decodeFile(appData);
appData = "file://" + appData;
}
+
+ if (bm.getWidth() > bm.getHeight() && bm.getWidth() > SIZE_MAX) {
+ bm = Bitmap.createScaledBitmap(bm, SIZE_MAX, (SIZE_MAX * bm.getHeight()) / bm.getWidth(), false);
+ } else if (bm.getHeight() > bm.getWidth() && bm.getHeight() > SIZE_MAX) {
+
+ bm = Bitmap.createScaledBitmap(bm, (SIZE_MAX * bm.getWidth()) / bm.getHeight(), SIZE_MAX, false);
+ }
if (bm != null) {
imageView.setImageBitmap(bm);
diff --git a/submodules/belle-sip b/submodules/belle-sip
index b3fcd2a85..7d27eb87c 160000
--- a/submodules/belle-sip
+++ b/submodules/belle-sip
@@ -1 +1 @@
-Subproject commit b3fcd2a8503069a9e9b0d15cc872e55c0eb48cf3
+Subproject commit 7d27eb87c5dbd530e1c0a95cd0da2e233fb4d6b5
diff --git a/submodules/linphone b/submodules/linphone
index 5913eff7a..5a0c92bac 160000
--- a/submodules/linphone
+++ b/submodules/linphone
@@ -1 +1 @@
-Subproject commit 5913eff7a5ff4516c745669b6bedb87f367a84fa
+Subproject commit 5a0c92bac32d086e176e2b10d13c7fd5bb4c1032
diff --git a/tests/custom_rules.xml b/tests/custom_rules.xml
index a6e0af289..5a23506fc 100644
--- a/tests/custom_rules.xml
+++ b/tests/custom_rules.xml
@@ -48,7 +48,7 @@
-
+
@@ -65,6 +65,6 @@
-
+