Android 自带Sipdemo的使用讲解( 二 )


四:接受电话

Android 自带Sipdemo的使用讲解

文章插图
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. */@Overridepublic void onReceive(Context context, Intent intent) {SipAudioCall incomingCall = null;try {SipAudioCall.Listener listener = new SipAudioCall.Listener() {@Overridepublic 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();}}}}
五:接受到对方挂电话的状态
private Handler handler = new Handler();private void initGetSipSession() {try {SipSession sessionFor = MyApplication.mSipManager.getSessionFor(intent);SipSession.Listener listener = new SipSession.Listener(){@Overridepublic void onCalling(SipSession session) {Logger.i("onCalling");}@Overridepublic void onCallEnded(SipSession session) {Logger.i("onCallEnded");handler.post(new Runnable() {@Overridepublic void run() {ToastView.newInstance(mContext).setToastMessage("通话通断");}});}};sessionFor.setListener(listener);} catch (SipException e) {e.printStackTrace();}}
六:主动挂电话
incomingCall.endCall();
接下来就是要把需要文件也顺便导入进去,如图
废话不多说,直接上全的页面代码
//sip注册// 拨打电话//呼叫喊话//20190904public class MainActivity extends AppCompatActivity {public String sipAddress = null;public SipManager manager = null;public SipProfile me = null;public SipAudioCall call = null;public IncomingCallReceiver callReceiver;private static final int CALL_ADDRESS = 1;private static final int SET_AUTH_INFO = 2;private static final int UPDATE_SETTINGS_DIALOG = 3;private static final int HANG_UP = 4;privateSipProfile.Builder builder;private static final String TAG = "MainActivity";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);if (isNetworkConnected(this)==false){Toast.makeText(this,"暂无网络连接",Toast.LENGTH_SHORT).show();}//申请sip、录音权限//6.0以后的Android不支持静态注册,必须动态注册申请权限verifyAudioPermissions(this);}/*** 判断是否有网络连接** @param context* @return*/public static boolean isNetworkConnected(Context context) {if (context != null) {ConnectivityManager mConnectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();if (mNetworkInfo != null) {return mNetworkInfo.isAvailable();}}return false;}/** 申请sip权限*/private static String[] PERMISSION_SIP = {Manifest.permission.USE_SIP};//申请录音权限private static String[] PERMISSION_AUDIO = {Manifest.permission.RECORD_AUDIO};//申请sdk权限private static String[] PERMISSION_SDK = {Manifest.permission.WRITE_EXTERNAL_STORAGE};public static void verifyAudioPermissions(Activity activity) {int permission = ActivityCompat.checkSelfPermission(activity,Manifest.permission.USE_SIP);int permission_audio = ActivityCompat.checkSelfPermission(activity,Manifest.permission.RECORD_AUDIO);if (permission != PackageManager.PERMISSION_GRANTED) {ActivityCompat.requestPermissions(activity, PERMISSION_SIP,1);}else {Log.e(TAG, "verifyAudioPermissions: sip权限已开启");}if (permission_audio != PackageManager.PERMISSION_GRANTED) {ActivityCompat.requestPermissions(activity, PERMISSION_AUDIO,1);}else {Log.e(TAG, "verifyAudioPermissions: 录音权限已开启");}if (permission_sdk != PackageManager.PERMISSION_GRANTED) {ActivityCompat.requestPermissions(activity, PERMISSION_SDK,1);}else {Log.e(TAG, "verifyAudioPermissions: sdk权限已开启");}}//开始进行sipmanager的注册@Overridepublic void onStart() {super.onStart();// When we get back from the preference setting Activity, assume// settings have changed, and re-login with new auth info.initializeManager();}//销毁的时候把相应开启的空间释放@Overridepublic void onDestroy() {super.onDestroy();if (call != null) {call.close();}closeLocalProfile();if (callReceiver != null) {this.unregisterReceiver(callReceiver);}}public void initializeManager() {//实例化if(manager == null) {manager = SipManager.newInstance(this);}initializeLocalProfile();}/*** Logs you into your SIP provider, registering this device as the location to* send SIP calls to for your SIP address.*/public void initializeLocalProfile() {if (manager == null) {return;}if (me != null) {closeLocalProfile();}SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());String username = prefs.getString("namePref", "");String domain = prefs.getString("domainPref", "");String password = prefs.getString("passPref", "");if (username.length() == 0 || domain.length() == 0 || password.length() == 0) {showDialog(UPDATE_SETTINGS_DIALOG);return;}try {//uesrname表示注册用户名,domain表示域,实际就是sip服务器ipbuilder = new SipProfile.Builder(username, domain);builder.setPassword(password);me = builder.build();//添加一个本地的过滤器,用于接受电话//构造一个PendingIntent对象,这样当sip Service收到一个通话请求时,//SipService会调用PendingIntent的send方法发送相应广播消息给调用者,也就是当前的SipProfile对象.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);// This listener must be added AFTER manager.open is called,// Otherwise the methods aren't guaranteed to fire.//注册一个监听器,用于获取注册账户时的通知状态manager.setRegistrationListener(me.getUriString(), new SipRegistrationListener() {public void onRegistering(String localProfileUri) {updateStatus("Registering with SIP Server...");Log.e(TAG, "onRegistering: "+"请求sip服务中" );}public void onRegistrationDone(String localProfileUri, long expiryTime) {updateStatus("Ready");Log.e(TAG, "onRegistering: "+"sip注册成功" );}public void onRegistrationFailed(String localProfileUri, int errorCode,String errorMessage) {updateStatus("Registration failed.Please check settings.");Log.e(TAG, "onRegistering: "+"sip注册失败" );}});} catch (ParseException pe) {updateStatus("Connection Error.");} catch (SipException se) {updateStatus("Connection error.");}}/*** Closes out your local profile, freeing associated objects into memory* and unregistering your device from the server.*/public void closeLocalProfile() {if (manager == null) {return;}try {if (me != null) {manager.close(me.getUriString());}} catch (Exception ee) {//Log.d("WalkieTalkieActivity/onDestroy", "Failed to close local profile.", ee);}}/*** Make an outgoing call.*/public void initiateCall() {updateStatus(sipAddress);try {SipAudioCall.Listener listener = new SipAudioCall.Listener() {// Much of the client's interaction with the SIP Stack will// happen via listeners.Even making an outgoing call, don't// forget to set up a listener to set things up once the call is established.//准备打电话@Overridepublic void onReadyToCall(SipAudioCall call) {Log.e(TAG, "onReadyToCall: " );}@Overridepublic void onRinging(SipAudioCall call, SipProfile caller) {Log.e(TAG, "onRinging: ");}@Overridepublic void onCallEstablished(SipAudioCall call) {call.startAudio(); //启动音频call.setSpeakerMode(false);//设置为扬声器模式,也就是开启回声抑制//call.toggleMute();//切换静音,注意默认为非静音,调用此方法后变为静音了//必须用下面这样的写法,否则没有任何声音if(call.isMuted()) {call.toggleMute();}updateStatus(call);Log.e(TAG, "onCallEstablished: 内端口"+me.getPort() );}@Overridepublic void onCallEnded(SipAudioCall call) {Log.e(TAG, "onCallEnded: " );updateStatus("Ready....");}};//注意此处的makeAudioCall方法就是打网络电话的,me就是本地设备的SipProfile对象,//sipAddress就是目标设备的SipProfile对象,listener是监听器call = manager.makeAudioCall(me.getUriString(), sipAddress, listener, 30);call.toggleMute();}catch (Exception e) {//Log.i("WalkieTalkieActivity/InitiateCall", "Error when trying to close manager.", e);if (me != null) {try {manager.close(me.getUriString());} catch (Exception ee) {//Log.i("WalkieTalkieActivity/InitiateCall",//"Error when trying to close manager.", ee);ee.printStackTrace();}}if (call != null) {call.close();}}}/*** Updates the status box at the top of the UI with a messege of your choice.* @param status The String to display in the status box.*/public void updateStatus(final String status) {// Be a good citizen.Make sure UI changes fire on the UI thread.this.runOnUiThread(new Runnable() {public void run() {Log.i("allenssip",status);TextView labelView = (TextView) findViewById(R.id.sipLabel);labelView.setText(status);}});}/*** Updates the status box with the SIP address of the current call.* @param call The current, active call.*/public void updateStatus(SipAudioCall call) {String useName = call.getPeerProfile().getDisplayName();if(useName == null) {useName = call.getPeerProfile().getUserName();}updateStatus(useName + "@" + call.getPeerProfile().getSipDomain());}public boolean onCreateOptionsMenu(Menu menu) {menu.add(0, CALL_ADDRESS, 0, "Call someone");menu.add(0, SET_AUTH_INFO, 0, "Edit your SIP Info.");menu.add(0, HANG_UP, 0, "End Current Call.");return true;}public boolean onOptionsItemSelected(MenuItem item) {switch (item.getItemId()) {case CALL_ADDRESS:showDialog(CALL_ADDRESS);break;case SET_AUTH_INFO:updatePreferences();break;case HANG_UP:if(call != null) {try {call.endCall();} catch (SipException se) {//Log.d("WalkieTalkieActivity/onOptionsItemSelected",//"Error ending call.", se);}call.close();}break;}return true;}@Overrideprotected Dialog onCreateDialog(int id) {switch (id) {case CALL_ADDRESS:LayoutInflater factory = LayoutInflater.from(this);final View textBoxView = factory.inflate(R.layout.call_address_dialog, null);return new AlertDialog.Builder(this).setTitle("Call Someone.").setView(textBoxView).setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {public void onClick(DialogInterface dialog, int whichButton) {EditText textField = (EditText)(textBoxView.findViewById(R.id.calladdress_edit));sipAddress = textField.getText().toString();initiateCall();}}).setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {public void onClick(DialogInterface dialog, int whichButton) {// Noop.}}).create();case UPDATE_SETTINGS_DIALOG:return new AlertDialog.Builder(this).setMessage("Please update your SIP Account Settings.").setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {public void onClick(DialogInterface dialog, int whichButton) {updatePreferences();}}).setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {public void onClick(DialogInterface dialog, int whichButton) {// Noop.}}).create();}return null;}public void updatePreferences() {Intent settingsActivity = new Intent(getBaseContext(),SipSettings.class);startActivity(settingsActivity);}}