Compatilibity package created (need to be filed for API < 5)

This commit is contained in:
Sylvain Berfini 2012-06-22 16:02:30 +02:00
parent 5613cd79dd
commit 97ee310441
9 changed files with 268 additions and 119 deletions

View file

@ -2,7 +2,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.linphone"
android:versionCode="2000" android:versionName="2.0" android:installLocation="auto">
<uses-sdk android:minSdkVersion="5" android:targetSdkVersion="15"/>
<uses-sdk android:minSdkVersion="4" android:targetSdkVersion="15"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>

View file

@ -18,29 +18,21 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.linphone;
import java.util.ArrayList;
import java.util.List;
import org.linphone.compatibility.Compatibility;
import org.linphone.core.LinphoneAddress;
import org.linphone.mediastream.Version;
import org.linphone.ui.AddressText;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.SipAddress;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Contacts.Data;
import android.provider.ContactsContract.Intents.Insert;
import android.telephony.PhoneNumberUtils;
import android.text.TextUtils;
public final class ContactHelper {
private String username;
private String domain;
private ContentResolver resolver;
@ -78,28 +70,7 @@ public final class ContactHelper {
}
public static Intent prepareAddContactIntent(AddressText address) {
return prepareAddContactIntent(address.getDisplayedName(), address.getText().toString());
}
//FIXME : Require API 5+
public static Intent prepareAddContactIntent(String displayName, String sipUri) {
Intent intent = new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI);
intent.putExtra(ContactsContract.Intents.Insert.NAME, displayName);
if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) {
ArrayList<ContentValues> data = new ArrayList<ContentValues>();
ContentValues sipAddressRow = new ContentValues();
sipAddressRow.put(Data.MIMETYPE, SipAddress.CONTENT_ITEM_TYPE);
sipAddressRow.put(SipAddress.SIP_ADDRESS, sipUri);
data.add(sipAddressRow);
intent.putParcelableArrayListExtra(Insert.DATA, data);
} else {
// VoIP field not available, we store the address in the IM field
intent.putExtra(ContactsContract.Intents.Insert.IM_HANDLE, sipUri);
intent.putExtra(ContactsContract.Intents.Insert.IM_PROTOCOL, "sip");
}
return intent;
return Compatibility.prepareAddContactIntent(address.getDisplayedName(), address.getText().toString());
}
public static Intent prepareEditContactIntent(int id) {
@ -273,48 +244,4 @@ public final class ContactHelper {
return false;
}
}
public static List<String> extractContactNumbersAndAddresses(String id, ContentResolver cr) {
List<String> list = new ArrayList<String>();
Uri uri = ContactsContract.Data.CONTENT_URI;
String[] projection = {ContactsContract.CommonDataKinds.Im.DATA};
if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) {
String selection = new StringBuilder()
.append(ContactsContract.Data.CONTACT_ID)
.append(" = ? AND ")
.append(ContactsContract.Data.MIMETYPE)
.append(" = '")
.append(ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE)
.append("'")
.toString();
projection = new String[] {ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS};
Cursor c = cr.query(uri, projection, selection, new String[]{id}, null);
int nbId = c.getColumnIndex(ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS);
while (c.moveToNext()) {
list.add("sip:" + c.getString(nbId));
}
c.close();
} else {
String selection = new StringBuilder()
.append(ContactsContract.Data.CONTACT_ID).append(" = ? AND ")
.append(ContactsContract.Data.MIMETYPE).append(" = '")
.append(ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE)
.append("' AND lower(")
.append(ContactsContract.CommonDataKinds.Im.CUSTOM_PROTOCOL)
.append(") = 'sip'")
.toString();
Cursor c = cr.query(uri, projection, selection, new String[]{id}, null);
int nbId = c.getColumnIndex(ContactsContract.CommonDataKinds.Im.DATA);
while (c.moveToNext()) {
list.add("sip:" + c.getString(nbId));
}
c.close();
}
return list;
}
}

View file

