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>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<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>
|
||||
</activity>
|
||||
<activity android:name=".LinphonePreferencesActivity">
|
||||
|
@ -24,11 +29,7 @@
|
|||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
</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 android:name=".ContactPickerActivity">
|
||||
<intent-filter>
|
||||
|
@ -44,7 +45,7 @@
|
|||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</activity>
|
||||
<service android:name=".LinphoneService">
|
||||
</service>
|
||||
<receiver android:name="NetworkManager">
|
||||
|
@ -55,6 +56,10 @@
|
|||
<intent-filter android:priority="0"><action android:name="android.intent.action.NEW_OUTGOING_CALL"></action>
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<receiver android:name="BootReceiver" >
|
||||
<intent-filter><action android:name="android.intent.action.BOOT_COMPLETED"></action>
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
</application>
|
||||
|
||||
<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.WAKE_LOCK"/>
|
||||
<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>
|
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"?>
|
||||
<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_key">Outbound proxy</string>
|
||||
<string name="pref_codec_pcma">pcma</string>
|
||||
|
|
|
@ -25,13 +25,15 @@
|
|||
android:title="@string/pref_codec_pcmu" android:defaultValue="true"></CheckBoxPreference>
|
||||
<CheckBoxPreference android:key="@string/pref_codec_pcma_key"
|
||||
android:title="@string/pref_codec_pcma" android:defaultValue="true"></CheckBoxPreference>
|
||||
</PreferenceScreen>
|
||||
<EditTextPreference android:title="@string/pref_prefix"
|
||||
</PreferenceScreen><CheckBoxPreference android:title="@string/pref_autostart" android:defaultValue="true" android:key="@string/pref_autostart_key"></CheckBoxPreference>
|
||||
<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>
|
||||
|
||||
<CheckBoxPreference android:key="@string/pref_debug_key"
|
||||
android:title="@string/pref_debug" android:enabled="true"></CheckBoxPreference>
|
||||
|
||||
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
</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);;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -115,7 +115,7 @@ public class DialerActivity extends Activity implements LinphoneCoreListener {
|
|||
mPref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
|
||||
|
||||
try {
|
||||
|
||||
|
||||
|
||||
mAddress = (TextView) findViewById(R.id.SipUri);
|
||||
mDisplayNameView = (TextView) findViewById(R.id.DisplayNameView);
|
||||
|
@ -158,31 +158,7 @@ public class DialerActivity extends Activity implements LinphoneCoreListener {
|
|||
}
|
||||
return;
|
||||
}
|
||||
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( 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;
|
||||
}
|
||||
newOutgoingCall(mAddress.getText().toString(),mDisplayName);
|
||||
}
|
||||
|
||||
});
|
||||
|
@ -234,6 +210,10 @@ public class DialerActivity extends Activity implements LinphoneCoreListener {
|
|||
mInCallControlRow.setVisibility(View.GONE);
|
||||
mInCallAddressLayout.setVisibility(View.GONE);
|
||||
mDecline.setEnabled(false);
|
||||
if (LinphoneService.isready() && getIntent().getData() != null) {
|
||||
newOutgoingCall(getIntent().getData().toString().substring("tel://".length()));
|
||||
getIntent().setData(null);
|
||||
}
|
||||
if (LinphoneService.isready()) {
|
||||
LinphoneCore lLinphoenCore = LinphoneService.instance().getLinphoneCore();
|
||||
if (lLinphoenCore.isIncall()) {
|
||||
|
@ -411,9 +391,15 @@ public class DialerActivity extends Activity implements LinphoneCoreListener {
|
|||
if (mPref.getBoolean(PREF_CHECK_CONFIG, false) == false) {
|
||||
builder.create().show();
|
||||
}
|
||||
|
||||
} catch (Exception 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) {
|
||||
//nop
|
||||
} else if (state == GeneralState.GSTATE_CALL_OUT_INVITE) {
|
||||
|
@ -502,5 +488,42 @@ public class DialerActivity extends Activity implements LinphoneCoreListener {
|
|||
mDecline.setEnabled(true);
|
||||
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
|
||||
Intent lDialerIntent = new Intent().setClass(this, DialerActivity.class);
|
||||
lDialerIntent.setData(getIntent().getData());
|
||||
|
||||
// Initialize a TabSpec for each tab and add it to the TabHost
|
||||
spec = lTabHost.newTabSpec("dialer").setIndicator(getString(R.string.tab_dialer),
|
||||
|
@ -120,25 +121,15 @@ public class LinphoneActivity extends TabActivity implements SensorEventListener
|
|||
hideScreen(true);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onNewIntent(Intent intent) {
|
||||
super.onNewIntent(intent);
|
||||
if (intent.getData() != null) {
|
||||
//incoming call requested
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
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();
|
||||
DialerActivity.getDialer().newOutgoingCall(intent.getData().toString().substring("tel://".length()));
|
||||
intent.setData(null);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -266,4 +257,6 @@ public class LinphoneActivity extends TabActivity implements SensorEventListener
|
|||
}
|
||||
getWindow().setAttributes(lAttrs);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -43,6 +43,7 @@ import android.app.Service;
|
|||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.NetworkInfo;
|
||||
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);
|
||||
LinphoneCoreFactory.instance().setDebugMode(lIsDebug);
|
||||
|
||||
|
||||
//1 read proxy config from preferences
|
||||
String lUserName = mPref.getString(getString(R.string.pref_username_key), null);
|
||||
if (lUserName == null || lUserName.length()==0) {
|
||||
|
|
|
@ -23,18 +23,36 @@ import android.content.BroadcastReceiver;
|
|||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.preference.PreferenceManager;
|
||||
|
||||
public class OutgoingCallReceiver extends BroadcastReceiver {
|
||||
|
||||
public static String TAG = ";0000000";
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
String to = intent.getStringExtra("android.intent.extra.PHONE_NUMBER");
|
||||
setResult(Activity.RESULT_OK,null, null);
|
||||
Intent lIntent = new Intent();
|
||||
lIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
lIntent.setClass(context, LinphoneActivity.class);
|
||||
lIntent.setData(Uri.parse("tel://"+to));
|
||||
context.startActivity(lIntent);
|
||||
if (!to.contains(TAG)) {
|
||||
if (LinphoneService.isready() && LinphoneService.instance().getLinphoneCore().getDefaultProxyConfig()==null) {
|
||||
//just return
|
||||
return;
|
||||
}
|
||||
setResult(Activity.RESULT_OK,null, null);
|
||||
Intent lIntent = new Intent();
|
||||
// 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);
|
||||
} 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);
|
||||
|
||||
} else {
|
||||
setResult(Activity.RESULT_OK,to.replace(TAG, ""),null);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit a17cdb896f3df16b9715ab1a0bc57992857dfa24
|
||||
Subproject commit d1f0a3cebe43f779e486825fe200c4e51940bfb2
|
Loading…
Reference in a new issue