From 9ef3311f08a3caec83cf391a29ac6cad8f4063c4 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 8 Nov 2012 15:11:12 +0100 Subject: [PATCH] Added in-app contact editor support for Android < 9 + bugfix --- src/org/linphone/EditContactFragment.java | 48 ++--------- .../linphone/compatibility/ApiFivePlus.java | 49 +++++++++++ .../linphone/compatibility/ApiNinePlus.java | 83 +++++++++++++++++++ .../linphone/compatibility/Compatibility.java | 76 ++++++++++++----- 4 files changed, 196 insertions(+), 60 deletions(-) create mode 100644 src/org/linphone/compatibility/ApiNinePlus.java diff --git a/src/org/linphone/EditContactFragment.java b/src/org/linphone/EditContactFragment.java index 7fa628241..33a02659b 100644 --- a/src/org/linphone/EditContactFragment.java +++ b/src/org/linphone/EditContactFragment.java @@ -247,9 +247,11 @@ public class EditContactFragment extends Fragment { if (isSip) { controls.addView(view, controls.getChildCount()); - // Move to the bottom the remove contact button - controls.removeView(deleteContact); - controls.addView(deleteContact, controls.getChildCount()); + if (deleteContact != null) { + // Move to the bottom the remove contact button + controls.removeView(deleteContact); + controls.addView(deleteContact, controls.getChildCount()); + } } else { if (firstSipAddressIndex != -1) { controls.addView(view, firstSipAddressIndex); @@ -361,15 +363,7 @@ public class EditContactFragment extends Fragment { public void delete() { if (isSipAddress) { - String select = ContactsContract.Data.CONTACT_ID + "=? AND " - + ContactsContract.Data.MIMETYPE + "='" + ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE + "' AND " - + ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS + "=?"; - String[] args = new String[] { String.valueOf(contactID), oldNumberOrAddress }; - - ops.add(ContentProviderOperation.newDelete(ContactsContract.Data.CONTENT_URI) - .withSelection(select, args) - .build() - ); + Compatibility.deleteSipAddressFromContact(ops, oldNumberOrAddress, String.valueOf(contactID)); } else { String select = ContactsContract.Data.CONTACT_ID + "=? AND " + ContactsContract.Data.MIMETYPE + "='" + ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE + "' AND " @@ -386,14 +380,7 @@ public class EditContactFragment extends Fragment { private void addNewNumber() { if (isNewContact) { if (isSipAddress) { - ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) - .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) - .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE) - .withValue(ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS, newNumberOrAddress) - .withValue(ContactsContract.CommonDataKinds.SipAddress.TYPE, ContactsContract.CommonDataKinds.SipAddress.TYPE_CUSTOM) - .withValue(ContactsContract.CommonDataKinds.SipAddress.LABEL, getString(R.string.addressbook_label)) - .build() - ); + Compatibility.addSipAddressToContact(getActivity(), ops, newNumberOrAddress); } else { ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) @@ -408,14 +395,7 @@ public class EditContactFragment extends Fragment { String rawContactId = findRawContactID(String.valueOf(contactID)); if (isSipAddress) { - ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) - .withValue(ContactsContract.Data.RAW_CONTACT_ID, rawContactId) - .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE) - .withValue(ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS, newNumberOrAddress) - .withValue(ContactsContract.CommonDataKinds.SipAddress.TYPE, ContactsContract.CommonDataKinds.SipAddress.TYPE_CUSTOM) - .withValue(ContactsContract.CommonDataKinds.SipAddress.LABEL, getString(R.string.addressbook_label)) - .build() - ); + Compatibility.addSipAddressToContact(getActivity(), ops, newNumberOrAddress, rawContactId); } else { ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) .withValue(ContactsContract.Data.RAW_CONTACT_ID, rawContactId) @@ -431,17 +411,7 @@ public class EditContactFragment extends Fragment { private void updateNumber() { if (isSipAddress) { - String select = ContactsContract.Data.CONTACT_ID + "=? AND " - + ContactsContract.Data.MIMETYPE + "='" + ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE + "' AND " - + ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS + "=?"; - String[] args = new String[] { String.valueOf(contactID), oldNumberOrAddress }; - - ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI) - .withSelection(select, args) - .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE) - .withValue(ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS, newNumberOrAddress) - .build() - ); + Compatibility.updateSipAddressForContact(ops, oldNumberOrAddress, newNumberOrAddress, String.valueOf(contactID)); } else { String select = ContactsContract.Data.CONTACT_ID + "=? AND " + ContactsContract.Data.MIMETYPE + "='" + ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE + "' AND " diff --git a/src/org/linphone/compatibility/ApiFivePlus.java b/src/org/linphone/compatibility/ApiFivePlus.java index 986b469c7..6adde17b9 100644 --- a/src/org/linphone/compatibility/ApiFivePlus.java +++ b/src/org/linphone/compatibility/ApiFivePlus.java @@ -15,6 +15,7 @@ import android.annotation.TargetApi; import android.app.Activity; import android.app.Notification; import android.app.PendingIntent; +import android.content.ContentProviderOperation; import android.content.ContentResolver; import android.content.ContentUris; import android.content.ContentValues; @@ -372,4 +373,52 @@ public class ApiFivePlus { ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE); clipboard.setText(msg); } + + public static void addSipAddressToContact(Context context, ArrayList ops, String sipAddress) { + ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) + .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) + .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE) + .withValue(ContactsContract.CommonDataKinds.Im.DATA, sipAddress) + .withValue(ContactsContract.CommonDataKinds.Im.TYPE, ContactsContract.CommonDataKinds.Im.TYPE_CUSTOM) + .withValue(ContactsContract.CommonDataKinds.Im.LABEL, context.getString(R.string.addressbook_label)) + .build() + ); + } + + public static void addSipAddressToContact(Context context, ArrayList ops, String sipAddress, String rawContactID) { + ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) + .withValue(ContactsContract.Data.RAW_CONTACT_ID, rawContactID) + .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE) + .withValue(ContactsContract.CommonDataKinds.Im.DATA, sipAddress) + .withValue(ContactsContract.CommonDataKinds.Im.TYPE, ContactsContract.CommonDataKinds.Im.TYPE_CUSTOM) + .withValue(ContactsContract.CommonDataKinds.Im.LABEL, context.getString(R.string.addressbook_label)) + .build() + ); + } + + public static void updateSipAddressForContact(ArrayList ops, String oldSipAddress, String newSipAddress, String contactID) { + String select = ContactsContract.Data.CONTACT_ID + "=? AND " + + ContactsContract.Data.MIMETYPE + "='" + ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE + "' AND " + + ContactsContract.CommonDataKinds.Im.DATA + "=?"; + String[] args = new String[] { String.valueOf(contactID), oldSipAddress }; + + ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI) + .withSelection(select, args) + .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE) + .withValue(ContactsContract.CommonDataKinds.Im.DATA, newSipAddress) + .build() + ); + } + + public static void deleteSipAddressFromContact(ArrayList ops, String oldSipAddress, String contactID) { + String select = ContactsContract.Data.CONTACT_ID + "=? AND " + + ContactsContract.Data.MIMETYPE + "='" + ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE + "' AND " + + ContactsContract.CommonDataKinds.Im.DATA + "=?"; + String[] args = new String[] { String.valueOf(contactID), oldSipAddress }; + + ops.add(ContentProviderOperation.newDelete(ContactsContract.Data.CONTENT_URI) + .withSelection(select, args) + .build() + ); + } } diff --git a/src/org/linphone/compatibility/ApiNinePlus.java b/src/org/linphone/compatibility/ApiNinePlus.java new file mode 100644 index 000000000..1d462a313 --- /dev/null +++ b/src/org/linphone/compatibility/ApiNinePlus.java @@ -0,0 +1,83 @@ +package org.linphone.compatibility; + +import java.util.ArrayList; + +import org.linphone.R; + +import android.annotation.TargetApi; +import android.content.ContentProviderOperation; +import android.content.Context; +import android.provider.ContactsContract; + +/* +ApiNinePlus.java +Copyright (C) 2012 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +/** + * @author Sylvain Berfini + */ +@TargetApi(9) +public class ApiNinePlus { + + public static void addSipAddressToContact(Context context, ArrayList ops, String sipAddress) { + ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) + .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) + .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE) + .withValue(ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS, sipAddress) + .withValue(ContactsContract.CommonDataKinds.SipAddress.TYPE, ContactsContract.CommonDataKinds.SipAddress.TYPE_CUSTOM) + .withValue(ContactsContract.CommonDataKinds.SipAddress.LABEL, context.getString(R.string.addressbook_label)) + .build() + ); + } + + public static void addSipAddressToContact(Context context, ArrayList ops, String sipAddress, String rawContactID) { + ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) + .withValue(ContactsContract.Data.RAW_CONTACT_ID, rawContactID) + .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE) + .withValue(ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS, sipAddress) + .withValue(ContactsContract.CommonDataKinds.SipAddress.TYPE, ContactsContract.CommonDataKinds.SipAddress.TYPE_CUSTOM) + .withValue(ContactsContract.CommonDataKinds.SipAddress.LABEL, context.getString(R.string.addressbook_label)) + .build() + ); + } + + public static void updateSipAddressForContact(ArrayList ops, String oldSipAddress, String newSipAddress, String contactID) { + String select = ContactsContract.Data.CONTACT_ID + "=? AND " + + ContactsContract.Data.MIMETYPE + "='" + ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE + "' AND " + + ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS + "=?"; + String[] args = new String[] { String.valueOf(contactID), oldSipAddress }; + + ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI) + .withSelection(select, args) + .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE) + .withValue(ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS, newSipAddress) + .build() + ); + } + + public static void deleteSipAddressFromContact(ArrayList ops, String oldSipAddress, String contactID) { + String select = ContactsContract.Data.CONTACT_ID + "=? AND " + + ContactsContract.Data.MIMETYPE + "='" + ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE + "' AND " + + ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS + "=?"; + String[] args = new String[] { String.valueOf(contactID), oldSipAddress }; + + ops.add(ContentProviderOperation.newDelete(ContactsContract.Data.CONTENT_URI) + .withSelection(select, args) + .build() + ); + } +} diff --git a/src/org/linphone/compatibility/Compatibility.java b/src/org/linphone/compatibility/Compatibility.java index e286db7da..fef976bb7 100644 --- a/src/org/linphone/compatibility/Compatibility.java +++ b/src/org/linphone/compatibility/Compatibility.java @@ -18,6 +18,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ import java.io.InputStream; +import java.util.ArrayList; import java.util.List; import org.linphone.Contact; @@ -27,6 +28,7 @@ import org.linphone.mediastream.Version; import android.app.Activity; import android.app.Notification; import android.app.PendingIntent; +import android.content.ContentProviderOperation; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; @@ -40,76 +42,76 @@ import android.view.Display; */ public class Compatibility { public static void overridePendingTransition(Activity activity, int idAnimIn, int idAnimOut) { - if (Version.sdkAboveOrEqual(5)) { + if (Version.sdkAboveOrEqual(Version.API05_ECLAIR_20)) { ApiFivePlus.overridePendingTransition(activity, idAnimIn, idAnimOut); } } public static Intent prepareAddContactIntent(String displayName, String sipUri) { - if (Version.sdkAboveOrEqual(5)) { + if (Version.sdkAboveOrEqual(Version.API05_ECLAIR_20)) { return ApiFivePlus.prepareAddContactIntent(displayName, sipUri); } return null; } public static Intent prepareEditContactIntent(int id) { - if (Version.sdkAboveOrEqual(5)) { + if (Version.sdkAboveOrEqual(Version.API05_ECLAIR_20)) { return ApiFivePlus.prepareEditContactIntent(id); } return null; } public static Intent prepareEditContactIntentWithSipAddress(int id, String sipAddress) { - if (Version.sdkAboveOrEqual(5)) { + if (Version.sdkAboveOrEqual(Version.API05_ECLAIR_20)) { return ApiFivePlus.prepareEditContactIntentWithSipAddress(id, sipAddress); } return null; } public static List extractContactNumbersAndAddresses(String id, ContentResolver cr) { - if (Version.sdkAboveOrEqual(5)) { + if (Version.sdkAboveOrEqual(Version.API05_ECLAIR_20)) { return ApiFivePlus.extractContactNumbersAndAddresses(id, cr); } return null; } public static Cursor getContactsCursor(ContentResolver cr) { - if (Version.sdkAboveOrEqual(5)) { + if (Version.sdkAboveOrEqual(Version.API05_ECLAIR_20)) { return ApiFivePlus.getContactsCursor(cr); } return null; } public static Cursor getSIPContactsCursor(ContentResolver cr) { - if (Version.sdkAboveOrEqual(5)) { + if (Version.sdkAboveOrEqual(Version.API05_ECLAIR_20)) { return ApiFivePlus.getSIPContactsCursor(cr); } return null; } public static int getCursorDisplayNameColumnIndex(Cursor cursor) { - if (Version.sdkAboveOrEqual(5)) { + if (Version.sdkAboveOrEqual(Version.API05_ECLAIR_20)) { return ApiFivePlus.getCursorDisplayNameColumnIndex(cursor); } return -1; } public static Contact getContact(ContentResolver cr, Cursor cursor, int position) { - if (Version.sdkAboveOrEqual(5)) { + if (Version.sdkAboveOrEqual(Version.API05_ECLAIR_20)) { return ApiFivePlus.getContact(cr, cursor, position); } return null; } public static InputStream getContactPictureInputStream(ContentResolver cr, String id) { - if (Version.sdkAboveOrEqual(5)) { + if (Version.sdkAboveOrEqual(Version.API05_ECLAIR_20)) { return ApiFivePlus.getContactPictureInputStream(cr, id); } return null; } public static Uri findUriPictureOfContactAndSetDisplayName(LinphoneAddress address, ContentResolver cr) { - if (Version.sdkAboveOrEqual(5)) { + if (Version.sdkAboveOrEqual(Version.API05_ECLAIR_20)) { return ApiFivePlus.findUriPictureOfContactAndSetDisplayName(address, cr); } return null; @@ -126,7 +128,7 @@ public class Compatibility { if (Version.sdkAboveOrEqual(16)) { notif = ApiSixteenPlus.createMessageNotification(context, msgCount, msgSender, msg, contactIcon, intent); - } else if (Version.sdkAboveOrEqual(11)) { + } else if (Version.sdkAboveOrEqual(Version.API11_HONEYCOMB_30)) { notif = ApiElevenPlus.createMessageNotification(context, msgCount, msgSender, msg, contactIcon, intent); } else { notif = ApiFivePlus.createMessageNotification(context, title, msg, intent); @@ -139,7 +141,7 @@ public class Compatibility { if (Version.sdkAboveOrEqual(16)) { notif = ApiSixteenPlus.createInCallNotification(context, title, msg, iconID, contactIcon, contactName, intent); - } else if (Version.sdkAboveOrEqual(11)) { + } else if (Version.sdkAboveOrEqual(Version.API11_HONEYCOMB_30)) { notif = ApiElevenPlus.createInCallNotification(context, title, msg, iconID, contactIcon, contactName, intent); } else { notif = ApiFivePlus.createInCallNotification(context, title, msg, iconID, intent); @@ -148,14 +150,14 @@ public class Compatibility { } public static String refreshContactName(ContentResolver cr, String id) { - if (Version.sdkAboveOrEqual(5)) { + if (Version.sdkAboveOrEqual(Version.API05_ECLAIR_20)) { return ApiFivePlus.refreshContactName(cr, id); } return null; } public static int getRotation(Display display) { - if (Version.sdkStrictlyBelow(8)) { + if (Version.sdkStrictlyBelow(Version.API08_FROYO_22)) { return ApiFivePlus.getRotation(display); } else { return ApiEightPlus.getRotation(display); @@ -163,7 +165,7 @@ public class Compatibility { } public static void setNotificationLatestEventInfo(Notification notif, Context context, String title, String content, PendingIntent intent) { - if (Version.sdkAboveOrEqual(11)) { + if (Version.sdkAboveOrEqual(Version.API11_HONEYCOMB_30)) { ApiElevenPlus.setNotificationLatestEventInfo(notif, context, title, content, intent); } else { ApiFivePlus.setNotificationLatestEventInfo(notif, context, title, content, intent); @@ -171,7 +173,7 @@ public class Compatibility { } public static CompatibilityScaleGestureDetector getScaleGestureDetector(Context context, CompatibilityScaleGestureListener listener) { - if (Version.sdkAboveOrEqual(8)) { + if (Version.sdkAboveOrEqual(Version.API08_FROYO_22)) { CompatibilityScaleGestureDetector csgd = new CompatibilityScaleGestureDetector(context); csgd.setOnScaleListener(listener); return csgd; @@ -181,7 +183,7 @@ public class Compatibility { public static void setPreferenceChecked(Preference preference, boolean checked) { - if (Version.sdkAboveOrEqual(14)) { + if (Version.sdkAboveOrEqual(Version.API14_ICE_CREAM_SANDWICH_40)) { ApiFourteenPlus.setPreferenceChecked(preference, checked); } else { ApiFivePlus.setPreferenceChecked(preference, checked); @@ -189,7 +191,7 @@ public class Compatibility { } public static boolean isPreferenceChecked(Preference preference) { - if (Version.sdkAboveOrEqual(14)) { + if (Version.sdkAboveOrEqual(Version.API14_ICE_CREAM_SANDWICH_40)) { return ApiFourteenPlus.isPreferenceChecked(preference); } else { return ApiFivePlus.isPreferenceChecked(preference); @@ -197,16 +199,48 @@ public class Compatibility { } public static void initPushNotificationService(Context context) { - if (Version.sdkAboveOrEqual(8)) { + if (Version.sdkAboveOrEqual(Version.API08_FROYO_22)) { ApiEightPlus.initPushNotificationService(context); } } public static void copyTextToClipboard(Context context, String msg) { - if(Version.sdkAboveOrEqual(11)) { + if(Version.sdkAboveOrEqual(Version.API11_HONEYCOMB_30)) { ApiElevenPlus.copyTextToClipboard(context, msg); } else { ApiFivePlus.copyTextToClipboard(context, msg); } } + + public static void addSipAddressToContact(Context context, ArrayList ops, String sipAddress) { + if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) { + ApiNinePlus.addSipAddressToContact(context, ops, sipAddress); + } else { + ApiFivePlus.addSipAddressToContact(context, ops, sipAddress); + } + } + + public static void addSipAddressToContact(Context context, ArrayList ops, String sipAddress, String rawContactID) { + if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) { + ApiNinePlus.addSipAddressToContact(context, ops, sipAddress, rawContactID); + } else { + ApiFivePlus.addSipAddressToContact(context, ops, sipAddress, rawContactID); + } + } + + public static void updateSipAddressForContact(ArrayList ops, String oldSipAddress, String newSipAddress, String contactID) { + if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) { + ApiNinePlus.updateSipAddressForContact(ops, oldSipAddress, newSipAddress, contactID); + } else { + ApiFivePlus.updateSipAddressForContact(ops, oldSipAddress, newSipAddress, contactID); + } + } + + public static void deleteSipAddressFromContact(ArrayList ops, String oldSipAddress, String contactID) { + if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) { + ApiNinePlus.deleteSipAddressFromContact(ops, oldSipAddress, contactID); + } else { + ApiFivePlus.deleteSipAddressFromContact(ops, oldSipAddress, contactID); + } + } }