@ -21,7 +21,8 @@ import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import android.content.ContentUris;
import org.linphone.compatibility.Compatibility;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
@ -94,7 +95,7 @@ public class ContactsFragment extends Fragment implements OnClickListener, OnIte
onlyDisplayLinphoneCalls = true;
}
else if (id == R.id.newContact) {
Intent intent = ContactHelper.prepareAddContactIntent(null, null);
Intent intent = Compatibility.prepareAddContactIntent(null, null);
startActivity(intent);
}
}
@ -112,21 +113,22 @@ public class ContactsFragment extends Fragment implements OnClickListener, OnIte
LinphoneActivity.instance().selectMenu(FragmentsAvailable.CONTACTS);
}
cursor = getActivity().getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null, ContactsContract.Contacts.DISPLAY_NAME + " IS NOT NULL", null, ContactsContract.Contacts.DISPLAY_NAME + " ASC");
if (contactsList.getAdapter() == null) {
cursor = Compatibility.getContactsCursor(getActivity().getContentResolver());
contactsList.setAdapter(new ContactsListAdapter());
contactsList.setFastScrollEnabled(true);
}
contacts = new ArrayList<Contact>();
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < cursor.getCount(); i++) {
Contact contact = getContact(i);
contacts.add(contact);
contacts = new ArrayList<Contact>();
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < cursor.getCount(); i++) {
Contact contact = getContact(i);
contacts.add(contact);
}
}
}
}).start();
}).start();
}
contactsList.setSelectionFromTop(lastKnownPosition, 0);
}
@ -138,11 +140,10 @@ public class ContactsFragment extends Fragment implements OnClickListener, OnIte
return null;
String id = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
Uri person = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, Long.parseLong(id));
Uri photo = Uri.withAppendedPath(person, ContactsContract.Contacts.Photo.CONTENT_DIRECTORY);
String name = Compatibility.getContactDisplayName(cursor);
Uri photo = Compatibility.getContactPictureUri(cursor, id);
InputStream input = Compatibility.getContactPictureInputStream(getActivity().getContentResolver(), id);
InputStream input = ContactsContract.Contacts.openContactPhotoInputStream(getActivity().getContentResolver(), person);
Contact contact;
if (input == null) {
contact = new Contact(id, name);
@ -151,7 +152,7 @@ public class ContactsFragment extends Fragment implements OnClickListener, OnIte
contact = new Contact(id, name, photo, BitmapFactory.decodeStream(input));
}
contact.setNumerosOrAddresses(ContactHelper.extractContactNumbersAndAddresses(contact.getID(), getActivity().getContentResolver()));
contact.setNumerosOrAddresses(Compatibility.extractContactNumbersAndAddresses(contact.getID(), getActivity().getContentResolver()));
return contact;
}
@ -162,7 +163,7 @@ public class ContactsFragment extends Fragment implements OnClickListener, OnIte
private Bitmap bitmapUnknown;
ContactsListAdapter() {
indexer = new AlphabetIndexer(cursor, cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME), " ABCDEFGHIJKLMNOPQRSTUVWXYZ");
indexer = new AlphabetIndexer(cursor, Compatibility.getCursorDisplayNameColumnIndex(cursor), " ABCDEFGHIJKLMNOPQRSTUVWXYZ");
margin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, getResources().getDisplayMetrics());
bitmapUnknown = BitmapFactory.decodeResource(getResources(), R.drawable.unknown_small);
}

View file

@ -17,6 +17,8 @@ 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.
*/
import org.linphone.compatibility.Compatibility;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
@ -97,7 +99,7 @@ public class HistoryDetailFragment extends Fragment implements OnClickListener {
} else if (id == R.id.chat) {
LinphoneActivity.instance().displayChat(sipUri);
} else if (id == R.id.addToContacts) {
Intent intent = ContactHelper.prepareAddContactIntent(displayName, sipUri);
Intent intent = Compatibility.prepareAddContactIntent(displayName, sipUri);
startActivity(intent);
}
}

View file

