链接:SIP

Android提供了支持会话发起协议(SIP)的API。 这样可以为您的应用程序添加基于SIP的互联网电话功能。 Android包括一个完整的SIP协议栈和集成的呼叫管理服务,使应用程序可以轻松地设置拨出和接收语音呼叫,而无需直接管理会话,传输级别通信或音频记录或播放。


以下是可能使用SIP API的应用程序类型的示例:

1、视频会议。

2、即时通讯。



一、要求和限制

以下是开发SIP应用程序的要求:

1、您必须拥有运行Android 2.3或更高版本的移动设备。


2、SIP通过无线数据连接运行,因此您的设备必须具有数据连接(使用移动数据服务或Wi-Fi)。 这意味着您无法在AVD上测试 - 您只能在物理设备上测试。 有关详细信息,请参阅测试SIP应用程序。


3、应用程序通信会话中的每个参与者必须具有SIP帐户。 有许多不同的SIP提供商提供SIP帐户。



二、SIP API类和接口

以下是Android SIP API中包含的类和一个接口(SipRegistrationListener)的摘要:

Class/Interface Description
SipAudioCall 通过SIP处理互联网音频呼叫。
SipAudioCall.Listener 用于与SIP呼叫有关的事件的侦听器,例如当正在接收呼叫(“在振铃”)或呼叫呼出(“在呼叫”)时。
SipErrorCode 定义SIP操作期间返回的错误代码。
SipManager 为SIP任务提供API,例如发起SIP连接,并提供对相关SIP服务的访问。
SipProfile 定义SIP配置文件,包括SIP帐户,域和服务器信息。
SipProfile.Builder 用于创建SipProfile的Helper类。
SipSession 表示与SIP对话或不在对话框内的独立事务相关联的SIP会话。
SipSession.Listener 用于与SIP会话有关的事件的侦听器,例如当会话被注册时(“登记”)或呼叫正在发出(“在呼叫”)。
SipSession.State 定义SIP会话状态,例如“注册”,“呼出”和“在呼叫中”。
SipRegistrationListener 作为SIP注册事件的侦听器的接口。


三、创建清单

如果您正在开发使用SIP API的应用程序,请记住该功能仅在Android 2.3(API第9级)和更高版本的平台上受支持。 此外,在运行Android 2.3(API级别9)或更高版本的设备中,并非所有设备都将提供SIP支持。


要使用SIP,请将以下权限添加到应用程序的清单中:

  • android.permission.USE_SIP
  • android.permission.INTERNET

要确保您的应用程序只能安装在能够支持SIP的设备上,请将以下内容添加到应用程序的清单中:

<uses-sdk android:minSdkVersion="9" />

这表示您的应用程序需要Android 2.3或更高版本。 有关详细信息,请参阅API级别和<uses-sdk>元素的文档。


要控制您的应用程序如何从不支持SIP的设备(例如,在Google Play上)过滤,请将以下内容添加到应用程序的清单中:

<uses-feature android:name="android.hardware.sip.voip" />

这表示您的应用程序使用SIP API。 声明应包括一个android:required属性,指示是否要从不提供SIP支持的设备中过滤应用程序。 也可能需要其他<uses-feature>声明,具体取决于您的实现。 有关更多信息,请参阅<uses-feature>元素的文档。


如果您的应用程序旨在接收呼叫,则还必须在应用程序的清单中定义一个接收器(BroadcastReceiver子类):

<receiver android:name=".IncomingCallReceiver" android:label="Call Receiver" />

这里是SipDemo清单的摘录:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.example.android.sip">
  ...
     <receiver android:name=".IncomingCallReceiver" android:label="Call Receiver" />
  ...
  <uses-sdk android:minSdkVersion="9" />
  <uses-permission android:name="android.permission.USE_SIP" />
  <uses-permission android:name="android.permission.INTERNET" />
  ...
  <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" />
</manifest>



四、创建SipManager

要使用SIP API,您的应用程序必须创建一个SipManager对象。 SipManager在您的应用程序中处理以下内容:

1、启动SIP会话。


2、启动和接听呼叫。


3、使用SIP提供商注册和取消注册。


4、验证会话连接。


您实例化一个新的SipManager如下:

public SipManager mSipManager = null;
...
if (mSipManager == null) {
    mSipManager = SipManager.newInstance(this);
}



五、注册SIP服务器

