这几天接触到了sip,研究了两天,用官网的demo跑了一下,其中遇到了很多坑,在此记录
- 拿到demo,迫不及待的扔到AS上运行,这里需要注意的是,sip需要Android2.3以上的版本支持,这里我用的是2.3.3
dependencies { classpath 'com.android.tools.build:gradle:2.3.3' }
- 权限,这里需要注意,需要开启sip权限
<uses-sdk android:minSdkVersion="9" /> <uses-permission android:name="android.permission.USE_SIP" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.VIBRATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.RECORD_AUDIO" /> <uses-feature android:name="android.hardware.sip.voip" android:required="true" /> <uses-feature android:name="android.hardware.wifi" android:required="true" /> <uses-feature android:name="android.hardware.microphone" android:required="true" />
- 接下来注册广播
IntentFilter filter = new IntentFilter(); filter.addAction("android.SipDemo.INCOMING_CALL"); callReceiver = new IncomingCallReceiver(); this.registerReceiver(callReceiver, filter);
- 然后实例SipManager
public void initializeManager() { if(manager == null) { manager = SipManager.newInstance(this); } initializeLocalProfile(); }
- 设置SipProfile,登录到SIP提供程序中,将此设备注册为发送SIP调用到SIP地址的位置 , 注意注意 这里坑的要死,我在这里为手动填写的sip信息,这里的坑在于sip账户,刚接触的小盆友应该不知道,sip账户需要有sip服务器,并且在sip服务器下才能注册,否则注册不上
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext()); String username = prefs.getString("namePref", ""); String domain = prefs.getString("domainPref", ""); String password = prefs.getString("passPref", ""); Log.e(TAG, "initializeLocalProfile: username="+username+" domain="+domain+" password="+password ); if (username.length() == 0 || domain.length() == 0 || password.length() == 0) { showDialog(UPDATE_SETTINGS_DIALOG); return; }
- 然后设置接听电话广播
SipProfile.Builder builder = new SipProfile.Builder(username, domain); builder.setPassword(password); 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);
- 接下来是登录状态的监听,三个状态,等待、成功、失败没啥好说的
manager.setRegistrationListener(me.getUriString(), new SipRegistrationListener() { public void onRegistering(String localProfileUri) { updateStatus("Registering with SIP Server..."); Log.e("Registration","loading"); } public void onRegistrationDone(String localProfileUri, long expiryTime) { updateStatus("Ready"); Log.e("Registration","success"); } public void onRegistrationFailed(String localProfileUri, int errorCode, String errorMessage) { updateStatus("Registration failed. Please check settings."); Log.e("Registration","failed"); } });
- 客户端与SIP的大部分交互将通过侦听器进行
SipAudioCall.Listener listener = new SipAudioCall.Listener() { @Override public void onCallEstablished(SipAudioCall call) { //播出电话对方接通时调用 call.startAudio(); call.setSpeakerMode(true); if(call.isMuted()){ call.toggleMute(); } updateStatus(call); } @Override public void onCallEnded(SipAudioCall call) { //对方挂断时调用。主动挂断不调用 updateStatus("Ready."); } @Override public void onError(SipAudioCall call, int errorCode, String errorMessage) { //无人应答接听时调用 super.onError(call, errorCode, errorMessage); }
- 最后关闭SipProfile
以下几点,是让我差点自杀的地方,注意:public void closeLocalProfile() { if (manager == null) { return; } try { if (me != null) { manager.close(me.getUriString()); } } catch (Exception ee) { Log.d("WalkieTalkieActivity", "Failed to close local profile.", ee); } }
- sip账户,需要有一个sip账户,这个sip账户是sip提供商提供的,需要有可以用的服务器地址,这个账户包括三个部分,用户名,sip地址,密码,官方也有说明x
- 如果你的账号可以用,到这里你应该可以注册成功了,怎么打电话呢,Call someone,这里需要你输入要拨打的地址,坑又来了,我打了好久打不通,后来发现,你拨打的用户,需要 ’用户名@sip地址‘的格式,才能拨出去,用户名是你的要拨打的用户名,也可以是手机号,只要有外拨权限,sip地址是你当前注册的sip地址
官方demo地址:https://github.com/android/platform_development/tree/master/samples/SipDemo
Android官网sip的相关使用的介绍:https://developer.android.com/reference/android/net/sip/package-summary.html
这里官网介绍如何测试sip应用:https://developer.android.com/guide/topics/connectivity/sip.html#testing