@ -27,6 +27,7 @@ import java.util.List;
import org.linphone.LinphoneSimpleListener.LinphoneOnCallStateChangedListener;
import org.linphone.LinphoneSimpleListener.LinphoneOnMessageReceived;
import org.linphone.LinphoneSimpleListener.LinphoneOnRegistrationStateChangedListener;
import org.linphone.compatibility.Compatibility;
import org.linphone.core.CallDirection;
import org.linphone.core.LinphoneAddress;
import org.linphone.core.LinphoneCall;
@ -301,11 +302,10 @@ public class LinphoneActivity extends FragmentActivity implements OnClickListene
Intent intent = new Intent(ACTION_MAIN);
intent.setClass(this, PreferencesActivity.class);
startActivityForResult(intent, SETTINGS_ACTIVITY);
//FIXME : Require API 5+
if (FragmentsAvailable.SETTINGS.isRightOf(currentFragment)) {
overridePendingTransition(R.anim.slide_in_right_to_left, R.anim.slide_out_right_to_left);
Compatibility.overridePendingTransition(R.anim.slide_in_right_to_left, R.anim.slide_out_right_to_left);
} else {
overridePendingTransition(R.anim.slide_in_left_to_right, R.anim.slide_out_left_to_right);
Compatibility.overridePendingTransition(R.anim.slide_in_left_to_right, R.anim.slide_out_left_to_right);
}
// }
}

View file

@ -17,6 +17,8 @@ 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.
*/
import org.linphone.compatibility.Compatibility;
import android.content.Intent;
import android.os.Bundle;
import android.preference.PreferenceActivity;
@ -112,13 +114,12 @@ public class LinphonePreferencesActivity extends PreferenceActivity implements O
}
}
//FIXME : Require API 5+
private void finishWithCustomAnimation(FragmentsAvailable newFragment) {
finish();
if (FragmentsAvailable.SETTINGS.isRightOf(newFragment)) {
overridePendingTransition(R.anim.slide_in_left_to_right, R.anim.slide_out_left_to_right);
Compatibility.overridePendingTransition(R.anim.slide_in_left_to_right, R.anim.slide_out_left_to_right);
} else {
overridePendingTransition(R.anim.slide_in_right_to_left, R.anim.slide_out_right_to_left);
Compatibility.overridePendingTransition(R.anim.slide_in_right_to_left, R.anim.slide_out_right_to_left);
}
}

View file

@ -161,21 +161,6 @@ public class PreferencesActivity extends LinphonePreferencesActivity implements
parent.addPreference(me);
}
private void fillLinphoneAccount(int i, String username, String password, boolean createdByWizard) {
SharedPreferences prefs = getPreferenceManager().getSharedPreferences();
SharedPreferences.Editor editor = prefs.edit();
editor.putString(getString(R.string.pref_username_key) + i, username);
editor.putString(getString(R.string.pref_passwd_key) + i, password);
editor.putString(getString(R.string.pref_domain_key) + i, "sip.linphone.org");
editor.putString(getString(R.string.pref_proxy_key) + i, "");
editor.putBoolean(getString(R.string.pref_wizard_key) + i, createdByWizard);
editor.putBoolean(getString(R.string.pref_activated_key) + i, false);
editor.putBoolean(getString(R.string.pref_enable_outbound_proxy_key) + i, false);
editor.commit();
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == ADD_SIP_ACCOUNT) {
//Verify if last created account is filled

View file

@ -0,0 +1,132 @@
package org.linphone.compatibility;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import org.linphone.mediastream.Version;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.SipAddress;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Contacts.Data;
import android.provider.ContactsContract.Intents.Insert;
/*
ApiFivePlus.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
*/
public class ApiFivePlus {
public static void overridePendingTransition(int idAnimIn, int idAnimOut) {
overridePendingTransition(idAnimIn, idAnimOut);
}
public static Intent prepareAddContactIntent(String displayName, String sipUri) {
Intent intent = new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI);
intent.putExtra(ContactsContract.Intents.Insert.NAME, displayName);
if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) {
ArrayList<ContentValues> data = new ArrayList<ContentValues>();
ContentValues sipAddressRow = new ContentValues();
sipAddressRow.put(Data.MIMETYPE, SipAddress.CONTENT_ITEM_TYPE);
sipAddressRow.put(SipAddress.SIP_ADDRESS, sipUri);
data.add(sipAddressRow);
intent.putParcelableArrayListExtra(Insert.DATA, data);
} else {
// VoIP field not available, we store the address in the IM field
intent.putExtra(ContactsContract.Intents.Insert.IM_HANDLE, sipUri);
intent.putExtra(ContactsContract.Intents.Insert.IM_PROTOCOL, "sip");
}
return intent;
}
public static List<String> extractContactNumbersAndAddresses(String id, ContentResolver cr) {
List<String> list = new ArrayList<String>();
Uri uri = ContactsContract.Data.CONTENT_URI;
String[] projection = {ContactsContract.CommonDataKinds.Im.DATA};
if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) {
String selection = new StringBuilder()
.append(ContactsContract.Data.CONTACT_ID)
.append(" = ? AND ")
.append(ContactsContract.Data.MIMETYPE)
.append(" = '")
.append(ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE)
.append("'")
.toString();
projection = new String[] {ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS};
Cursor c = cr.query(uri, projection, selection, new String[]{id}, null);
int nbId = c.getColumnIndex(ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS);
while (c.moveToNext()) {
list.add("sip:" + c.getString(nbId));
}
c.close();
} else {
String selection = new StringBuilder()
.append(ContactsContract.Data.CONTACT_ID).append(" = ? AND ")
.append(ContactsContract.Data.MIMETYPE).append(" = '")
.append(ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE)
.append("' AND lower(")
.append(ContactsContract.CommonDataKinds.Im.CUSTOM_PROTOCOL)
.append(") = 'sip'")
.toString();
Cursor c = cr.query(uri, projection, selection, new String[]{id}, null);
int nbId = c.getColumnIndex(ContactsContract.CommonDataKinds.Im.DATA);
while (c.moveToNext()) {
list.add("sip:" + c.getString(nbId));
}
c.close();
}
return list;
}
public static Cursor getContactsCursor(ContentResolver cr) {
return cr.query(ContactsContract.Contacts.CONTENT_URI, null, ContactsContract.Contacts.DISPLAY_NAME + " IS NOT NULL", null, ContactsContract.Contacts.DISPLAY_NAME + " ASC");
}
public static String getContactDisplayName(Cursor cursor) {
return cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
}
public static Uri getContactPictureUri(Cursor cursor, String id) {
Uri person = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, Long.parseLong(id));
return Uri.withAppendedPath(person, ContactsContract.Contacts.Photo.CONTENT_DIRECTORY);
}
public static InputStream getContactPictureInputStream(ContentResolver cr, String id) {
Uri person = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, Long.parseLong(id));
return ContactsContract.Contacts.openContactPhotoInputStream(cr, person);
}
public static int getCursorDisplayNameColumnIndex(Cursor cursor) {
return cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
}
}

