mirror of
https://gitlab.linphone.org/BC/public/linphone-android.git
synced 2026-01-18 03:48:08 +00:00
394 lines
12 KiB
Java
394 lines
12 KiB
Java
/*
|
|
DialerActivity.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.HashMap;
|
|
|
|
import org.linphone.LinphoneService.LinphoneGuiListener;
|
|
import org.linphone.core.LinphoneCall;
|
|
import org.linphone.core.LinphoneCall.State;
|
|
import org.linphone.core.LinphoneCore.RegistrationState;
|
|
import org.linphone.core.LinphoneProxyConfig;
|
|
import org.linphone.core.Log;
|
|
import org.linphone.ui.AddressAware;
|
|
import org.linphone.ui.AddressText;
|
|
import org.linphone.ui.CallButton;
|
|
import org.linphone.ui.EraseButton;
|
|
|
|
import android.app.Activity;
|
|
import android.app.AlertDialog;
|
|
import android.app.Dialog;
|
|
import android.content.Intent;
|
|
import android.content.SharedPreferences;
|
|
import android.net.Uri;
|
|
import android.os.Bundle;
|
|
import android.preference.PreferenceManager;
|
|
import android.view.KeyEvent;
|
|
import android.view.LayoutInflater;
|
|
import android.view.View;
|
|
import android.view.View.OnClickListener;
|
|
import android.widget.Adapter;
|
|
import android.widget.Button;
|
|
import android.widget.ListAdapter;
|
|
import android.widget.ListView;
|
|
import android.widget.SimpleAdapter;
|
|
import android.widget.SlidingDrawer;
|
|
import android.widget.SlidingDrawer.OnDrawerScrollListener;
|
|
import android.widget.TextView;
|
|
import android.widget.Toast;
|
|
|
|
/**
|
|
*
|
|
* Dialer and main activity of Linphone Android.
|
|
*
|
|
* Roles are:<ul>
|
|
* <li>Display the numpad, call/accept, address buttons</li>
|
|
* <li>Define preferences through the menu</li>
|
|
* <li>React to bad preference / no account set</li>
|
|
* <li>Manage first launch</li>
|
|
* </ul>
|
|
*
|
|
*/
|
|
public class DialerActivity extends Activity implements LinphoneGuiListener {
|
|
|
|
private TextView mStatus;
|
|
|
|
private AddressText mAddress;
|
|
private CallButton mCall;
|
|
|
|
private static DialerActivity instance;
|
|
private boolean mPreventDoubleCallOnRotation;
|
|
|
|
private AlertDialog wizardDialog;
|
|
protected String username;
|
|
private String key;
|
|
|
|
private static final String CURRENT_ADDRESS = "org.linphone.current-address";
|
|
private static final String CURRENT_DISPLAYNAME = "org.linphone.current-displayname";
|
|
private static final String PREVENT_DOUBLE_CALL = "prevent_call_on_phone_rotation";
|
|
|
|
private static final int CONFIRM_ID = 0x668;
|
|
|
|
/**
|
|
* @return null if not ready yet
|
|
*/
|
|
public static DialerActivity instance() {
|
|
return instance;
|
|
}
|
|
|
|
private String getStatusIcon(RegistrationState state) {
|
|
if (state == RegistrationState.RegistrationOk)
|
|
return Integer.toString(R.drawable.status_green);
|
|
|
|
else if (state == RegistrationState.RegistrationNone)
|
|
return Integer.toString(R.drawable.status_red);
|
|
|
|
else if (state == RegistrationState.RegistrationProgress)
|
|
return Integer.toString(R.drawable.status_orange);
|
|
|
|
else
|
|
return Integer.toString(R.drawable.status_offline);
|
|
}
|
|
|
|
private void displayRegisterStatus() {
|
|
ListView accounts = (ListView) findViewById(R.id.accounts);
|
|
if (accounts != null) {
|
|
accounts.setDividerHeight(0);
|
|
ArrayList<HashMap<String,String>> hashMapAccountsStateList = new ArrayList<HashMap<String,String>>();
|
|
for (LinphoneProxyConfig lpc : LinphoneManager.getLc().getProxyConfigList()) {
|
|
HashMap<String, String> entitiesHashMap = new HashMap<String, String>();
|
|
entitiesHashMap.put("Identity", lpc.getIdentity().split("sip:")[1]);
|
|
entitiesHashMap.put("State", getStatusIcon(lpc.getState()));
|
|
hashMapAccountsStateList.add(entitiesHashMap);
|
|
}
|
|
Adapter adapterForList = new SimpleAdapter(this, hashMapAccountsStateList, R.layout.accounts,
|
|
new String[] {"Identity", "State"},
|
|
new int[] { R.id.Identity, R.id.State });
|
|
accounts.setAdapter((ListAdapter) adapterForList);
|
|
accounts.invalidate();
|
|
}
|
|
}
|
|
|
|
protected Dialog onCreateDialog (int id) {
|
|
if (id == CONFIRM_ID) {
|
|
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
|
builder.setTitle(R.string.wizard_confirmation);
|
|
|
|
final LayoutInflater inflater = LayoutInflater.from(this);
|
|
View v = inflater.inflate(R.layout.wizard_confirm, null);
|
|
builder.setView(v);
|
|
|
|
Button check = (Button) v.findViewById(R.id.wizardCheckAccount);
|
|
check.setOnClickListener(new OnClickListener() {
|
|
public void onClick(View v) {
|
|
wizardDialog.dismiss();
|
|
if (LinphonePreferencesActivity.isAccountVerified(username)) {
|
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(DialerActivity.this);
|
|
SharedPreferences.Editor editor = prefs.edit();
|
|
editor.putBoolean(getString(R.string.pref_activated_key) + key, true);
|
|
editor.commit();
|
|
} else {
|
|
showDialog(CONFIRM_ID);
|
|
}
|
|
}
|
|
});
|
|
|
|
Button cancel = (Button) v.findViewById(R.id.wizardCancel);
|
|
cancel.setOnClickListener(new OnClickListener() {
|
|
public void onClick(View v) {
|
|
wizardDialog.dismiss();
|
|
}
|
|
});
|
|
|
|
wizardDialog = builder.create();
|
|
return wizardDialog;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private void verifiyAccountsActivated() {
|
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
|
int nbAccounts = prefs.getInt(getString(R.string.pref_extra_accounts), 0);
|
|
|
|
for (int i = 0; i < nbAccounts; i++) {
|
|
String key = (i == 0 ? "" : Integer.toString(i));
|
|
boolean createdByWizard = prefs.getBoolean(getString(R.string.pref_wizard_key) + key, false);
|
|
boolean activated = prefs.getBoolean(getString(R.string.pref_activated_key) + key, true);
|
|
if (createdByWizard && !activated) {
|
|
//Check if account has been activated since
|
|
String username = prefs.getString(getString(R.string.pref_username_key) + key, "");
|
|
activated = LinphonePreferencesActivity.isAccountVerified(username);
|
|
if (activated) {
|
|
SharedPreferences.Editor editor = prefs.edit();
|
|
editor.putBoolean(getString(R.string.pref_activated_key) + key, true);
|
|
editor.commit();
|
|
} else {
|
|
this.username = username;
|
|
this.key = key;
|
|
showDialog(CONFIRM_ID);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public void onCreate(Bundle savedInstanceState) {
|
|
setContentView(R.layout.dialer);
|
|
|
|
mAddress = (AddressText) findViewById(R.id.SipUri);
|
|
((EraseButton) findViewById(R.id.Erase)).setAddressWidget(mAddress);
|
|
|
|
|
|
mCall = (CallButton) findViewById(R.id.Call);
|
|
mCall.setAddressWidget(mAddress);
|
|
|
|
mStatus = (TextView) findViewById(R.id.status_label);
|
|
|
|
SlidingDrawer drawer = (SlidingDrawer) findViewById(R.id.drawer);
|
|
if (drawer != null) {
|
|
drawer.setOnDrawerScrollListener(new OnDrawerScrollListener() {
|
|
public void onScrollEnded() {
|
|
|
|
}
|
|
|
|
public void onScrollStarted() {
|
|
displayRegisterStatus();
|
|
}
|
|
});
|
|
}
|
|
|
|
AddressAware numpad = (AddressAware) findViewById(R.id.Dialer);
|
|
if (numpad != null)
|
|
numpad.setAddressWidget(mAddress);
|
|
|
|
// call to super must be done after all fields are initialized
|
|
// because it may call this.enterIncallMode
|
|
super.onCreate(savedInstanceState);
|
|
|
|
mPreventDoubleCallOnRotation=savedInstanceState != null
|
|
&& savedInstanceState.getBoolean(PREVENT_DOUBLE_CALL, false);
|
|
if (mPreventDoubleCallOnRotation) {
|
|
Log.i("Prevent launching a new call on rotation");
|
|
} else {
|
|
checkIfOutgoingCallIntentReceived();
|
|
}
|
|
|
|
instance = this;
|
|
super.onCreate(savedInstanceState);
|
|
|
|
verifiyAccountsActivated();
|
|
|
|
displayRegisterStatus();
|
|
}
|
|
|
|
|
|
private void checkIfOutgoingCallIntentReceived() {
|
|
if (getIntent().getData() == null) return;
|
|
|
|
if (!LinphoneService.isReady() || LinphoneManager.getLc().isIncall()) {
|
|
Log.w("Outgoing call aborted as LinphoneService"
|
|
+ " is not ready or we are already in call");
|
|
return;
|
|
}
|
|
|
|
// Fix call from contact issue
|
|
if (getIntent().getData().getSchemeSpecificPart() != null)
|
|
getIntent().setAction(Intent.ACTION_CALL);
|
|
|
|
newOutgoingCall(getIntent());
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
public void onSaveInstanceState(Bundle savedInstanceState) {
|
|
super.onSaveInstanceState(savedInstanceState);
|
|
savedInstanceState.putCharSequence(CURRENT_ADDRESS, mAddress.getText());
|
|
if (mAddress.getDisplayedName() != null)
|
|
savedInstanceState.putString(CURRENT_DISPLAYNAME,mAddress.getDisplayedName());
|
|
savedInstanceState.putBoolean(PREVENT_DOUBLE_CALL, mPreventDoubleCallOnRotation);
|
|
}
|
|
|
|
@Override
|
|
protected void onRestoreInstanceState(Bundle savedState) {
|
|
super.onRestoreInstanceState(savedState);
|
|
CharSequence addr = savedState.getCharSequence(CURRENT_ADDRESS);
|
|
if (addr != null && mAddress != null) {
|
|
mAddress.setText(addr);
|
|
}
|
|
mAddress.setDisplayedName(savedState.getString(CURRENT_DISPLAYNAME));
|
|
}
|
|
|
|
|
|
@Override
|
|
protected void onDestroy() {
|
|
super.onDestroy();
|
|
instance=null;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void newOutgoingCall(Intent intent) {
|
|
String scheme = intent.getData().getScheme();
|
|
if (scheme.startsWith("imto")) {
|
|
mAddress.setText("sip:" + intent.getData().getLastPathSegment());
|
|
} else if (scheme.startsWith("call") || scheme.startsWith("sip")) {
|
|
mAddress.setText(intent.getData().getSchemeSpecificPart());
|
|
} else {
|
|
Log.e("Unknown scheme: ",scheme);
|
|
mAddress.setText(intent.getData().getSchemeSpecificPart());
|
|
}
|
|
|
|
mAddress.clearDisplayedName();
|
|
intent.setData(null);
|
|
// Setting data to null is no use when the activity is recreated
|
|
// as the intent is immutable.
|
|
// https://groups.google.com/forum/#!topic/android-developers/vrLdM5mKeoY
|
|
mPreventDoubleCallOnRotation=true;
|
|
setIntent(intent);
|
|
|
|
LinphoneManager.getInstance().newOutgoingCall(mAddress);
|
|
}
|
|
|
|
|
|
public void setContactAddress(String aContact,String aDisplayName, Uri photo) {
|
|
mAddress.setText(aContact);
|
|
mAddress.setDisplayedName(aDisplayName);
|
|
mAddress.setPictureUri(photo);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/***** GUI delegates for listener LinphoneServiceListener *************/
|
|
@Override
|
|
public void onDisplayStatus(String message) {
|
|
mStatus.setText(message);
|
|
}
|
|
|
|
@Override
|
|
public void onAlreadyInCall() {
|
|
showToast(R.string.warning_already_incall);
|
|
}
|
|
|
|
@Override
|
|
public void onCannotGetCallParameters() {
|
|
showToast(R.string.error_cannot_get_call_parameters,mAddress.getText());
|
|
}
|
|
|
|
@Override
|
|
public void onWrongDestinationAddress() {
|
|
showToast(R.string.warning_wrong_destination_address, mAddress.getText());
|
|
}
|
|
|
|
private void showToast(int id, String txt) {
|
|
final String msg = String.format(getString(id), txt);
|
|
Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
|
|
}
|
|
private void showToast(int id, CharSequence txt) {
|
|
showToast(id, txt.toString());
|
|
}
|
|
private void showToast(int id) {
|
|
Toast.makeText(this, getString(id), Toast.LENGTH_LONG).show();
|
|
}
|
|
|
|
@Override
|
|
public void onCallStateChanged(LinphoneCall call, State s, String m) {}
|
|
|
|
public void onGlobalStateChangedToOn(String message) {
|
|
mCall.setEnabled(!LinphoneManager.getLc().isIncall());
|
|
|
|
if (getIntent().getData() != null) {
|
|
checkIfOutgoingCallIntentReceived();
|
|
}
|
|
}
|
|
|
|
@Override
|
|
protected void onResume() {
|
|
// When coming back from a video call, if the phone orientation is different
|
|
// Android will destroy the previous Dialer and create a new one.
|
|
// Unfortunately the "call end" status event is received in the meanwhile
|
|
// and set to the to be destroyed Dialer.
|
|
// Note1: We wait as long as possible before setting the last message.
|
|
// Note2: Linphone service is in charge of instantiating LinphoneManager
|
|
mStatus.setText(LinphoneManager.getInstance().getLastLcStatusMessage());
|
|
|
|
super.onResume();
|
|
}
|
|
|
|
|
|
@Override
|
|
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
|
if (LinphoneUtils.onKeyVolumeSoftAdjust(keyCode)) return true;
|
|
return super.onKeyDown(keyCode, event);
|
|
}
|
|
|
|
}
|