Implement Android dialer integration
This commit is contained in:
parent
e41ca841fa
commit
ac7944f668
11 changed files with 173 additions and 55 deletions
|
@ -13,6 +13,11 @@
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
|
</intent-filter>
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.CALL" />
|
||||||
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
<data android:scheme="tel" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
<activity android:name=".LinphonePreferencesActivity">
|
<activity android:name=".LinphonePreferencesActivity">
|
||||||
|
@ -24,11 +29,7 @@
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
<intent-filter>
|
|
||||||
<action android:name="android.intent.action.CALL" />
|
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
|
||||||
<data android:scheme="tel" />
|
|
||||||
</intent-filter>
|
|
||||||
</activity>
|
</activity>
|
||||||
<activity android:name=".ContactPickerActivity">
|
<activity android:name=".ContactPickerActivity">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
|
@ -55,6 +56,10 @@
|
||||||
<intent-filter android:priority="0"><action android:name="android.intent.action.NEW_OUTGOING_CALL"></action>
|
<intent-filter android:priority="0"><action android:name="android.intent.action.NEW_OUTGOING_CALL"></action>
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</receiver>
|
</receiver>
|
||||||
|
<receiver android:name="BootReceiver" >
|
||||||
|
<intent-filter><action android:name="android.intent.action.BOOT_COMPLETED"></action>
|
||||||
|
</intent-filter>
|
||||||
|
</receiver>
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
|
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
|
||||||
|
@ -64,5 +69,8 @@
|
||||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||||
<uses-permission android:name="android.permission.WAKE_LOCK"/>
|
<uses-permission android:name="android.permission.WAKE_LOCK"/>
|
||||||
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"></uses-permission>
|
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"></uses-permission>
|
||||||
|
<uses-permission android:name="android.permission.CALL_PHONE"></uses-permission>
|
||||||
|
<uses-permission android:name="android.permission.BOOT_COMPLETED"></uses-permission>
|
||||||
|
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
Binary file not shown.
26
res/layout/outcall_choser.xml
Normal file
26
res/layout/outcall_choser.xml
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:padding="6dip" android:layout_height="wrap_content"
|
||||||
|
android:id="@+id/outcall_chooser_linear_v" android:layout_width="fill_parent"
|
||||||
|
android:gravity="center">
|
||||||
|
|
||||||
|
<LinearLayout android:id="@+id/LinearLayout02"
|
||||||
|
android:layout_height="wrap_content" android:layout_width="fill_parent"
|
||||||
|
android:layout_weight="0.5" android:gravity="center">
|
||||||
|
<ImageButton android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content" android:src="@drawable/logo_linphone_57x57"
|
||||||
|
android:id="@+id/outcall_chooser_linphone_button" android:background="@android:color/transparent"></ImageButton>
|
||||||
|
</LinearLayout>
|
||||||
|
<LinearLayout android:id="@+id/LinearLayout01"
|
||||||
|
android:layout_width="fill_parent" android:layout_weight=".5"
|
||||||
|
android:gravity="center" android:layout_height="fill_parent">
|
||||||
|
<Button android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content" android:text="@string/outcall_chooser_cellular"
|
||||||
|
android:layout_below="@+id/outcall_text" android:layout_alignRight="@+id/outcall_text"
|
||||||
|
android:id="@+id/outcall_chooser_cellular_button"></Button>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</LinearLayout>
|
|
@ -1,5 +1,12 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
|
<string name="pref_handle_outcall_summarry">If set cellular call are redirected to voip when possible</string>
|
||||||
|
<string name="pref_handle_outcall">Redirect cellular calls</string>
|
||||||
|
<string name="pref_handle_outcall_key">pref_handle_outcall_key</string>
|
||||||
|
<string name="pref_autostart">Start at boot time</string>
|
||||||
|
<string name="pref_autostart_key">pref_autostart_key</string>
|
||||||
|
<string name="outcall_chooser_cellular">Cellular</string>
|
||||||
|
<string name="outcall_chooser_text">Choose application to call %s</string>
|
||||||
<string name="pref_enable_outbound_proxy">Outbound proxy</string>
|
<string name="pref_enable_outbound_proxy">Outbound proxy</string>
|
||||||
<string name="pref_enable_outbound_proxy_key">Outbound proxy</string>
|
<string name="pref_enable_outbound_proxy_key">Outbound proxy</string>
|
||||||
<string name="pref_codec_pcma">pcma</string>
|
<string name="pref_codec_pcma">pcma</string>
|
||||||
|
|
|
@ -25,13 +25,15 @@
|
||||||
android:title="@string/pref_codec_pcmu" android:defaultValue="true"></CheckBoxPreference>
|
android:title="@string/pref_codec_pcmu" android:defaultValue="true"></CheckBoxPreference>
|
||||||
<CheckBoxPreference android:key="@string/pref_codec_pcma_key"
|
<CheckBoxPreference android:key="@string/pref_codec_pcma_key"
|
||||||
android:title="@string/pref_codec_pcma" android:defaultValue="true"></CheckBoxPreference>
|
android:title="@string/pref_codec_pcma" android:defaultValue="true"></CheckBoxPreference>
|
||||||
</PreferenceScreen>
|
</PreferenceScreen><CheckBoxPreference android:title="@string/pref_autostart" android:defaultValue="true" android:key="@string/pref_autostart_key"></CheckBoxPreference>
|
||||||
<EditTextPreference android:title="@string/pref_prefix"
|
<CheckBoxPreference android:title="@string/pref_handle_outcall" android:key="@string/pref_handle_outcall_key" android:summary="@string/pref_handle_outcall_summarry"></CheckBoxPreference><EditTextPreference android:title="@string/pref_prefix"
|
||||||
android:key="@string/pref_prefix_key"></EditTextPreference>
|
android:key="@string/pref_prefix_key"></EditTextPreference>
|
||||||
|
|
||||||
<CheckBoxPreference android:key="@string/pref_debug_key"
|
<CheckBoxPreference android:key="@string/pref_debug_key"
|
||||||
android:title="@string/pref_debug" android:enabled="true"></CheckBoxPreference>
|
android:title="@string/pref_debug" android:enabled="true"></CheckBoxPreference>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
|
||||||
</PreferenceScreen>
|
</PreferenceScreen>
|
||||||
|
|
39
src/org/linphone/BootReceiver.java
Normal file
39
src/org/linphone/BootReceiver.java
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
BootReceiver.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 android.content.BroadcastReceiver;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.preference.PreferenceManager;
|
||||||
|
|
||||||
|
public class BootReceiver extends BroadcastReceiver {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
|
||||||
|
if (PreferenceManager.getDefaultSharedPreferences(context).getBoolean(context.getString(R.string.pref_autostart_key), true)) {
|
||||||
|
Intent lLinphoneServiceIntent = new Intent(Intent.ACTION_MAIN);
|
||||||
|
lLinphoneServiceIntent.setClass(context, LinphoneService.class);
|
||||||
|
context.startService(lLinphoneServiceIntent);;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -158,31 +158,7 @@ public class DialerActivity extends Activity implements LinphoneCoreListener {
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (lLinphoneCore.isIncall()) {
|
newOutgoingCall(mAddress.getText().toString(),mDisplayName);
|
||||||
Toast toast = Toast.makeText(DialerActivity.this, getString(R.string.warning_already_incall), Toast.LENGTH_LONG);
|
|
||||||
toast.show();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
LinphoneAddress lAddress;
|
|
||||||
try {
|
|
||||||
lAddress = lLinphoneCore.interpretUrl( mAddress.getText().toString());
|
|
||||||
} catch (LinphoneCoreException e) {
|
|
||||||
Toast toast = Toast.makeText(DialerActivity.this
|
|
||||||
,String.format(getString(R.string.warning_wrong_destination_address),mAddress.getText().toString())
|
|
||||||
, Toast.LENGTH_LONG);
|
|
||||||
toast.show();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
lAddress.setDisplayName(mDisplayName);
|
|
||||||
try {
|
|
||||||
lLinphoneCore.invite(lAddress);
|
|
||||||
} catch (LinphoneCoreException e) {
|
|
||||||
Toast toast = Toast.makeText(DialerActivity.this
|
|
||||||
,String.format(getString(R.string.error_cannot_invite_address),mAddress.getText().toString())
|
|
||||||
, Toast.LENGTH_LONG);
|
|
||||||
toast.show();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -234,6 +210,10 @@ public class DialerActivity extends Activity implements LinphoneCoreListener {
|
||||||
mInCallControlRow.setVisibility(View.GONE);
|
mInCallControlRow.setVisibility(View.GONE);
|
||||||
mInCallAddressLayout.setVisibility(View.GONE);
|
mInCallAddressLayout.setVisibility(View.GONE);
|
||||||
mDecline.setEnabled(false);
|
mDecline.setEnabled(false);
|
||||||
|
if (LinphoneService.isready() && getIntent().getData() != null) {
|
||||||
|
newOutgoingCall(getIntent().getData().toString().substring("tel://".length()));
|
||||||
|
getIntent().setData(null);
|
||||||
|
}
|
||||||
if (LinphoneService.isready()) {
|
if (LinphoneService.isready()) {
|
||||||
LinphoneCore lLinphoenCore = LinphoneService.instance().getLinphoneCore();
|
LinphoneCore lLinphoenCore = LinphoneService.instance().getLinphoneCore();
|
||||||
if (lLinphoenCore.isIncall()) {
|
if (lLinphoenCore.isIncall()) {
|
||||||
|
@ -411,9 +391,15 @@ public class DialerActivity extends Activity implements LinphoneCoreListener {
|
||||||
if (mPref.getBoolean(PREF_CHECK_CONFIG, false) == false) {
|
if (mPref.getBoolean(PREF_CHECK_CONFIG, false) == false) {
|
||||||
builder.create().show();
|
builder.create().show();
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (Exception e ) {
|
} catch (Exception e ) {
|
||||||
Log.e(LinphoneService.TAG,"Cannot get initial config", e);
|
Log.e(LinphoneService.TAG,"Cannot get initial config", e);
|
||||||
}
|
}
|
||||||
|
if (getIntent().getData() != null) {
|
||||||
|
newOutgoingCall(getIntent().getData().toString().substring("tel://".length()));
|
||||||
|
getIntent().setData(null);
|
||||||
|
}
|
||||||
|
|
||||||
} else if (state == GeneralState.GSTATE_REG_OK) {
|
} else if (state == GeneralState.GSTATE_REG_OK) {
|
||||||
//nop
|
//nop
|
||||||
} else if (state == GeneralState.GSTATE_CALL_OUT_INVITE) {
|
} else if (state == GeneralState.GSTATE_CALL_OUT_INVITE) {
|
||||||
|
@ -502,5 +488,42 @@ public class DialerActivity extends Activity implements LinphoneCoreListener {
|
||||||
mDecline.setEnabled(true);
|
mDecline.setEnabled(true);
|
||||||
routeAudioToSpeaker();
|
routeAudioToSpeaker();
|
||||||
}
|
}
|
||||||
|
public void newOutgoingCall(String aTo) {
|
||||||
|
newOutgoingCall(aTo,null);
|
||||||
|
}
|
||||||
|
public void newOutgoingCall(String aTo, String displayName) {
|
||||||
|
String lto = aTo;
|
||||||
|
if (aTo.contains(OutgoingCallReceiver.TAG)) {
|
||||||
|
lto = aTo.replace(OutgoingCallReceiver.TAG, "");
|
||||||
|
}
|
||||||
|
mAddress.setText(lto);
|
||||||
|
mDisplayName = displayName;
|
||||||
|
LinphoneCore lLinphoneCore = LinphoneService.instance().getLinphoneCore();
|
||||||
|
if (lLinphoneCore.isIncall()) {
|
||||||
|
Toast toast = Toast.makeText(DialerActivity.this, getString(R.string.warning_already_incall), Toast.LENGTH_LONG);
|
||||||
|
toast.show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
LinphoneAddress lAddress;
|
||||||
|
try {
|
||||||
|
lAddress = lLinphoneCore.interpretUrl(lto);
|
||||||
|
} catch (LinphoneCoreException e) {
|
||||||
|
Toast toast = Toast.makeText(DialerActivity.this
|
||||||
|
,String.format(getString(R.string.warning_wrong_destination_address),mAddress.getText().toString())
|
||||||
|
, Toast.LENGTH_LONG);
|
||||||
|
toast.show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
lAddress.setDisplayName(mDisplayName);
|
||||||
|
try {
|
||||||
|
lLinphoneCore.invite(lAddress);
|
||||||
|
} catch (LinphoneCoreException e) {
|
||||||
|
Toast toast = Toast.makeText(DialerActivity.this
|
||||||
|
,String.format(getString(R.string.error_cannot_invite_address),mAddress.getText().toString())
|
||||||
|
, Toast.LENGTH_LONG);
|
||||||
|
toast.show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,6 +100,7 @@ public class LinphoneActivity extends TabActivity implements SensorEventListener
|
||||||
|
|
||||||
// dialer
|
// dialer
|
||||||
Intent lDialerIntent = new Intent().setClass(this, DialerActivity.class);
|
Intent lDialerIntent = new Intent().setClass(this, DialerActivity.class);
|
||||||
|
lDialerIntent.setData(getIntent().getData());
|
||||||
|
|
||||||
// Initialize a TabSpec for each tab and add it to the TabHost
|
// Initialize a TabSpec for each tab and add it to the TabHost
|
||||||
spec = lTabHost.newTabSpec("dialer").setIndicator(getString(R.string.tab_dialer),
|
spec = lTabHost.newTabSpec("dialer").setIndicator(getString(R.string.tab_dialer),
|
||||||
|
@ -120,25 +121,15 @@ public class LinphoneActivity extends TabActivity implements SensorEventListener
|
||||||
hideScreen(true);
|
hideScreen(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onNewIntent(Intent intent) {
|
protected void onNewIntent(Intent intent) {
|
||||||
super.onNewIntent(intent);
|
super.onNewIntent(intent);
|
||||||
if (intent.getData() != null) {
|
if (intent.getData() != null) {
|
||||||
//incoming call requested
|
DialerActivity.getDialer().newOutgoingCall(intent.getData().toString().substring("tel://".length()));
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
intent.setData(null);
|
||||||
builder.setMessage(getString(R.string.place_call_chooser))
|
|
||||||
.setCancelable(false)
|
|
||||||
.setPositiveButton(getString(R.string.yes), new DialogInterface.OnClickListener() {
|
|
||||||
public void onClick(DialogInterface dialog, int id) {
|
|
||||||
;
|
|
||||||
}
|
|
||||||
}).setNegativeButton(getString(R.string.no), new DialogInterface.OnClickListener() {
|
|
||||||
public void onClick(DialogInterface dialog, int id) {
|
|
||||||
}
|
|
||||||
});
|
|
||||||
builder.create().show();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -266,4 +257,6 @@ public class LinphoneActivity extends TabActivity implements SensorEventListener
|
||||||
}
|
}
|
||||||
getWindow().setAttributes(lAttrs);
|
getWindow().setAttributes(lAttrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,7 @@ import android.app.Service;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
import android.net.ConnectivityManager;
|
import android.net.ConnectivityManager;
|
||||||
import android.net.NetworkInfo;
|
import android.net.NetworkInfo;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
|
@ -253,6 +254,7 @@ public class LinphoneService extends Service implements LinphoneCoreListener {
|
||||||
boolean lIsDebug = mPref.getBoolean(getString(R.string.pref_debug_key), false);
|
boolean lIsDebug = mPref.getBoolean(getString(R.string.pref_debug_key), false);
|
||||||
LinphoneCoreFactory.instance().setDebugMode(lIsDebug);
|
LinphoneCoreFactory.instance().setDebugMode(lIsDebug);
|
||||||
|
|
||||||
|
|
||||||
//1 read proxy config from preferences
|
//1 read proxy config from preferences
|
||||||
String lUserName = mPref.getString(getString(R.string.pref_username_key), null);
|
String lUserName = mPref.getString(getString(R.string.pref_username_key), null);
|
||||||
if (lUserName == null || lUserName.length()==0) {
|
if (lUserName == null || lUserName.length()==0) {
|
||||||
|
|
|
@ -23,18 +23,36 @@ import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
import android.preference.PreferenceManager;
|
||||||
|
|
||||||
public class OutgoingCallReceiver extends BroadcastReceiver {
|
public class OutgoingCallReceiver extends BroadcastReceiver {
|
||||||
|
public static String TAG = ";0000000";
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
String to = intent.getStringExtra("android.intent.extra.PHONE_NUMBER");
|
String to = intent.getStringExtra("android.intent.extra.PHONE_NUMBER");
|
||||||
|
if (!to.contains(TAG)) {
|
||||||
|
if (LinphoneService.isready() && LinphoneService.instance().getLinphoneCore().getDefaultProxyConfig()==null) {
|
||||||
|
//just return
|
||||||
|
return;
|
||||||
|
}
|
||||||
setResult(Activity.RESULT_OK,null, null);
|
setResult(Activity.RESULT_OK,null, null);
|
||||||
Intent lIntent = new Intent();
|
Intent lIntent = new Intent();
|
||||||
lIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
// 1 check config
|
||||||
|
if (PreferenceManager.getDefaultSharedPreferences(context).getBoolean(context.getString(R.string.pref_handle_outcall_key), false)) {
|
||||||
|
//start linphone directly
|
||||||
lIntent.setClass(context, LinphoneActivity.class);
|
lIntent.setClass(context, LinphoneActivity.class);
|
||||||
lIntent.setData(Uri.parse("tel://"+to));
|
} else {
|
||||||
|
//start activity chooser
|
||||||
|
lIntent.setAction(Intent.ACTION_CALL);
|
||||||
|
}
|
||||||
|
|
||||||
|
lIntent.setData(Uri.parse("tel://"+to+TAG));
|
||||||
|
lIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
context.startActivity(lIntent);
|
context.startActivity(lIntent);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
setResult(Activity.RESULT_OK,to.replace(TAG, ""),null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit a17cdb896f3df16b9715ab1a0bc57992857dfa24
|
Subproject commit d1f0a3cebe43f779e486825fe200c4e51940bfb2
|
Loading…
Reference in a new issue