View file

@ -0,0 +1,101 @@
package org.linphone.compatibility;
/*
Compatibility.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.
*/
import java.io.InputStream;
import java.util.List;
import org.linphone.mediastream.Version;
import android.content.ContentResolver;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
/**
* @author Sylvain Berfini
*/
public class Compatibility {
public static void overridePendingTransition(int idAnimIn, int idAnimOut) {
if (Version.sdkAboveOrEqual(5)) {
ApiFivePlus.overridePendingTransition(idAnimIn, idAnimOut);
}
}
public static Intent prepareAddContactIntent(String displayName, String sipUri) {
if (Version.sdkAboveOrEqual(5)) {
return ApiFivePlus.prepareAddContactIntent(displayName, sipUri);
} else {
//TODO
}
return null;
}
public static List<String> extractContactNumbersAndAddresses(String id, ContentResolver cr) {
if (Version.sdkAboveOrEqual(5)) {
return ApiFivePlus.extractContactNumbersAndAddresses(id, cr);
} else {
//TODO
}
return null;
}
public static Cursor getContactsCursor(ContentResolver cr) {
if (Version.sdkAboveOrEqual(5)) {
return ApiFivePlus.getContactsCursor(cr);
} else {
//TODO
}
return null;
}
public static String getContactDisplayName(Cursor cursor) {
if (Version.sdkAboveOrEqual(5)) {
return ApiFivePlus.getContactDisplayName(cursor);
} else {
//TODO
}
return null;
}
public static Uri getContactPictureUri(Cursor cursor, String id) {
if (Version.sdkAboveOrEqual(5)) {
return ApiFivePlus.getContactPictureUri(cursor, id);
} else {
//TODO
}
return null;
}
public static InputStream getContactPictureInputStream(ContentResolver cr, String id) {
if (Version.sdkAboveOrEqual(5)) {
return ApiFivePlus.getContactPictureInputStream(cr, id);
} else {
//TODO
}
return null;
}
public static int getCursorDisplayNameColumnIndex(Cursor cursor) {
if (Version.sdkAboveOrEqual(5)) {
return ApiFivePlus.getCursorDisplayNameColumnIndex(cursor);
} else {
//TODO
}
return -1;
}
}