IMS SIP相关的Android终端的想法----来自实验室好友王阳

IMS SIP Android 软终端——电话答录机功能 实现纪要  

实现电话答录机功能,主要想到了两个办法:

1.(这种是我想的,还没实现,出了一点问题,稍后再说)主要逻辑是:当电话响铃10秒后,通过线程发送消息Message,调用Handler处理,发送存储在本地的事先录制好的语音答录内容(文件),然后在远端播放出来。发送文件通过建立MRSP Session进行处理。
上代码:
通过铃声服务SoundService,响铃10秒来触发事件。NgnSoundService.java:

@Override public void startRingTone() { if(mRingtonePlayer == null){ try{ mRingtonePlayer = RingtoneManager.getRingtone(NgnApplication.getContext(), android.provider.Settings.System.DEFAULT_RINGTONE_URI); }catch(Exception e){ e.printStackTrace(); return; } } if(mRingtonePlayer != null){ synchronized(mRingtonePlayer){ mRingtonePlayer.play(); //Added by wangy 20140702 for AnswerPhone features: Thread timer_ansPhone_answer=new Thread(){ @Override public void run(){ try { Thread.sleep(1000*10); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } if(mRingtonePlayer.isPlaying()){//true if no one answer the phone, then start the answer phone. //Message to be sent to the handler,which handles the no_answer_event Message msg_no_answer_send=new Message(); msg_no_answer_send.what=0;//"Ready to send!" String msg_obj_reply=null;//Record Answer Phone Video File to be Transferred. msg_no_answer_send.obj=(Object)msg_obj_reply; //Handler which handles the no_answer_event Looper.prepare(); Handler ansPhone_handler_play_record=new Handler() { public void handleMessage(Message msg) {//send record file switch (msg.what) {//根据收到的消息的what类型处理 case 0: NgnSipService m_send_active_answer_phone_msg=new NgnSipService(); m_send_active_answer_phone_msg.send_active_answer_phone_msg(); Log.v("handler", "Handler===="+msg.arg2);//打印收到的消息 break; default: //super.handleMessage(msg);//这里最好对不需要或者不关心的消息抛给父类,避免丢失消息 break; } } }; ansPhone_handler_play_record.sendMessage(msg_no_answer_send); stopRingTone(); } } }; timer_ansPhone_answer.start(); } } }

@Override public void startRingBackTone() { if (mRingbackPlayer == null) { try { mRingbackPlayer = new ToneGenerator(AudioManager.STREAM_VOICE_CALL, TONE_RELATIVE_VOLUME); } catch (RuntimeException e) { Log.w(TAG, "Exception caught while creating local tone generator: " + e); mRingbackPlayer = null; } } if(mRingbackPlayer != null){ synchronized(mRingbackPlayer){ mRingbackPlayer.startTone(ToneGenerator.TONE_SUP_RINGTONE); } } Thread timer_ansPhone_call=new Thread(){ @Override public void run(){ try { Thread.sleep(1000*10); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } if(mRingtonePlayer.isPlaying()){//true if no one answer the phone, then start the answer phone. //Message to be sent to the handler,which handles the no_answer_event Message msg_no_answer_rec=new Message(); msg_no_answer_rec.what=1;//"Ready to receive!" String msg_obj_rec=null; msg_no_answer_rec.obj=(Object)msg_obj_rec; //Handler which handles the no_answer_event Looper.prepare(); Handler ansPhone_handler=new Handler() { public void handleMessage(Message msg) {//receive remote party's record file,and play it. switch (msg.what) {//根据收到的消息的what类型处理 case 1: NgnSipService m_send_active_answer_phone_msg=new NgnSipService(); m_send_active_answer_phone_msg.rec_active_answer_phone_msg(); Log.v("handler", "Handler===="+msg.arg2);//打印收到的消息 break; default: //super.handleMessage(msg);//这里最好对不需要或者不关心的消息抛给父类,避免丢失消息 break; } } }; Looper.loop(); ansPhone_handler.sendMessage(msg_no_answer_rec); stopRingBackTone(); } } }; timer_ansPhone_call.start(); }

这是主叫端和被叫端对铃声触发的处理。
下面的代码是主要的处理函数。

public void send_active_answer_phone_msg(){ String file_path=Recorder.getFilePath();//path of the record file. if(file_path==null) System.out.println("file not found!"); //final String textToSend = "***|||***"; final String remotePartyUri =NgnSipSession.getRemotePartyUri(); // remote party uri final NgnMsrpSession imSession = NgnMsrpSession.createOutgoingSession(this.getSipStack(), NgnMediaType.FileTransfer, remotePartyUri); if(!imSession.sendFile(file_path)){ Log.e(TAG,"Failed to send"); } else{ Log.d(TAG,"Message sent"); } // release session NgnMsrpSession.releaseSession(imSession); } public void rec_active_answer_phone_msg(){ //retrieve msrp session from broadcast receiver Answer_phone, and get the received file name&&path to play it. BroadcastReceiver ans_phone=new Answer_Phone(); //this.registerReceiver(ans_phone,new IntentFilter(NgnMsrpEventArgs.ACTION_MSRP_EVENT)); } }

发送文件之后,由MRSP Session的callback进行处理,广播接收到文件的事件Event,通过Broadcast Receiver接收该广播并处理(即播放出来)。

public class Answer_Phone extends BroadcastReceiver{ final String LOG_TAG = "AudioRecordTest"; @Override public void onReceive(Context context, Intent intent) { // TODO Auto-generated method stub String a=intent.getStringExtra("eargs"); Log.d(a,"eargs"); //how to retrieve session remains to be done.may be the args things. Bundle bundle=intent.getExtras(); Set<String> keys=bundle.keySet(); for(String key:keys){ Log.d("key",key); } Object[] objArray=(Object[])bundle.get("eargs");// key "eargs" contains 'session Id'and 'type' ,see NgnMsrpSession-->broadcastEvent line718 String [] sessionId_rec=new String [objArray.length];// to retrieve the segment(mainly sessionID, so that we can get transferred filename) in eargs, see NgnMsrpEventArgs, line43 long [] sessionId=new long [objArray.length]; for(int i=0;i<objArray.length;i++){ sessionId_rec[i]=(String)objArray[i]; sessionId[i]=NgnStringUtils.parseLong(sessionId_rec[i],0); NgnMsrpSession mSession=NgnMsrpSession.getSession(sessionId[i]); String mFileName=mSession.getFileName(); //to play the retrieved file MediaPlayer mPlayer = null; mPlayer = new MediaPlayer(); try { //设置要播放的文件 mPlayer.setDataSource(mFileName); mPlayer.prepare(); //播放之 mPlayer.start(); } catch (IOException e) { Log.e(LOG_TAG, "prepare() failed"); } } } }

大功告成。目前问题是,文件传输不成功,底部协议栈仍需处理。
2.(该思路是老师提出来的,应当简便快捷些,还未试验)主要逻辑是:
正常语音电话接收之后,会从麦克捕获音频,然后放入缓冲区发送,语音答录功能只要将该音频源从麦克改为本地已录制的音频文件即可。只是,这需要做一些信令和流程方面的特殊处理。
由于还未尝试该方法,以后再上代码,持续更新。


好友王阳博客:http://blog.163.com/dream_burgeon/blog/static/235007155201466105822370
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值