[英]How do I Register SIP profile with SIP server using Android SIP API?
[英]Registering SIP Profile using Android SIP stack
我一直在開發一個應用程序,該應用程序使用戶能夠使用受 SIPDemo 啟發的 SIP 撥打和接聽電話,在我從手機上卸載該應用程序之前,它運行良好,它進行了注冊,顯示消息“就緒”和然后着手進行通話處理。 現在它沒有進入 Sipregistrationlistener 並顯示錯誤“嘗試關閉管理器 1 SipException 時出錯:無法創建 SipSession;網絡不可用?”。
據我了解,我懷疑問題是由於以前的 SIP 帳戶仍然鏈接,因此在應用程序中自動打開,不允許任何注冊,如這篇文章的解決方案中所述“ Android Native SIP Stack not registering客戶端”,但我不知道如何處理這個,在onDestroy上引入closelocalprofile function,onPause沒有效果。 此外,直到最近它確實顯示消息“SipManager 已准備好調用”並且它已打開,但現在盡管沒有更改代碼中的任何內容,但現在它沒有顯示,因此問題可能不一定是這個。
在打印方面,顯示了以下消息: - 不顯示與狀態相關的消息; - 日志顯示“創建管理器”和“構建新配置文件”;
此外,我已經擁有支持 SIP 通信的權限和清單編碼。
我現在知道這個堆棧不是最好的,但我不想放棄這個項目,所以任何幫助或提示將不勝感激。 在最后一種情況下,如果沒有找到解決方案/進展,如果你們中的任何人也可以向類似的替代堆棧提供建議,那也將不勝感激。
這是代碼:
public SipManager sipManager = null;//SIPMANAGER
public SipProfile sipProfile = null;//SIPPROFILE
public SipAudioCall call = null;//SIPAUDIOCALL
public IncomingCallReceiver callReceiver;
@Override
protected void onCreate(Bundle savedInstanceState)
{
Permissions();
Supported();
initManager();
MakeCallButton.setOnClickListener(new View.OnClickListener() /onclick event
{
@Override
public void onClick(View view)
{
initCall();
}
});
EndCallButton.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View view) {
try
{
call.endCall();
}
catch (SipException e)
{
status("Error when trying to end call. " + e);
}
}
});
}
public void initManager()//SIPMANAGER
{
if(sipManager == null)
{
sipManager = SipManager.newInstance(this); //Creates a manager instance. Returns null if SIP API is not supported
Log.d("Manager", "Creating Manager");
}
initLocalProfile();
}
public void initLocalProfile()
{
if (sipManager == null)
{
Log.d("Manager", "There is no manager");
return;
}
if (sipProfile != null)
{
Log.d("Profile", "There is already a profile 1");
closeLocalProfile();
}
//localprofiledata
String user = "x";
String domain = "xxx";
String pass = "zzzz";
try
{
Log.d("Profile", "Building a new profile");
SipProfile.Builder builder = new SipProfile.Builder(user, domain); //user of the SIP account & the SIP server domain
builder.setPassword(pass);//Sets the password of the SIP account
builder.setOutboundProxy(domain);//Sets the outbound proxy of the SIP server
builder.setPort(5060);//port number
builder.setProtocol("UDP");
builder.setAutoRegistration(false);
sipProfile = builder.build();//Builds and returns the SIP profile object.
Intent sipIntent = new Intent();//intent for the calls
sipIntent.setAction("android.Login.INCOMING_CALL");
PendingIntent pi = PendingIntent.getBroadcast(this, 0, sipIntent, Intent.FILL_IN_DATA);
sipManager.open(sipProfile, pi, null);//Opens the profile for making calls and/or receiving generic SIP calls
//Sets the listener to listen to registration events. No effect if the profile has not been opened to receive call
sipManager.setRegistrationListener(sipProfile.getUriString(), new SipRegistrationListener()
{
public void onRegistering(String localProfileUri)
{
//Called when a registration request is sent
status("Registering");
}
public void onRegistrationDone(String localProfileUri, long expiryTime)
{
//Called when the registration succeeded
status("Ready");
}
public void onRegistrationFailed(String localProfileUri, int errorCode, String errorMessage)
{
//Called when the registration failed
status("Registration Failed " + localProfileUri + errorCode + errorMessage );
}
});
if (sipManager.isRegistered(sipProfile.getUriString()))
{
Log.d("Profile","SipManager is ready for calls");
}
if (sipManager.isOpened(sipProfile.getUriString()))
{
Log.d("Profile","SipManager is open");
}
}
catch (ParseException pe)
{
status("Connection Error");
}
catch (SipException sipe)//if calling the SIP service results in an error
{
status("Error with SIP " + sipe);
}
catch (SecurityException se)
{
status("Error with security" + se);
}
catch (RuntimeException re)
{
status("Error with runtime" + re);
}
catch (Exception e)
{
status("Error" + e);
}
}
public void closeLocalProfile()
{
if (sipManager == null)
{
Log.d("Manager", "There is no manager 1");
return;
}
try
{
if (sipProfile != null)
{
Log.d("Profile", "There is already a profile 2");
sipManager.close(sipProfile.getUriString()); //Closes the specified profile to not make/receive calls
}
}
catch (SipException se)//if calling the SIP service results in an error
{
status("Error while closing SIP" + se);
}
}
public void initCall()
{
callstatus("Adress: " + sipAddress);
try
{
SipAudioCall.Listener listener = new SipAudioCall.Listener() //Listener for events relating to a SIP call, such as when a call is being recieved ("on ringing") or a call is outgoing ("on calling")
{
@Override
public void onCalling(SipAudioCall call)
{
Log.d("initCall", "Initiating session! " + sipAddress);
}
@Override
public void onCallEstablished(SipAudioCall call)
{
Log.d("initCall", "Call started! " + sipAddress);
call.startAudio();//Starts the audio for the established call. This method should be called after onCallEstablished(SipAudioCall) is called
Enter();
}
@Override
public void onRinging(SipAudioCall call, SipProfile caller)
{
Log.d("initCall", "Ringing " + sipAddress);
}
@Override
public void onRingingBack(SipAudioCall call) //Called when a RINGING response is received for the INVITE request sent
{
Log.d("initCall", "Ringing back " + sipAddress);
}
@Override
public void onCallBusy(SipAudioCall call)
{
Log.d("initCall", "Call busy " + sipAddress);
}
@Override
public void onCallEnded(SipAudioCall call)
{
Log.d("initCall", "Call Over ");
call.close();
}
@Override
public void onError(SipAudioCall call, int errorCode, String errorMessage)
{
//super.onError(call, errorCode, errorMessage);
Log.d("initCall", "Error! " + errorMessage + errorCode);
}
};
//the call object that carries out the audio call
call = sipManager.makeAudioCall(sipProfile.getUriString(), sipAddress, listener, 30);
}
catch (Exception e)
{
status("Error when trying to close manager 1. " + e);
if (sipProfile != null)
{
try
{
sipManager.close(sipProfile.getUriString());
}
catch (Exception ee)
{
status("Error when trying to close manager 2. " + ee);
}
}
if (call != null)
{
call.close();
}
}
}
public void status(final String status)//status about the program
{
StatusTextView = (TextView) findViewById(R.id.StatusTextView);
StatusTextView.setText(status);
}
public void callstatus(final String callstatus)//status about the call
{
CallTextView = (TextView) findViewById(R.id.CallTextView);
CallTextView.setText(callstatus);
}
感謝您的時間和關注。
更新
通過在重新安裝應用程序后重新啟動設備並將代碼從 Android Studio 重新發送到手機的組合,設法繞過這些先前的錯誤。 如上所述,我對錯誤來源的懷疑是由於此堆棧存在的錯誤,但它現在可以正常工作並且我對成品感到滿意。
盡管在這里沒有得到任何回應,但我希望這個帖子可以對某人有所幫助。
感謝您的時間和關注。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.