我使用Android的原生库(android.net.sip
和android.net.rtp
)开发了一款软电话。
我遇到了RTP数据包的问题。数据包正在发送,但它们是空的,然后没有收到音频。
似乎SIP通信正在正确完成,因为INVITE,RINGING,TRYING,BYE ......和其他数据包正在发送正常。
import java.io.IOException;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.text.ParseException;
import java.util.Enumeration;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.SoundPool;
import es.app.packet.MainActivity;
import es.app.packet.R;
import es.app.packet.utils.Constants;
import android.annotation.SuppressLint;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.rtp.AudioCodec;
import android.net.rtp.AudioGroup;
import android.net.rtp.RtpStream;
import android.net.rtp.AudioStream;
import android.net.sip.SipAudioCall;
import android.net.sip.SipException;
import android.net.sip.SipManager;
import android.net.sip.SipProfile;
import android.net.sip.SipRegistrationListener;
import android.util.Log;
import android.widget.Toast;
public class SipUtil {
SharedPreferences prefs;
MainActivity mActivity;
//Para SIP
public String sipAddress = null;
public SipManager manager = null;
public SipProfile me = null;
public SipAudioCall mCall = null;
Toast toast;
String username;
String domain;
int conPort;
String password;
static SipUtil mSip;
AudioStream audioStream;
AudioGroup audioGroup;
AudioManager audio;
RtpStream rtpStream;
public SipUtil (MainActivity activity)
{
manager = null;
me = null;
mCall = null;
this.mActivity = activity;
prefs = mActivity.getSharedPreferences(Constants.SHARE_PREFERENCES, Context.MODE_PRIVATE);
mSip=this;
}
public void initializeManager() {
if(manager == null) {
manager = SipManager.newInstance(mActivity);
}
initializeLocalProfile();
}
public void initializeLocalProfile() {
if (manager == null) {
return;
}
if (me != null) {
closeLocalProfile();
}
username = prefs.getString("user", "");
domain = prefs.getString("domain", "XXX.XXX.XXX.XXX");
conPort = prefs.getInt("conPort", 5060);
password = prefs.getString("pass", "");
try {
SipProfile.Builder builder = new SipProfile.Builder(username, domain);
builder.setPassword(password);
me = builder.build();
Intent i = new Intent();
i.setAction("app.INCOMING_CALL");
PendingIntent pi = PendingIntent.getBroadcast(mActivity, 0, i, Intent.FILL_IN_DATA);
manager.open(me, pi, null);
manager.setRegistrationListener(me.getUriString(), new SipRegistrationListener() {
public void onRegistering(String localProfileUri) {
toast.setText(R.string.conectando);
toast.show();
Log.d("/SipUtil", "Conectando");
}
public void onRegistrationDone(String localProfileUri, long expiryTime) {
Log.d("/SipUtil", "Conectado!!");
toast.setText(R.string.conectado);
toast.show();
}
public void onRegistrationFailed(String localProfileUri, int errorCode,
String errorMessage) {
Log.d("/SipUtil", "Error Autenticacion: " + errorMessage);
toast.setText(R.string.error_autenticacion);
toast.show();
}
});
} catch (ParseException pe) {
toast.setText(R.string.error_conexion_SIP);
toast.show();
} catch (SipException se) {
toast.setText(R.string.error_conexion_SIP);
toast.show();
}
}
public void destroySipUtil()
{
if (mCall != null) {
mCall.close();
}
closeLocalProfile();
}
public void closeLocalProfile() {
if (manager == null) {
return;
}
try {
if (me != null) {
manager.close(me.getUriString());
}
} catch (Exception ee) {
Log.d("/onDestroy", "Failed to close local profile.", ee);
}
}
public void initiateCall(String destino)
{
this.sipAddress = "sip:"+destino+"@"+domain;
llamar();
}
public void colgar() {
try {
mCall.endCall();
if(audioGroup != null)
audioGroup.clear();
Log.d("/SipUtil", "Llamada finalizada en colgar");
} catch (SipException e) {
Log.d("/SipUtil", "Llamada MAL finalizada en colgar");
}
}
private void llamar()
{
try
{
SipAudioCall.Listener listener = new SipAudioCall.Listener() {
@Override
public void onCallEstablished(SipAudioCall call)
{
Log.d("/SipUtil", "onCallEstablished");
mCall = call;
try
{
byte ip[] = null;
try {
for (Enumeration<NetworkInterface> en = NetworkInterface
.getNetworkInterfaces(); en
.hasMoreElements();) {
NetworkInterface intf = en.nextElement();
for (Enumeration<InetAddress> enumIpAddr = intf
.getInetAddresses(); enumIpAddr
.hasMoreElements();) {
InetAddress inetAddress = enumIpAddr
.nextElement();
if (!inetAddress.isLoopbackAddress()) {
ip = inetAddress.getAddress();
}
}
}
} catch (SocketException ex) {
Log.i("SocketException ", ex.toString());
}
audio = (AudioManager) mActivity.getSystemService(Context.AUDIO_SERVICE);
audio.setMode(AudioManager.MODE_IN_CALL);
audioGroup = new AudioGroup();
audioGroup.setMode(AudioGroup.MODE_NORMAL);
audioStream = new AudioStream(InetAddress.getByAddress(ip));
audioStream.setCodec(AudioCodec.GSM);
audioStream.setMode(RtpStream.MODE_NORMAL);
audioStream.associate(InetAddress.getByName(mCall.getPeerProfile().getSipDomain()),
11234);
audioStream.join(audioGroup);
mCall.startAudio();
if (mCall.isMuted())
{
mCall.toggleMute();
}
Log.d("/SipUtil", "HABLANDO... "+mCall.getPeerProfile().getSipDomain());
Log.d("/SipUtil", "Codec");
} catch (SocketException e) {
toast.setText(R.string.error_codec);
Log.d("/SipUtil", "Error Codec");
} catch (IOException e) {
toast.setText(R.string.error_codec);
toast.show();
Log.d("/SipUtil", "Error Codec");
}
}
@Override
public void onCallEnded(SipAudioCall call) {
mCall = call;
Log.d("/SipUtil", "onCallEnded");
try {
mCall.endCall();
colgar();
Log.d("/SipUtil", "Llamada finalizada");
} catch (SipException e) {
Log.d("/SipUtil", "Llamada MAL finalizada");
}
}
public void onChanged (SipAudioCall call){
Log.d("/SipUtil", "onChanged");
mCall = call;
}
};
String origen = "sip:"+username+":"+password+"@"+domain;
mCall = manager.makeAudioCall(origen, sipAddress, listener, 0);
}
catch (Exception e) {
Log.i("/InitiateCall", "Error intentando cerrar manager.", e);
if (me != null) {
try {
manager.close(me.getUriString());
} catch (Exception ee) {
Log.i("/InitiateCall",
"Error when trying to close manager.", ee);
}
}
if (mCall != null) {
mCall.close();
}
}
}
}
答案 0 :(得分:2)
看一下这个例子https://github.com/Mobicents/restcomm-android-sdk/tree/master/Examples/JAIN%20SIP
了解如何在btnCall点击处理程序
上建立RTP连接