diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 270d32c36..64166c3fd 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -3,11 +3,12 @@
package="org.linphone"
android:versionCode="1104" android:versionName="1.1.4" android:installLocation="auto">
-
+
+
+
-
+
+
+
+
+
+
+
@@ -53,7 +61,12 @@
-
+
+
+
+
+
+
diff --git a/res/layout/contact_picker.xml b/res/layout/contact_picker.xml
new file mode 100644
index 000000000..9ad7a12e1
--- /dev/null
+++ b/res/layout/contact_picker.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
diff --git a/src/org/linphone/ContactPickerActivityNew.java b/src/org/linphone/ContactPickerActivityNew.java
new file mode 100644
index 000000000..e3a06fe60
--- /dev/null
+++ b/src/org/linphone/ContactPickerActivityNew.java
@@ -0,0 +1,271 @@
+/*
+ContactPickerActivity.java
+Copyright (C) 2010 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.
+ */
+package org.linphone;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.ContactsContract;
+import android.text.Editable;
+import android.text.TextUtils;
+import android.text.TextWatcher;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.EditText;
+import android.widget.FilterQueryProvider;
+import android.widget.ListView;
+import android.widget.SimpleCursorAdapter;
+import android.widget.TextView;
+import android.widget.Toast;
+import android.widget.AdapterView.OnItemClickListener;
+
+
+/**
+ * Activity for retrieving a phone number / SIP address to call.
+ *
+ *
+ * The cinematic is:
+ *
+ * - Select contact (either through native or custom way)
+ * - Select phone number or SIP address
+ *
- Back to dialer
+ *
+ *
+ * @author Guillaume Beraudo
+ *
+ */
+public class ContactPickerActivityNew extends Activity implements FilterQueryProvider {
+
+ private ListView mContactList;
+ private EditText mcontactFilter;
+
+ private SimpleCursorAdapter adapter;
+ private boolean useNativePicker;
+
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ useNativePicker = getResources().getBoolean(R.bool.use_android_contact_picker);
+
+ if (!useNativePicker) {
+ setContentView(R.layout.contact_picker);
+ createPicker();
+ }
+ }
+
+
+
+ private void createPicker() {
+ mContactList = (ListView) findViewById(R.id.contactList);
+
+ mcontactFilter = (EditText) findViewById(R.id.contactFilter);
+ mcontactFilter.addTextChangedListener(new TextWatcher() {
+ public void onTextChanged(CharSequence s, int start, int b, int c) {}
+ public void beforeTextChanged(CharSequence s, int st, int c, int a) {}
+
+ public void afterTextChanged(Editable s) {
+ adapter.runQueryOnBackgroundThread(s);
+ adapter.getFilter().filter(s.toString());
+ }
+ });
+
+
+ // Populate the contact list
+ String[] from = new String[] {ContactsContract.Data.DISPLAY_NAME};
+ int[] to = new int[] {android.R.id.text1};
+ int layout = android.R.layout.simple_list_item_1;
+ adapter = new SimpleCursorAdapter(this, layout, runQuery(null), from, to);
+ adapter.setFilterQueryProvider(this);
+ mContactList.setAdapter(adapter);
+
+ mContactList.setOnItemClickListener(new OnItemClickListener() {
+ public void onItemClick(AdapterView> parent, View view, int position, long id) {
+ final CharSequence contactName = ((TextView) view.findViewById(android.R.id.text1)).getText();
+ choosePhoneNumberAndDial(contactName, String.valueOf(id));
+ }
+ });
+ }
+
+
+
+ private void choosePhoneNumberAndDial(final CharSequence contactName, final String id) {
+ List phones = extractPhones(id);
+ phones.addAll(extractSipNumbers(id));
+
+ switch (phones.size()) {
+ case 0:
+ String msg = String.format(getString(R.string.no_phone_numbers), contactName);
+ Toast.makeText(ContactPickerActivityNew.this, msg, Toast.LENGTH_LONG).show();
+ break;
+ case 1:
+ returnSelectedValues(phones.get(0), contactName.toString());
+ break;
+ default:
+ AlertDialog.Builder builder = new AlertDialog.Builder(ContactPickerActivityNew.this);
+
+ final ArrayAdapter pAdapter = new ArrayAdapter(ContactPickerActivityNew.this,
+ android.R.layout.simple_dropdown_item_1line, phones);
+
+ builder.setTitle(String.format(getString(R.string.title_numbers_dialog),contactName));
+ builder.setAdapter(pAdapter, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ returnSelectedValues(pAdapter.getItem(which), contactName.toString());
+ }
+ });
+ builder.setCancelable(true);
+ builder.setNeutralButton("cancel", new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ dialog.dismiss();
+ }
+ });
+ AlertDialog dialog = builder.create();
+ dialog.show();
+ }
+ }
+
+ private void returnSelectedValues(String number, String name) {
+/* if (getCallingActivity() != null) {
+ setResult(RESULT_OK, new Intent()
+ .putExtra(Intent.EXTRA_PHONE_NUMBER, number)
+ .putExtra(EXTRA_CONTACT_NAME, name));
+ finish();
+ }*/
+
+ LinphoneActivity.setAddressAndGoToDialer(number, name);
+ }
+
+
+ private List extractPhones(String id) {
+ List list = new ArrayList();
+ Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
+ String selection = ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?";
+ String[] selArgs = new String[] {id};
+ Cursor c = this.getContentResolver().query(uri, null, selection, selArgs, null);
+
+ int nbId = c.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
+
+ while (c.moveToNext()) {
+ list.add(c.getString(nbId));
+ }
+
+ c.close();
+
+ return list;
+ }
+
+ private List extractSipNumbers(String id) {
+ List list = new ArrayList();
+ Uri uri = ContactsContract.Data.CONTENT_URI;
+ String selection = new StringBuilder()
+ .append(ContactsContract.Data.CONTACT_ID).append(" = ? AND ")
+ .append(ContactsContract.Data.MIMETYPE).append(" = ? ")
+ .append(" AND lower(")
+ .append(ContactsContract.CommonDataKinds.Im.CUSTOM_PROTOCOL)
+ .append(") = 'sip'").toString();
+ String[] selArgs = new String[] {id, ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE};
+ Cursor c = this.getContentResolver().query(uri, null, selection, selArgs, null);
+
+ int nbId = c.getColumnIndex(ContactsContract.CommonDataKinds.Im.DATA);
+
+ while (c.moveToNext()) {
+ list.add("sip:" + c.getString(nbId));
+ }
+
+ c.close();
+
+ return list;
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+
+ if (useNativePicker) {
+ Uri uri = ContactsContract.Contacts.CONTENT_URI;
+ //ContactsContract.CommonDataKinds.Phone.CONTENT_URI
+ startActivityForResult(new Intent(Intent.ACTION_PICK, uri), 0);
+ }
+ }
+
+ protected void onActivityResult(int reqCode, int resultCode, Intent intent) {
+ // If using native picker
+ if (reqCode == 0) {
+ if (resultCode == RESULT_OK) {
+ String id = intent.getData().getLastPathSegment();
+ String contactName = intent.getStringExtra(Intent.EXTRA_SHORTCUT_NAME);
+ if (contactName == null)
+ contactName = retrieveContactName(id);
+ choosePhoneNumberAndDial(contactName, id);
+ }
+ }
+
+ LinphoneActivity.instance().getTabHost().setCurrentTabByTag(LinphoneActivity.DIALER_TAB);
+ }
+
+
+ private String retrieveContactName(String id) {
+ Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
+ String selection = ContactsContract.CommonDataKinds.Phone._ID + " = ?";
+ String[] selArgs = new String[] {id};
+ Cursor c = this.getContentResolver().query(uri, null, selection, selArgs, null);
+
+ String name = "";
+ if (c.moveToFirst()) {
+ name = c.getString(c.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
+ }
+ c.close();
+
+ return name;
+ }
+
+
+
+ public Cursor runQuery(CharSequence constraint) {
+ // Run query
+ Uri uri = ContactsContract.Contacts.CONTENT_URI;
+ String[] projection = new String[] {
+ ContactsContract.Contacts._ID,
+ ContactsContract.Contacts.DISPLAY_NAME
+ };
+ String selection =
+ ContactsContract.Contacts.IN_VISIBLE_GROUP + " = '1' and "
+ + ContactsContract.Contacts.HAS_PHONE_NUMBER + " = '1'";
+ String[] selectionArgs = null;
+ if (!TextUtils.isEmpty(constraint)) {
+ // FIXME absolutely unsecure
+ selection += " and " + ContactsContract.Contacts.DISPLAY_NAME + " ilike '%"+mcontactFilter.getText()+"%'";
+ }
+
+ String sortOrder = ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC";
+
+ return managedQuery(uri, projection, selection, selectionArgs, sortOrder);
+ }
+
+
+}
diff --git a/src/org/linphone/ContactPickerActivity.java b/src/org/linphone/ContactPickerActivityOld.java
similarity index 96%
rename from src/org/linphone/ContactPickerActivity.java
rename to src/org/linphone/ContactPickerActivityOld.java
index 99604ef6c..943587781 100644
--- a/src/org/linphone/ContactPickerActivity.java
+++ b/src/org/linphone/ContactPickerActivityOld.java
@@ -25,8 +25,8 @@ import android.os.Bundle;
import android.provider.Contacts;
import android.provider.Contacts.People;
-
-public class ContactPickerActivity extends Activity {
+@SuppressWarnings("deprecation")
+public class ContactPickerActivityOld extends Activity {
static final int PICK_CONTACT_REQUEST = 0;
static final int PICK_PHONE_NUMBER_REQUEST = 1;
diff --git a/src/org/linphone/HistoryActivity.java b/src/org/linphone/HistoryActivity.java
index 86eb2bc82..a4d958e12 100644
--- a/src/org/linphone/HistoryActivity.java
+++ b/src/org/linphone/HistoryActivity.java
@@ -59,12 +59,12 @@ public class HistoryActivity extends ListActivity {
TextView lSecondLineView = (TextView) v.findViewById(R.id.history_cell_second_line);
if (lSecondLineView.getVisibility() == View.GONE) {
// no display name
- DialerActivity.instance().setContactAddress(lFirstLineView.getText().toString(), null);
+ LinphoneActivity.setAddressAndGoToDialer(lFirstLineView.getText().toString(), null);
} else {
- DialerActivity.instance().setContactAddress(lSecondLineView.getText().toString()
- ,lFirstLineView.getText().toString());
+ LinphoneActivity.setAddressAndGoToDialer(
+ lSecondLineView.getText().toString(),
+ lFirstLineView.getText().toString());
}
- LinphoneActivity.instance().getTabHost().setCurrentTabByTag(LinphoneActivity.DIALER_TAB);
}
diff --git a/src/org/linphone/LinphoneActivity.java b/src/org/linphone/LinphoneActivity.java
index 3999e2d90..8a44b9ac6 100644
--- a/src/org/linphone/LinphoneActivity.java
+++ b/src/org/linphone/LinphoneActivity.java
@@ -1,5 +1,5 @@
/*
-LinphoneActivity.java
+iLinphoneActivity.java
Copyright (C) 2010 Belledonne Communications, Grenoble, France
This program is free software; you can redistribute it and/or
@@ -74,6 +74,7 @@ public class LinphoneActivity extends TabActivity {
private FrameLayout mMainFrame;
private SensorManager mSensorManager;
private static SensorEventListener mSensorEventListener;
+ private static String TAG = LinphoneManager.TAG;
private static final String SCREEN_IS_HIDDEN ="screen_is_hidden";
@@ -155,7 +156,7 @@ public class LinphoneActivity extends TabActivity {
}
});
} catch (LinphoneCoreException e) {
- Log.e(LinphoneManager.TAG, "Unable to calibrate EC", e);
+ Log.e(TAG, "Unable to calibrate EC", e);
}
fillTabHost();
@@ -197,7 +198,8 @@ public class LinphoneActivity extends TabActivity {
// Contact picker
- tabIntent = new Intent().setClass(this, ContactPickerActivity.class);
+ tabIntent = new Intent().setClass(this, Version.sdkAboveOrEqual(5) ?
+ ContactPickerActivityNew.class : ContactPickerActivityOld.class);
indicator = getString(R.string.tab_contact);
tabDrawable = getResources().getDrawable(R.drawable.contact_orange);
spec = lTabHost.newTabSpec("contact")
@@ -212,14 +214,17 @@ public class LinphoneActivity extends TabActivity {
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
- if (intent.getData() != null) {
- if (DialerActivity.instance() != null) {
- DialerActivity.instance().newOutgoingCall(intent);
- } else {
- Toast.makeText(this, getString(R.string.dialer_null_on_new_intent), Toast.LENGTH_LONG).show();
- }
- }
+ if (intent.getData() == null) {
+ Log.e(TAG, "LinphoneActivity received an intent without data, discarding");
+ return;
+ }
+
+ if (DialerActivity.instance() != null) {
+ DialerActivity.instance().newOutgoingCall(intent);
+ } else {
+ Toast.makeText(this, getString(R.string.dialer_null_on_new_intent), Toast.LENGTH_LONG).show();
+ }
}
@Override
protected void onPause() {
@@ -264,7 +269,7 @@ public class LinphoneActivity extends TabActivity {
startActivity(new Intent(ACTION_MAIN)
.setClass(this, AboutActivity.class));
default:
- Log.e(LinphoneManager.TAG, "Unknown menu item ["+item+"]");
+ Log.e(TAG, "Unknown menu item ["+item+"]");
break;
}
@@ -293,14 +298,14 @@ public class LinphoneActivity extends TabActivity {
synchronized void startProxymitySensor() {
if (mSensorEventListener != null) {
- Log.i(LinphoneManager.TAG, "proximity sensor already active");
+ Log.i(TAG, "proximity sensor already active");
return;
}
List lSensorList = mSensorManager.getSensorList(Sensor.TYPE_PROXIMITY);
mSensorEventListener = new SensorEventListener() {
public void onSensorChanged(SensorEvent event) {
if (event.timestamp == 0) return; //just ignoring for nexus 1
- Log.d(LinphoneManager.TAG, "Proximity sensor report ["+event.values[0]+"] , for max range ["+event.sensor.getMaximumRange()+"]");
+ Log.d(TAG, "Proximity sensor report ["+event.values[0]+"] , for max range ["+event.sensor.getMaximumRange()+"]");
if (event.values[0] != event.sensor.getMaximumRange() ) {
instance().hideScreen(true);
@@ -313,7 +318,7 @@ public class LinphoneActivity extends TabActivity {
};
if (lSensorList.size() >0) {
mSensorManager.registerListener(mSensorEventListener,lSensorList.get(0),SensorManager.SENSOR_DELAY_UI);
- Log.i(LinphoneManager.TAG, "Proximity sensor detected, registering");
+ Log.i(TAG, "Proximity sensor detected, registering");
}
}
@@ -420,5 +425,10 @@ public class LinphoneActivity extends TabActivity {
builder.create().show();
}
+
+ public static void setAddressAndGoToDialer(String number, String name) {
+ DialerActivity.instance().setContactAddress(number, name);
+ instance.getTabHost().setCurrentTabByTag(DIALER_TAB);
+ }
}