典型的Android SIP应用程序涉及一个或多个用户,每个用户都有一个SIP帐户。 在Android SIP应用程序中,每个SIP帐户都由SipProfile对象表示。


SipProfile定义SIP配置文件,包括SIP帐户以及域和服务器信息。 与运行应用程序的设备上的SIP帐户关联的配置称为本地配置文件。 会话连接的配置文件称为对等体配置文件。 当您的SIP应用程序使用本地SipProfile登录到SIP服务器时,有效地将设备注册为将SIP呼叫发送到您的SIP地址的位置。


本节介绍如何创建SipProfile,使用SIP服务器注册,并跟踪注册事件。


您创建一个SipProfile对象,如下所示:

public SipProfile mSipProfile = null;
...

SipProfile.Builder builder = new SipProfile.Builder(username, domain);
builder.setPassword(password);
mSipProfile = builder.build();

以下代码片段打开用于进行呼叫和/或接收通用SIP呼叫的本地配置文件。 呼叫者可以通过mSipManager.makeAudioCall进行后续呼叫。 这个节选还会设置动作android.SipDemo.INCOMING_CALL,当设备接收到一个呼叫时,它将被意图过滤器使用(请参阅设置意图过滤器来接收呼叫)。 这是注册步骤:

Intent intent = new Intent();
intent.setAction("android.SipDemo.INCOMING_CALL");
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, Intent.FILL_IN_DATA);
mSipManager.open(mSipProfile, pendingIntent, null);

最后,该代码在SipManager上设置一个SipRegistrationListener。 这将跟踪SipProfile是否已成功注册到您的SIP服务提供商:

