如何通过Android SipManager SIP栈向手机号发起呼叫?
解决Android SipManager无法呼叫手机号的问题
看起来你遇到的核心问题是SIP到公共电话网(PSTN)的呼叫格式不匹配——那些能正常工作的软SIP电话已经帮你自动处理了手机号到合法SIP URI的转换,但你直接把手机号作为SipProfile的用户名来构造呼叫,SIP服务器无法识别该如何路由到PSTN网络。
下面是具体的解决步骤和代码调整建议:
1. 先确认你的SIP服务商的呼叫规则
不同SIP服务商对手机号/固话的呼叫格式要求不一样,常见的规则有这几种:
- 格式1:手机号(带完整国家码)作为用户名,拼接你的SIP域名,比如
sip:0041766666@your-sip-domain.com - 格式2:无需拼接域名,直接用手机号作为用户名(部分服务商支持内部自动路由到PSTN)
- 格式3:需要添加特殊前缀(比如
0或9)触发PSTN呼叫,比如sip:90041766666@your-sip-domain.com
你可以先打开能正常呼叫的软SIP电话,查看它的呼叫日志(大部分软电话都有信令日志功能),找到INVITE请求里的To头格式,照着这个格式构造SipProfile就不会错。
2. 修改你的SipProfile构造代码
以最通用的格式1为例,调整代码如下:
SipProfile.Builder builder; SipProfile toCall; try { // 正确构造:带国家码的手机号作为用户名,SIP域名保持和注册账号一致 builder = new SipProfile.Builder("0041766666", DOMAIN); // 如果你的服务商要求特定端口/协议,取消以下注释 // builder.setProtocol("UDP"); // builder.setPort(5090); toCall = builder.build(); SipSession.Listener ssl = new SipSession.Listener() { @Override public void onCallEnded(SipSession session) { super.onCallEnded(session); try { if (call != null) { call.endCall(); } } catch (SipException e) { e.printStackTrace(); } session.endCall(); } }; call.makeCall(toCall, manager.createSipSession(profile, ssl), 30); } catch (Exception e) { // 添加异常捕获,方便排查初始化失败问题 e.printStackTrace(); }
如果你的服务商支持格式2,直接用手机号作为用户名,域名仍填你的SIP服务商域名即可。
3. 额外检查项
- 确认你的SIP账号已开通PSTN呼叫权限:部分SIP账号默认仅支持SIP地址互呼,需要额外开通打手机号/固话的权限
- 检查网络连通性:确保Android设备能访问SIP服务器的出站端口(默认5060,部分服务商是5090),没有被防火墙或运营商拦截
- 对比信令排查差异:用Wireshark抓包,对比软电话和你的代码发起的
INVITE请求,看是否有头字段或参数差异(比如Contact头、From头格式)
内容的提问来源于stack exchange,提问作者Tim
相关产品推荐
相关产品推荐

