Android的联通性-会话发起协议(SIP)(3)

Android的联通性---会话发起协议(SIP)(三)

拨打音频电话

要拨打音频呼叫,就必须具备以下条件:

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类的子类来接收呼叫,这个类具有响应指明呼叫源的Intent对象的能力。因此,你的应用程序要做以下事情:

1. 在AndroidManifest.xml中声明一个<receiver>元素。在SipDemo中的声明是:<receiver android:name=".IncomingCallReceiver" android:label="Call Receiver"/>.

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

3. 用呼叫本地配置文件时,触发你的接收器的PendingIntent对象来初始化本地的配置对象(SipProfile)。

4. 建立一个Intent过滤器来过滤代表呼入的操作。在SipDemo中,这个操作是android.SipDemo.INCOMING_CALL

BroadcastReceiver的子类

要接收呼叫,你的SIP应用程序就必须实现一个BroadcastReceiver的子类。Android系统处理SIP的呼入,并且在收到呼入的时候广播一个“incoming call”的Intent对象(由应用程序定义的)。以下是来自SipDemo的BroadcastReceiver的子类的代码。要看完整的例子,请看SipDemo sample,它包含在SDK的示例中。

/*** 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();

            }

        }

    }

}

建立接收呼叫的Intent过滤器

当SIP服务接到一个新的呼叫的时候,它会发出一个带有由应用程序提供的操作字符串的Intent对象。在SipDemo中,这个操作字符串是android.SipDemo.INCOMING_CALL。

以下来自SipDemo的代码摘要显示了如果用基于操作字符串android.SipDemo.INCOMING_CALL所获得的PendingIntent对象来创建SipProfile对象。PendingIntent对象会在SipProfile对象接收一个呼叫时执行一个广播处理:

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);

该广播会被Intent过滤器截获,然后触发接收器(IncomingCallReceiver)。你可以在你的应用程序清单文件中指定一个Intent过滤器,或者是像SipDemo示例那样在应用程序的Activity的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. 一部运行Android2.3以上系统的移动设备。SIP是运行在无线之上的,因此你必须在实际的设备上测试,在AVD上不能进行测试工作。

2. 一个SIP账号。有很多不同的SIP提供商会提供SIP账号。

3. 如果你要进行呼叫,就必须有一个有效的SIP账号。

测试SIP应用程序:

1. 在你的设备上,接入无线(Setting->Wireless&networks->Wi-Fi->Wi-Fi settings)

2. 把你的移动设备设置为用于调试,设置方法在Developing on a Device中进行了介绍。

3. 在你的移动设备上运行你的应用程序,运行方法在Developing on a Device中进行了介绍。

4. 如果你使用的是Eclipse,你可以使用Eclipse中LogCat来查看应用程序的日志输出(Window->Show View->Other->Android->LogCat)。