mSipManager.setRegistrationListener(mSipProfile.getUriString(), new SipRegistrationListener() {

public void onRegistering(String localProfileUri) {
    updateStatus("Registering with SIP Server...");
}

public void onRegistrationDone(String localProfileUri, long expiryTime) {
    updateStatus("Ready");
}

public void onRegistrationFailed(String localProfileUri, int errorCode,
    String errorMessage) {
    updateStatus("Registration failed.  Please check settings.");
}

当您的应用程序使用配置文件完成时,应该关闭它,以将关联的对象释放到内存中,并从服务器取消注册设备。 例如:

public void closeLocalProfile() {
    if (mSipManager == null) {
       return;
    }
    try {
       if (mSipProfile != null) {
          mSipManager.close(mSipProfile.getUriString());
       }
     } catch (Exception ee) {
       Log.d("WalkieTalkieActivity/onDestroy", "Failed to close local profile.", ee);
     }
}



六、进行音频通话

要进行音频通话,您必须具备以下功能:

1、正在进行呼叫的SipProfile(“本地配置文件”)以及接收呼叫的有效SIP地址(“对等体配置文件”)。

2、SipManager对象。


要进行音频通话,您应该设置一个SipAudioCall.Listener。 客户端与SIP堆栈的大部分交互通过监听器进行。 在这段代码中,您将看到SipAudioCall.Listener在调用建立后如何设置:

SipAudioCall.Listener listener = new SipAudioCall.Listener() {

   @Override
   public void onCallEstablished(SipAudioCall call) {
      call.startAudio();
      call.setSpeakerMode(true);
      call.toggleMute();
         ...
   }

   @Override
   public void onCallEnded(SipAudioCall call) {
      // Do something.
   }
};

一旦你设置了SipAudioCall.Listener,你可以打电话。 SipManager方法makeAudioCall采用以下参数:

1、本地SIP配置文件(呼叫者)。

2、对等SIP配置文件(被叫用户)。

3、SipAudioCall.Listener收听来自SipAudioCall的呼叫事件。 这可以是null,但是如上所示,监听器用于在建立呼叫后设置事件。

4、超时值,以秒为单位。


例如:

call = mSipManager.makeAudioCall(mSipProfile.getUriString(), sipAddress, listener, 30);


七、接收电话

要接收呼叫,SIP应用程序必须包括BroadcastReceiver的子类,该子类能够响应表示有来电的意图。 因此,您必须在应用程序中执行以下操作:

1、在AndroidManifest.xml中,声明一个<receiver>。 在SipDemo中,这是<receiver android:name =“IncomingCallReceiver”android:label =“Call Receiver”/>。

2、实现接收机,它是BroadcastReceiver的一个子类。 在SipDemo中,这是IncomingCallReceiver。

3、初始化本地配置文件(SipProfile),具有在有人呼叫本地配置文件时触发接收器的挂起意图。

4、设置一个意图过滤器,通过代表来电的动作进行过滤。 在SipDemo中,此操作是android.SipDemo.INCOMING_CALL。


一)、Subclassing BroadcastReceiver

要接收呼叫,您的SIP应用程序必须对BroadcastReceiver进行子类化。 Android系统在接收到呼叫时处理传入的SIP呼叫并广播“来电”意图(由应用程序定义)。 以下是SipDemo示例中的子类BroadcastReceiver代码。

/**
 * Listens for incoming SIP calls, intercepts and hands them off to WalkieTalkieActivity.
 */
public class IncomingCallReceiver extends BroadcastReceiver {
    /**
     * Processes the incoming call, answers it, and hands it over to the
     * WalkieTalkieActivity.
     * @param context The context under which the receiver is running.
     * @param intent The intent being received.
     */
    @Override
    public void onReceive(Context context, Intent intent) {
        SipAudioCall incomingCall = null;
        try {
            SipAudioCall.Listener listener = new SipAudioCall.Listener() {
                @Override
                public void onRinging(SipAudioCall call, SipProfile caller) {
                    try {
                        call.answerCall(30);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            };
            WalkieTalkieActivity wtActivity = (WalkieTalkieActivity) context;
            incomingCall = wtActivity.mSipManager.takeAudioCall(intent, listener);
            incomingCall.answerCall(30);
            incomingCall.startAudio();
            incomingCall.setSpeakerMode(true);
            if(incomingCall.isMuted()) {
                incomingCall.toggleMute();
            }
            wtActivity.call = incomingCall;
            wtActivity.updateStatus(incomingCall);
        } catch (Exception e) {
            if (incomingCall != null) {
                incomingCall.close();
            }
        }
    }
}

2、设置意图过滤器以接收呼叫

当SIP服务接收到新的呼叫时,它发送一个意图,其中包含应用程序提供的动作字符串。 在SipDemo中,此操作字符串为android.SipDemo.INCOMING_CALL。


来自SipDemo的此代码摘录显示了基于动作字符串android.SipDemo.INCOMING_CALL的SipProfile对象是如何创建的。 当SipProfile接收到一个调用时,PendingIntent对象将执行一个广播:

public SipManager mSipManager = null;
public SipProfile mSipProfile = null;
...

Intent intent = new Intent();
intent.setAction("android.SipDemo.INCOMING_CALL");
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, Intent.FILL_IN_DATA);
mSipManager.open(mSipProfile, pendingIntent, null);

广播将被意图过滤器拦截,然后触发接收器(IncomingCallReceiver)。 您可以在应用程序的清单文件中指定意图过滤器,或者按照应用程序的“活动”的SipDemo示例应用程序的onCreate()方法中的代码进行操作:

public class WalkieTalkieActivity extends Activity implements View.OnTouchListener {
...
    public IncomingCallReceiver callReceiver;
    ...

    @Override
    public void onCreate(Bundle savedInstanceState) {

       IntentFilter filter = new IntentFilter();
       filter.addAction("android.SipDemo.INCOMING_CALL");
       callReceiver = new IncomingCallReceiver();
       this.registerReceiver(callReceiver, filter);
       ...
    }
    ...
}



八、测试SIP应用程序

要测试SIP应用程序,您需要以下内容:

1、运行Android 2.3或更高版本的移动设备。 SIP通过无线方式运行,因此您必须在实际的设备上进行测试。 AVD测试将无法正常工作。


2、SIP帐号。 有许多不同的SIP提供商提供SIP帐户。


3、如果您打电话,也必须是有效的SIP帐户。


测试SIP应用程序:

1、在您的设备上,连接到无线(设置>无线和网络> Wi-Fi> Wi-Fi设置)。


2、设置您的移动设备进行测试,如“开发设备”中所述。


3、在您的移动设备上运行应用程序,如“在设备上开发”中所述。


4、如果您使用的是Android Studio,则可以通过打开事件日志控制台(视图>工具Windows>事件日志)查看应用程序日志输出。


5、确保您的应用程序配置为在运行时自动启动Logcat:

 1)、选择Run > Edit Configurations

 2)、在运行/调试配置窗口中选择 Miscellaneous选项卡。

 3)、在Logcat下,选择自动显示logcat,然后选择OK

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值