|
/*
|
|
* Copyright (C) 2010 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package com.example.android.sip;
|
|
|
|
import android.app.Activity;
|
|
import android.app.AlertDialog;
|
|
import android.app.Dialog;
|
|
import android.app.PendingIntent;
|
|
import android.content.DialogInterface;
|
|
import android.content.Intent;
|
|
import android.content.IntentFilter;
|
|
import android.content.SharedPreferences;
|
|
import android.os.Bundle;
|
|
import android.preference.PreferenceManager;
|
|
import android.util.Log;
|
|
import android.view.*;
|
|
import android.net.sip.*;
|
|
import android.widget.EditText;
|
|
import android.widget.TextView;
|
|
import android.widget.ToggleButton;
|
|
|
|
import java.text.ParseException;
|
|
|
|
/**
|
|
* Handles all calling, receiving calls, and UI interaction in the WalkieTalkie app.
|
|
*/
|
|
public class WalkieTalkieActivity extends Activity implements View.OnTouchListener {
|
|
|
|
public String sipAddress = "sip:sridhar007@sip2sip.info";
|
|
|
|
public SipManager manager = null;
|
|
public SipProfile me = null;
|
|
public SipAudioCall call = null;
|
|
public IncomingCallReceiver callReceiver;
|
|
|
|
private static final int CALL_ADDRESS = 1;
|
|
private static final int SET_AUTH_INFO = 2;
|
|
private static final int UPDATE_SETTINGS_DIALOG = 3;
|
|
private static final int HANG_UP = 4;
|
|
|
|
|
|
@Override
|
|
public void onCreate(Bundle savedInstanceState) {
|
|
|
|
super.onCreate(savedInstanceState);
|
|
setContentView(R.layout.walkietalkie);
|
|
|
|
ToggleButton pushToTalkButton = (ToggleButton) findViewById(R.id.pushToTalk);
|
|
pushToTalkButton.setOnTouchListener(this);
|
|
|
|
// Set up the intent filter. This will be used to fire an
|
|
// IncomingCallReceiver when someone calls the SIP address used by this
|
|
// application.
|
|
IntentFilter filter = new IntentFilter();
|
|
filter.addAction("android.SipDemo.INCOMING_CALL");
|
|
callReceiver = new IncomingCallReceiver();
|
|
this.registerReceiver(callReceiver, filter);
|
|
|
|
// "Push to talk" can be a serious pain when the screen keeps turning off.
|
|
// Let's prevent that.
|
|
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
|
|
|
initializeManager();
|
|
}
|
|
|
|
@Override
|
|
public void onStart() {
|
|
super.onStart();
|
|
// When we get back from the preference setting Activity, assume
|
|
// settings have changed, and re-login with new auth info.
|
|
initializeManager();
|
|
}
|
|
|
|
@Override
|
|
public void onDestroy() {
|
|
super.onDestroy();
|
|
if (call != null) {
|
|
call.close();
|
|
}
|
|
|
|
closeLocalProfile();
|
|
|
|
if (callReceiver != null) {
|
|
this.unregisterReceiver(callReceiver);
|
|
}
|
|
}
|
|
|
|
public void initializeManager() {
|
|
if(manager == null) {
|
|
manager = SipManager.newInstance(this);
|
|
}
|
|
|
|
initializeLocalProfile();
|
|
}
|
|
|
|
/**
|
|
* Logs you into your SIP provider, registering this device as the location to
|
|
* send SIP calls to for your SIP address.
|
|
*/
|
|
public void initializeLocalProfile() {
|
|
if (manager == null) {
|
|
return;
|
|
}
|
|
|
|
if (me != null) {
|
|
closeLocalProfile();
|
|
}
|
|
|
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
|
|
// String username = prefs.getString("namePref", "");
|
|
// String domain = prefs.getString("domainPref", "");
|
|
// String password = prefs.getString("passPref", "");
|
|
|
|
// if (username.length() == 0 || domain.length() == 0 || password.length() == 0) {
|
|
// showDialog(UPDATE_SETTINGS_DIALOG);
|
|
// return;
|
|
// }
|
|
|
|
try {
|
|
SipProfile.Builder builder = new SipProfile.Builder("speed_kal", "sip2sip.info");
|
|
builder.setPassword("sippassword");
|
|
me = builder.build();
|
|
Intent i = new Intent();
|
|
i.setAction("android.SipDemo.INCOMING_CALL");
|
|
PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, Intent.FILL_IN_DATA);
|
|
manager.open(me, pi, null);
|
|
|
|
// This listener must be added AFTER manager.open is called,
|
|
// Otherwise the methods aren't guaranteed to fire.
|
|
|
|
manager.setRegistrationListener(me.getUriString(), new SipRegistrationListener() {
|
|
public void onRegistering(String localProfileUri) {
|
|
updateStatus("Registering with SIP Server...");
|
|
}
|
|
|
|
public void onRegistrationDone(String localProfileUri, long expiryTime) {
|
|
updateStatus("Ready");
|
|
}
|
|
|
|
public void onRegistrationFailed(String localProfileUri, int errorCode,
|
|
String errorMessage) {
|
|
updateStatus("Registration failed. Please check settings.");
|
|
}
|
|
});
|
|
} catch (Exception e){
|
|
System.out.println("OK------------------------->eRROR");
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Closes out your local profile, freeing associated objects into memory
|
|
* and unregistering your device from the server.
|
|
*/
|
|
public void closeLocalProfile() {
|
|
if (manager == null) {
|
|
return;
|
|
}
|
|
try {
|
|
if (me != null) {
|
|
manager.close(me.getUriString());
|
|
}
|
|
} catch (Exception ee) {
|
|
System.out.println("OK------------------------->eRROR");
|
|
Log.d("WalkieTalkieActivity/onDestroy", "Failed to close local profile.", ee);
|
|
ee.printStackTrace();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Make an outgoing call.
|
|
*/
|
|
public void initiateCall() {
|
|
try {
|
|
updateStatus(sipAddress);
|
|
SipAudioCall.Listener listener = new SipAudioCall.Listener() {
|
|
// Much of the client's interaction with the SIP Stack will
|
|
// happen via listeners. Even making an outgoing call, don't
|
|
// forget to set up a listener to set things up once the call is established.
|
|
@Override
|
|
public void onCallEstablished(SipAudioCall call) {
|
|
call.startAudio();
|
|
call.setSpeakerMode(true);
|
|
call.toggleMute();
|
|
updateStatus(call);
|
|
}
|
|
|
|
@Override
|
|
public void onCallEnded(SipAudioCall call) {
|
|
updateStatus("Ready.");
|
|
}
|
|
};
|
|
|
|
call = manager.makeAudioCall(me.getUriString(), sipAddress, listener, 30);
|
|
|
|
}
|
|
catch (Exception e) {
|
|
e.printStackTrace();
|
|
Log.i("WalkieTalkieActivity/InitiateCall", "Error when trying to close manager.", e);
|
|
if (me != null) {
|
|
try {
|
|
manager.close(me.getUriString());
|
|
} catch (Exception ee) {
|
|
Log.i("WalkieTalkieActivity/InitiateCall",
|
|
"Error when trying to close manager.", ee);
|
|
ee.printStackTrace();
|
|
}
|
|
}
|
|
if (call != null) {
|
|
call.close();
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Updates the status box at the top of the UI with a messege of your choice.
|
|
* @param status The String to display in the status box.
|
|
*/
|
|
public void updateStatus(final String status) {
|
|
// Be a good citizen. Make sure UI changes fire on the UI thread.
|
|
this.runOnUiThread(new Runnable() {
|
|
public void run() {
|
|
TextView labelView = (TextView) findViewById(R.id.sipLabel);
|
|
labelView.setText(status);
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Updates the status box with the SIP address of the current call.
|
|
* @param call The current, active call.
|
|
*/
|
|
public void updateStatus(SipAudioCall call) {
|
|
String useName = call.getPeerProfile().getDisplayName();
|
|
if(useName == null) {
|
|
useName = call.getPeerProfile().getUserName();
|
|
}
|
|
updateStatus(useName + "@" + call.getPeerProfile().getSipDomain());
|
|
}
|
|
|
|
/**
|
|
* Updates whether or not the user's voice is muted, depending on whether the button is pressed.
|
|
* @param v The View where the touch event is being fired.
|
|
* @param event The motion to act on.
|
|
* @return boolean Returns false to indicate that the parent view should handle the touch event
|
|
* as it normally would.
|
|
*/
|
|
public boolean onTouch(View v, MotionEvent event) {
|
|
if (call == null) {
|
|
return false;
|
|
} else if (event.getAction() == MotionEvent.ACTION_DOWN && call != null && call.isMuted()) {
|
|
call.toggleMute();
|
|
} else if (event.getAction() == MotionEvent.ACTION_UP && !call.isMuted()) {
|
|
call.toggleMute();
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public boolean onCreateOptionsMenu(Menu menu) {
|
|
menu.add(0, CALL_ADDRESS, 0, "Call someone");
|
|
menu.add(0, SET_AUTH_INFO, 0, "Edit your SIP Info.");
|
|
menu.add(0, HANG_UP, 0, "End Current Call.");
|
|
|
|
return true;
|
|
}
|
|
|
|
public boolean onOptionsItemSelected(MenuItem item) {
|
|
switch (item.getItemId()) {
|
|
case CALL_ADDRESS:
|
|
showDialog(CALL_ADDRESS);
|
|
break;
|
|
case SET_AUTH_INFO:
|
|
updatePreferences();
|
|
break;
|
|
case HANG_UP:
|
|
if(call != null) {
|
|
try {
|
|
call.endCall();
|
|
} catch (SipException se) {
|
|
Log.d("WalkieTalkieActivity/onOptionsItemSelected",
|
|
"Error ending call.", se);
|
|
}
|
|
call.close();
|
|
}
|
|
break;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
protected Dialog onCreateDialog(int id) {
|
|
switch (id) {
|
|
case CALL_ADDRESS:
|
|
|
|
LayoutInflater factory = LayoutInflater.from(this);
|
|
final View textBoxView = factory.inflate(R.layout.call_address_dialog, null);
|
|
return new AlertDialog.Builder(this)
|
|
.setTitle("Call Someone.")
|
|
.setView(textBoxView)
|
|
.setPositiveButton(
|
|
android.R.string.ok, new DialogInterface.OnClickListener() {
|
|
public void onClick(DialogInterface dialog, int whichButton) {
|
|
EditText textField = (EditText)
|
|
(textBoxView.findViewById(R.id.calladdress_edit));
|
|
sipAddress = textField.getText().toString();
|
|
initiateCall();
|
|
|
|
}
|
|
})
|
|
.setNegativeButton(
|
|
android.R.string.cancel, new DialogInterface.OnClickListener() {
|
|
public void onClick(DialogInterface dialog, int whichButton) {
|
|
// Noop.
|
|
}
|
|
})
|
|
.create();
|
|
|
|
case UPDATE_SETTINGS_DIALOG:
|
|
return new AlertDialog.Builder(this)
|
|
.setMessage("Please update your SIP Account Settings.")
|
|
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
|
|
public void onClick(DialogInterface dialog, int whichButton) {
|
|
updatePreferences();
|
|
}
|
|
})
|
|
.setNegativeButton(
|
|
android.R.string.cancel, new DialogInterface.OnClickListener() {
|
|
public void onClick(DialogInterface dialog, int whichButton) {
|
|
// Noop.
|
|
}
|
|
})
|
|
.create();
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public void updatePreferences() {
|
|
Intent settingsActivity = new Intent(getBaseContext(),
|
|
SipSettings.class);
|
|
startActivity(settingsActivity);
|
|
}
|
|
}
|