注册使用Android SIP堆栈的SIP配置文件

huangapple go评论89阅读模式
英文:

Registering SIP Profile using Android SIP stack

问题

我一直在开发一个应用程序通过 SIPDemo 提供的灵感使用户能够使用 SIP 进行呼叫和接听呼叫在我从手机中卸载应用程序之前它运行得很好它进行了注册显示了消息准备就绪”,然后继续进行呼叫处理现在它没有进入 Sipregistrationlistener并显示错误尝试关闭管理器 1 时出错 SipException:Failed to create SipSession; network unavailable?”。

据我所知我怀疑问题是由于之前的 SIP 帐户仍然链接在应用程序中自动打开不允许任何注册正如解决此帖子的方法所述:“https://stackoverflow.com/questions/49414650/android-native-sip-stack-not-registering-client”,但我不知道如何处理这个问题,在 onDestroy、onPause 中引入 closelocalprofile 函数没有效果。此外,直到最近,它仍然显示消息“SipManager is ready for calls”并且它是打开的,但是现在它没有了,尽管代码没有更改,所以问题可能不一定是这个。

在打印方面显示了以下消息
- 没有与状态相关联的消息显示
- 日志显示Creating ManagerBuilding a new profile”。

此外我已经具备了支持 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() // 点击事件
        {
            @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("尝试结束通话时出错。 " + e);
                }
            }
        });
    }

    public void initManager() // SIPMANAGER
    {
        if(sipManager == null)
        {
            sipManager = SipManager.newInstance(this); // 创建管理器实例。如果不支持 SIP API,则返回 null
            Log.d("Manager", "创建 Manager");
        }

        initLocalProfile();
    }
    public void initLocalProfile()
    {
        if (sipManager == null)
        {
            Log.d("Manager", "没有 Manager");
            return;
        }
        if (sipProfile != null)
        {
            Log.d("Profile", "已经有一个配置文件 1");
            closeLocalProfile();
        }

       // 本地配置数据
       String user = "x";
       String domain = "xxx";
       String pass = "zzzz";

       try
       {
           Log.d("Profile", "正在构建新配置文件");
           SipProfile.Builder builder = new SipProfile.Builder(user, domain); // SIP 帐户的用户和 SIP 服务器域
           builder.setPassword(pass); // 设置 SIP 帐户的密码
           builder.setOutboundProxy(domain); // 设置 SIP 服务器的出站代理
           builder.setPort(5060); // 端口号
           builder.setProtocol("UDP");
           builder.setAutoRegistration(false);

           sipProfile = builder.build(); // 构建并返回 SIP 配置文件对象。

           Intent sipIntent = new Intent(); // 呼叫的 intent
           sipIntent.setAction("android.Login.INCOMING_CALL");
           PendingIntent pi = PendingIntent.getBroadcast(this, 0, sipIntent, Intent.FILL_IN_DATA);
           sipManager.open(sipProfile, pi, null); // 打开配置文件以进行呼叫和/或接收通用 SIP 呼叫

           // 设置监听器以侦听注册事件。如果配置文件尚未打开以接收呼叫,则没有效果

           sipManager.setRegistrationListener(sipProfile.getUriString(), new SipRegistrationListener()
            {
               public void onRegistering(String localProfileUri)
               {
                   // 当发送注册请求时调用
                   status("正在注册");
               }
               public void onRegistrationDone(String localProfileUri, long expiryTime)
               {
                   // 当注册成功时调用
                    status("准备就绪");
               }
               public void onRegistrationFailed(String localProfileUri, int errorCode, String errorMessage)
               {
                   // 当注册失败时调用
                    status("注册失败 " + localProfileUri + errorCode + errorMessage );
               }
           });
           if (sipManager.isRegistered(sipProfile.getUriString()))
           {
               Log.d("Profile","SipManager 准备就绪");
           }
           if (sipManager.isOpened(sipProfile.getUriString()))
           {
               Log.d("Profile","SipManager 已打开");
           }
       }
       catch (ParseException pe)
       {
            status("连接错误");
       }
       catch (SipException sipe) // 如果调用 SIP 服务会产生错误
       {
           status("SIP 出错 " + sipe);
       }
       catch (SecurityException se)
       {
           status("安全性出错" + se);
       }
       catch (RuntimeException re)
       {
           status("运行时出错" + re);
       }
       catch (Exception e)
       {
           status("出错" + e);
       }
    }
    public void closeLocalProfile()
    {
        if (sipManager == null)
        {
            Log.d("Manager", "没有 Manager 1");
            return;
        }
        try
        {
            if (sipProfile != null)
            {
                Log.d("Profile", "已经有一个配置文件 2");
                sipManager.close(sipProfile.getUriString()); // 关闭指定的配置文件以不进行/接收通话
            }
        }
        catch (SipException se) // 如果调用 SIP 服务会产生错误
        {
           

<details>
<summary>英文:</summary>

I have been developing an app that ables the user to call and receive calls using SIP inspired the by the SIPDemo, in which up until i unsinstalled the app from my phone it worked fine, it did the registration, showed the message &quot;Ready&quot; and then proceeded to do the call treatment. Now it does not enter the Sipregistrationlistener and displays the error &quot;Error when trying to close manager 1 SipException:Failed to create SipSession; network unavailable?&quot;. 

From what I understand I suspect that the problem is due to the fact that the previous SIP account is still linked and therefore automatically opened in the app, not letting any registration, as stated in the solution to this post &quot;https://stackoverflow.com/questions/49414650/android-native-sip-stack-not-registering-client&quot;, but I have no clue on how to deal with this, introducing the closelocalprofile function on the onDestroy, onPause did no effect. Besides up until recently it did showed the messages &quot;SipManager is ready for calls&quot; and that it was opened, but now it doesn&#39;t despite not changing anything in the code so the problem might not be necessarily this.

In terms of printing the following messages are shown:
-no message associated to the status are shown;
-the log shows &quot;Creating Manager&quot; &amp; &quot;Building a new profile&quot;;

Furthermore i already have the permissions and the manifest coded to support SIP comunnications.

I know by now that this stack is not the best but I would like not to abandon this project so any help or tips would be much appreciated.
In last case, in preparation if no solution/progress is found, if any of you could also give recomendations to an alternative stack that is similar that would be also appreciated.
 
Here is the code:

    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(&quot;Error when trying to end call. &quot; + 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(&quot;Manager&quot;, &quot;Creating Manager&quot;);
        }

        initLocalProfile();
    }
    public void initLocalProfile()
    {
        if (sipManager == null)
        {
            Log.d(&quot;Manager&quot;, &quot;There is no manager&quot;);
            return;
        }
        if (sipProfile != null)
        {
            Log.d(&quot;Profile&quot;, &quot;There is already a profile 1&quot;);
            closeLocalProfile();
        }

       //localprofiledata
       String user = &quot;x&quot;;
       String domain = &quot;xxx&quot;;
       String pass = &quot;zzzz&quot;;

       try
       {
           Log.d(&quot;Profile&quot;, &quot;Building a new profile&quot;);
           SipProfile.Builder builder = new SipProfile.Builder(user, domain); //user of the SIP account &amp; 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(&quot;UDP&quot;);
           builder.setAutoRegistration(false);

           sipProfile = builder.build();//Builds and returns the SIP profile object.

           Intent sipIntent = new Intent();//intent for the calls
           sipIntent.setAction(&quot;android.Login.INCOMING_CALL&quot;);
           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(&quot;Registering&quot;);
               }
               public void onRegistrationDone(String localProfileUri, long expiryTime)
               {
                   //Called when the registration succeeded
                    status(&quot;Ready&quot;);
               }
               public void onRegistrationFailed(String localProfileUri, int errorCode, String errorMessage)
               {
                   //Called when the registration failed
                    status(&quot;Registration Failed &quot; + localProfileUri + errorCode + errorMessage );
               }
           });
           if (sipManager.isRegistered(sipProfile.getUriString()))
           {
               Log.d(&quot;Profile&quot;,&quot;SipManager is ready for calls&quot;);
           }
           if (sipManager.isOpened(sipProfile.getUriString()))
           {
               Log.d(&quot;Profile&quot;,&quot;SipManager is open&quot;);
           }
       }
       catch (ParseException pe)
       {
            status(&quot;Connection Error&quot;);
       }
       catch (SipException sipe)//if calling the SIP service results in an error
       {
           status(&quot;Error with SIP &quot; + sipe);
       }
       catch (SecurityException se)
       {
           status(&quot;Error with security&quot; + se);
       }
       catch (RuntimeException re)
       {
           status(&quot;Error with runtime&quot; + re);
       }
       catch (Exception e)
       {
           status(&quot;Error&quot; + e);
       }
    }
    public void closeLocalProfile()
    {
        if (sipManager == null)
        {
            Log.d(&quot;Manager&quot;, &quot;There is no manager 1&quot;);
            return;
        }
        try
        {
            if (sipProfile != null)
            {
                Log.d(&quot;Profile&quot;, &quot;There is already a profile 2&quot;);
                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(&quot;Error while closing SIP&quot; + se);
        }
    }

    public void initCall()
    {
        callstatus(&quot;Adress: &quot; + sipAddress);

        try
        {
            SipAudioCall.Listener listener = new SipAudioCall.Listener() //Listener for events relating to a SIP call, such as when a call is being recieved (&quot;on ringing&quot;) or a call is outgoing (&quot;on calling&quot;)
            {
                @Override
                public void onCalling(SipAudioCall call)
                {
                    Log.d(&quot;initCall&quot;, &quot;Initiating session! &quot; + sipAddress);
                }
                @Override
                public void onCallEstablished(SipAudioCall call)
                {
                    Log.d(&quot;initCall&quot;, &quot;Call started! &quot; + 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(&quot;initCall&quot;, &quot;Ringing &quot; + sipAddress);
                }
                @Override
                public void onRingingBack(SipAudioCall call) //Called when a RINGING response is received for the INVITE request sent
                {
                    Log.d(&quot;initCall&quot;, &quot;Ringing back &quot; + sipAddress);
                }
                @Override
                public void onCallBusy(SipAudioCall call)
                {
                    Log.d(&quot;initCall&quot;, &quot;Call busy &quot; + sipAddress);
                }
                @Override
                public void onCallEnded(SipAudioCall call)
                {
                        Log.d(&quot;initCall&quot;, &quot;Call Over &quot;);
                        call.close();
                }
                @Override
                public void onError(SipAudioCall call, int errorCode, String errorMessage)
                {
                    //super.onError(call, errorCode, errorMessage);
                    Log.d(&quot;initCall&quot;, &quot;Error! &quot; + errorMessage + errorCode);
                }
            };
            //the call object that carries out the audio call
            call = sipManager.makeAudioCall(sipProfile.getUriString(), sipAddress, listener, 30);
        }
        catch (Exception e)
        {
            status(&quot;Error when trying to close manager 1. &quot; + e);
            if (sipProfile != null)
            {
                try
                {
                    sipManager.close(sipProfile.getUriString());
                }
                catch (Exception ee)
                {
                    status(&quot;Error when trying to close manager 2. &quot; + 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);
    }

Thanks for your time &amp; attention.

   

</details>


# 答案1
**得分**: 1

**更新**

通过在重新安装应用程序并将代码从Android Studio重新发送到手机后重新启动设备的组合方式成功地避开了先前的这些错误正如我之前所述我对错误来源的怀疑是由于这个堆栈存在的错误尽管如此现在它已经可以运行了我对最终的成品感到满意

尽管在这里没有得到任何回应我希望这个帖子能对某人有所帮助

感谢您的时间和关注

<details>
<summary>英文:</summary>

**Update**

Managed to circumnavigate these previous errors by a combination of rebooting the device after reinstalling the app and resending the code from Android Studio to the phone. My suspicions about the source of the error is, as I stated above, due to the bugs that this stack has, nevertheless it now works and I&#39;m satisfied with the finished product.

Despite not getting any response here, I hope that this thread can be of help to somebody.

Thanks for your time &amp; attention.



</details>



huangapple
  • 本文由 发表于 2020年4月6日 07:44:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/61050953.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定