Android audio calls using android's sip - android

I developed an application for a customer to internet calling using sip.For that he provided me two valid sip user_id and password. Am Using SIP API for SIP implementation.customer says that the call is not going.he don't get any notification about missed calls when he logged using his account.i cant find any mistakes in the code.please help me .the code is given below.
public class CallActivity extends Activity {
public String sipAddress = null;
public SipManager mSipManager = null;
public SipProfile mSipProfile = null;
public SipAudioCall call = null;
Button b1;
TextView sipadd;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.calling);
sipAddress = (String) getIntent().getExtras().get("sipAddress");
b1 = (Button) findViewById(R.id.sipcallbtnend);
b1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
finish();
}
});
sipadd = (TextView) findViewById(R.id.sipcalltvdialedaddress);
sipadd.setText(sipAddress);
b1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (call != null) {
call.close();
}
finish();
}
});
initializeManager();
}
#Override
public 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();
}
#Override
public void onDestroy() {
super.onDestroy();
if (call != null) {
call.close();
}
closeLocalProfile();
// if (callReceiver != null) {
// this.unregisterReceiver(callReceiver);
// }
}
public void initializeManager() {
if (mSipManager == null) {
mSipManager = SipManager.newInstance(this);
}
initializeLocalProfile();
}
public void initializeLocalProfile() {
if (mSipManager == null) {
return;
}
if (mSipProfile != 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 {
SipProfile.Builder builder = new SipProfile.Builder(username,
domain);
builder.setPassword(password);
builder.setDisplayName(username);
builder.setAuthUserName(username);
mSipProfile = builder.build();
Intent i = new Intent();
i.setAction("android.SipDemo.INCOMING_CALL");
PendingIntent pi = PendingIntent.getBroadcast(this, 0, i,
Intent.FILL_IN_DATA);
mSipManager.open(mSipProfile, pi, null);
//
//
// // This listener must be added AFTER manager.open is called,
// // Otherwise the methods aren't guaranteed to fire.
mSipManager.setRegistrationListener(mSipProfile.getUriString(),
new SipRegistrationListener() {
public void onRegistering(String localProfileUri) {
// updateStatus("Registering with SIP Server...");
Log.d("onRegistering",
"Registering with SIP Server...");
}
public void onRegistrationDone(String localProfileUri,
long expiryTime) {
// updateStatus("Ready");
Log.d("onRegistrationDone",
"RegistrationDone..Ready");
}
public void onRegistrationFailed(
String localProfileUri, int errorCode,
String errorMessage) {
// updateStatus("Registration failed. Please check settings.");
Log.d("onRegistrationFailed", "RegistrationFailed");
}
});
} catch (ParseException pe) {
// updateStatus("Connection Error.");
} catch (SipException se) {
// updateStatus("Connection error.");
}
initiateCall();
}
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);
}
}
public void initiateCall() {
// updateStatus(sipAddress);
Log.d("nzm", "initiatecall");
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.
#Override
public void onCallEstablished(SipAudioCall call) {
call.startAudio();
call.setSpeakerMode(true);
call.toggleMute();
Log.d("on call established", "on call established");
// updateStatus(call);
}
#Override
public void onCallEnded(SipAudioCall call) {
// updateStatus("Ready.");
// Intent i = new
// Intent(getBaseContext(),DialActivity.class);
// startActivity(i);
finish();
}
};
call = mSipManager.makeAudioCall(mSipProfile.getUriString(), sipAddress,
listener, 3000);
Log.d("call", "" + call.getState());
} catch (Exception e) {
Log.i("WalkieTalkieActivity/InitiateCall",
"Error when trying to close manager.", e);
if (mSipProfile != null) {
try {
mSipManager.close(mSipProfile.getUriString());
} catch (Exception ee) {
Log.i("WalkieTalkieActivity/InitiateCall",
"Error when trying to close manager.", ee);
ee.printStackTrace();
}
}
if (call != null) {
call.close();
}
}
}
}
The permissions in manifest is given below
<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" />
please help me .Thanks in Advance.

Maybe add these
<uses-permission android:name="android.permission.CONFIGURE_SIP" />
<uses-feature android:name="android.software.sip" android:required="true" />
<uses-feature android:name="android.software.sip.voip" android:required="true" />
<uses-feature android:name="android.hardware.telephony" android:required="false" />
Are you using the android's example? It should work on device that support SIP.
And add receiver in onCreate
IntentFilter filter = new IntentFilter();
filter.addAction("android.SipDemo.INCOMING_CALL");
callReceiver = new IncomingCallReceiver();
this.registerReceiver(callReceiver, filter);

Do you have this in manifest?:
<receiver android:name=".IncomingCallReceiver" android:label="Call Receiver"/>
See:
https://developer.android.com/guide/topics/connectivity/sip.html
and
https://android.googlesource.com/platform/development/+/master/samples/SipDemo/

Related

Phone is suspended when making outbound calls using TelephonyManager

Hello and thanks for your help in advanve,
So I've run into a problem while developing this production code. In some instances the phone seems to be freeze when making outbound calls, this code has been inherited by me to help solve this issue with refactoring and refactor the code. So I'm looking for alternative solutions as well as a fix for this issue.
So my current implementation is using a broadcast receiver to check the state of the phone in the onRecieve() method as shown below
public PhonecallService() {
mApiService = new ApiService();
}
#Override
public void onReceive(Context context, Intent intent) {
Timber.d("ONRECIEVE Service");
String stateStr = intent.getExtras() != null ? intent.getExtras().getString(TelephonyManager.EXTRA_STATE) : "";
String number = intent.getExtras() != null ? intent.getExtras().getString(TelephonyManager.EXTRA_INCOMING_NUMBER) : "";
try {
if (intent.getAction().equals("android.intent.action.NEW_OUTGOING_CALL")) {
savedNumber = intent.getExtras().getString("android.intent.extra.PHONE_NUMBER");
} else {
int state = 0;
if (stateStr != null) {
if (stateStr.equals(TelephonyManager.EXTRA_STATE_IDLE)) {
state = TelephonyManager.CALL_STATE_IDLE;
} else if (stateStr.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) {
state = TelephonyManager.CALL_STATE_OFFHOOK;
} else if (stateStr.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
state = TelephonyManager.CALL_STATE_RINGING;
}
}
onCallStateChanged(context, state, number);
}
} catch (Exception e) {
e.printStackTrace();
}
}
This then should call this method and check the state of the phone to then send a broadcast like so:
public void onCallStateChanged(Context context, int state, String number) {
if (lastState == state) {
return;
}
switch (state) {
case TelephonyManager.CALL_STATE_RINGING:
if (number != null) {
isIncoming = true;
callStartTime = new Date();
savedNumber = number;
onIncomingCallStarted(context, number, callStartTime);
lastState = state;
}
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
if (lastState != TelephonyManager.CALL_STATE_RINGING) {
isIncoming = false;
callStartTime = new Date();
onOutgoingCallStarted(context, savedNumber, callStartTime);
} else {
isIncoming = true;
callStartTime = new Date();
onIncomingCallAnswered(context, savedNumber, callStartTime);
}
lastState = state;
break;
case TelephonyManager.CALL_STATE_IDLE:
if (lastState == TelephonyManager.CALL_STATE_RINGING) {
onMissedCall(context, savedNumber, callStartTime);
} else if (isIncoming) {
onIncomingCallEnded(context, savedNumber, callStartTime, new Date());
} else {
onOutgoingCallEnded(context, savedNumber, callStartTime, new Date());
}
lastState = state;
break;
}
}
This is then handled in the CallOutFragment
public class CallOutFragment extends BaseFragment<MainViewModel, CallOutFragmentBinding> {
private BroadcastReceiver mKeypadBroadCastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
viewModel.getmIncomingCall().postValue(true);
}
};
private BroadcastReceiver mBroadCastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
viewModel.getmIncomingCall().postValue(true);
}
};
#Override
public Class<MainViewModel> getViewModel() {
return MainViewModel.class;
}
#Override
public int getLayoutRes() {
return R.layout.call_out_fragment;
}
public static CallOutFragment newInstance() {
Bundle args = new Bundle();
CallOutFragment fragment = new CallOutFragment();
fragment.setArguments(args);
return fragment;
}
#Override
public void onDestroy() {
super.onDestroy();
if (getActivity() != null) {
if (mBroadCastReceiver.isOrderedBroadcast()) {
try {
getActivity().unregisterReceiver(mBroadCastReceiver);
} catch (Exception e) {
e.printStackTrace();
}
}
}
if (mKeypadBroadCastReceiver.isOrderedBroadcast()) {
try {
getActivity().unregisterReceiver(mKeypadBroadCastReceiver);
} catch (Exception e) {
e.printStackTrace();
}
}
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getActivity() != null) {
if (mBroadCastReceiver.isOrderedBroadcast()) {
getActivity().registerReceiver(mBroadCastReceiver, new IntentFilter(Constants.PREFERENCES_CALL_OUT_CLOSE_BROADCAST));
}
if (mKeypadBroadCastReceiver.isOrderedBroadcast()) {
getActivity().registerReceiver(mKeypadBroadCastReceiver, new IntentFilter(Constants.KEYPAD_BROADCAST));
}
}
setHasOptionsMenu(false);
}
#Override
public void onPause() {
if (getActivity() != null) {
if (!mBroadCastReceiver.isOrderedBroadcast()) {
try {
getActivity().unregisterReceiver(mBroadCastReceiver);
} catch (Exception e) {
e.printStackTrace();
}
}
if (!mKeypadBroadCastReceiver.isOrderedBroadcast()) {
try {
getActivity().unregisterReceiver(mKeypadBroadCastReceiver);
} catch (Exception e) {
e.printStackTrace();
}
}
}
getActivity().registerReceiver(mBroadCastReceiver, new IntentFilter(Constants.PREFERENCES_CALL_OUT_CLOSE_BROADCAST));
getActivity().registerReceiver(mKeypadBroadCastReceiver, new IntentFilter(Constants.KEYPAD_BROADCAST));
super.onPause();
}
#Override
public void onResume() {
super.onResume();
if (getActivity() != null) {
getActivity().registerReceiver(mBroadCastReceiver, new IntentFilter(Constants.PREFERENCES_CALL_OUT_CLOSE_BROADCAST));
getActivity().registerReceiver(mKeypadBroadCastReceiver, new IntentFilter(Constants.KEYPAD_BROADCAST));
}
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
setHasOptionsMenu(false);
viewModel.getmDialerContactsFilter().postValue(null);
if (getActivity() != null) {
((MainActivity) getActivity()).hideFloatingDialer();
}
viewModel.getmIncomingCall().observe(this, incomingCall -> {
if (incomingCall != null && incomingCall) {
viewModel.getmSelectedNumber().postValue(null);
if (!Fragments.DIALER.equals(FragmentUtils.callOutPreviousFragment)) {
((MainActivity) getActivity()).showFloatingDialer();
}
if (FragmentUtils.currFragment != FragmentUtils.callOutPreviousFragment && FragmentUtils.callOutPreviousFragment != null) {
FragmentUtils.switchFragment((AppCompatActivity) getActivity(), FragmentUtils.callOutPreviousFragment);
}
}
});
String number = viewModel.getmSelectedNumber().getValue();
viewModel.getmOutCallStatus().observe(this, apiCallStatus -> {
if (apiCallStatus != null) {
if (apiCallStatus.getStatus().equals(Status.ERROR)) {
showOkDialog("Outbound call failed please check network", viewModel.getmMode().getValue(),
dialog -> viewModel.getmIncomingCall().postValue(true));
}
}
});
viewModel.getmOutCallDeclineStatus().observe(this, apiCallStatus -> {
if (apiCallStatus != null) {
viewModel.getmIncomingCall().postValue(true);
}
});
if (viewModel.getmConversationId().getValue() == null && viewModel.getmOutCallStatus().getValue() == null) {
if (number != null) {
viewModel.callRemoteNumber(number);
} else {
viewModel.getmIncomingCall().postValue(true);
}
}
Pair<String, String> numberDescription = viewModel.findNumberDescription(number);
if (numberDescription != null) {
dataBinding.outCallName.setText(numberDescription.first);
} else {
if (number != null) {
dataBinding.outCallName.setText(PhonecallService.getNumberSmart(number));
} else {
getString(R.string.number_unknown);
}
}
final Handler handler = new Handler();
Runnable runnable = new Runnable() {
int count = 0;
#Override
public void run() {
try {
count++;
if (getActivity() != null) {
if (count == 1) {
dataBinding.outTextview.setText(String.format("%s.", getActivity().getResources().getString(R.string.call_out_call)));
} else if (count == 2) {
dataBinding.outTextview.setText(String.format("%s..", getActivity().getResources().getString(R.string.call_out_call)));
} else if (count == 3) {
dataBinding.outTextview.setText(String.format("%s...", getActivity().getResources().getString(R.string.call_out_call)));
}
if (count == 3)
count = 0;
}
handler.postDelayed(this, 2 * 500);
} catch (Exception e) {
Timber.e(e);
}
}
};
handler.postDelayed(runnable, 500);
final Handler closeHandler = new Handler();
Runnable closeRunnable = () -> {
try {
if (Objects.equals(viewModel.getmIncomingCall().getValue(), false)) {
viewModel.getmIncomingCall().postValue(true);
viewModel.timeoutCall();
viewModel.getmDisplayAlert().postValue(getResources().getString(R.string.call_out_fail));
}
} catch (Exception e) {
Timber.e(e);
}
};
closeHandler.postDelayed(closeRunnable, 20000);
dataBinding.getRoot().setFocusableInTouchMode(true);
dataBinding.getRoot().requestFocus();
dataBinding.getRoot().setOnKeyListener((v, keyCode, event) -> {
if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) {
viewModel.getmIncomingCall().postValue(true);
return true;
}
return false;
});
return dataBinding.getRoot();
}
}
Some of my suspicions have come from how the manifest has been set up so here are the permissions set up in it alongside the receiver settings;
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ANSWER_PHONE_CALLS" />
<uses-permission android:name="android.permission.READ_CALL_LOG" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
<receiver
android:name="com.teliqo.pipcall.services.PhonecallService"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.android.vending.INSTALL_REFERRER" />
<action android:name="android.intent.action.ANSWER" />
<action android:name="android.intent.action.CALL_BUTTON" />
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>
This occurs quite randomly and haven't been able to generate a crash report, the only thing that has I've been able to observe is that the fragment is being called numerous times.
My question is;
1) Is there a reason as to why the phone is frozen when making a call?
2) Is there an alternative, cleaner way to implement this fix?
Thank you very much in advance and I'm open to any suggestions that could help solve this issue

Audio thread SIP Android

I have a connection with SIP server(Asterisk), but micro and dynamics doesn't work. Asterisk kicks client in 31 seconds(Empty RTP thread). Documentation by Google says:
Android provides an API that supports the Session Initiation Protocol (SIP). This lets you add SIP-based internet telephony features to your applications. Android includes a full SIP protocol stack and integrated call management services that let applications easily set up outgoing and incoming voice calls, without having to manage sessions, transport-level communication, or audio record or playback directly.
Activity + Receiver:
public class MainActivity extends AppCompatActivity {
public String domain = "192.168.10.37";
public String name = "111";
public String password = "123456";
public String sipAddress = "100#192.168.10.37";
public IncomingCallReceiver receiver;
public SipManager sipManager;
public SipProfile sipProfile;
public SipAudioCall call;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.USE_SIP)
!= PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.USE_SIP)) {
} else {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.USE_SIP},
0);
}
}
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("zlotnikov.SIPexample.INCOMING_CALL");
receiver = new IncomingCallReceiver();
this.registerReceiver(receiver, intentFilter);
initManager();
}
private void initManager() {
if (sipManager == null) {
sipManager = SipManager.newInstance(this);
}
}
private void initializeLocalProfile() {
if (sipProfile != null) {
closeLocalProfile();
}
try {
SipProfile.Builder builder = new SipProfile.Builder(name, domain);
builder.setPassword(password);
builder.setSendKeepAlive(true);
builder.setAutoRegistration(true);
sipProfile = builder.build();
Intent intent = new Intent();
intent.setAction("zlotnikov.SIPexample.INCOMING_CALL");
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, Intent.FILL_IN_DATA);
SipRegistrationListener listener = new SipRegistrationListener() {
#Override
public void onRegistering(String s) {
System.out.println("voip onRegistering " + s);
}
#Override
public void onRegistrationDone(String s, long l) {
System.out.println("voip onRegistrationDone " + s + " " + l);
//initCall();
}
#Override
public void onRegistrationFailed(String s, int i, String s1) {
System.out.println("voip onRegistrationFailed " + s);
}
};
sipManager.open(sipProfile, pendingIntent, null);
//sipManager.register(sipProfile, 40, listener);
sipManager.setRegistrationListener(sipProfile.getUriString(), listener);
} catch (ParseException e) {
e.printStackTrace();
} catch (SipException e) {
e.printStackTrace();
}
}
#Override
protected void onStart() {
super.onStart();
initializeLocalProfile();
}
#Override
protected void onStop() {
super.onStop();
closeLocalProfile();
}
private void closeLocalProfile() {
try {
if (sipProfile != null) {
sipManager.close(sipProfile.getUriString());
}
} catch (Exception ee) {
ee.printStackTrace();
}
}
private void initCall() {
try {
SipAudioCall.Listener listener = new SipAudioCall.Listener() {
#Override
public void onCallEstablished(SipAudioCall call) {
super.onCallEstablished(call);
System.out.println("voip onCallEstablished");
call.startAudio();
call.setSpeakerMode(true);
}
#Override
public void onCallEnded(SipAudioCall call) {
super.onCallEnded(call);
System.out.println("voip onCallEnded");
}
};
call = sipManager.makeAudioCall(sipProfile.getUriString(), sipAddress, listener, 30);
} catch (SipException e) {
closeLocalProfile();
call.close();
e.printStackTrace();
System.out.println("voip MainActivity Конец соединения");
}
}
public class IncomingCallReceiver extends BroadcastReceiver {
private MediaPlayer mediaPlayer;
#Override
public void onReceive(Context context, Intent intent) {
SipAudioCall incomingCall = null;
System.out.println("voip Пришел звонок " + intent.toString());
try {
SipAudioCall.Listener listener = new SipAudioCall.Listener() {
#Override
public void onRinging(SipAudioCall call, SipProfile caller) {
System.out.println("voip onRinging()");
try {
startRinging();
} catch (Exception e) {
stopRinging();
System.out.println("voip onRinging exception");
e.printStackTrace();
}
}
#Override
public void onCallEstablished(SipAudioCall call) {
super.onCallEstablished(call);
System.out.println("voip onCallEstablished()");
stopRinging();
}
#Override
public void onCallEnded(SipAudioCall call) {
super.onCallEnded(call);
System.out.println("voip onCallEnded()");
}
};
incomingCall = sipManager.takeAudioCall(intent, listener);
incomingCall.startAudio();
incomingCall.setSpeakerMode(true);
/*if (incomingCall.isMuted()) {
incomingCall.toggleMute();
}*/
//call = incomingCall;
incomingCall.answerCall(30);
} catch (Exception e) {
if (incomingCall != null) {
incomingCall.close();
System.out.println("voip IncomingCallReceiver конец соединения");
}
}
}
private synchronized void startRinging() {
long[] pattern = {0, 1000, 1000};
((Vibrator) getApplicationContext().getSystemService(Context.VIBRATOR_SERVICE)).vibrate(pattern, 0);
Uri defaultRingtoneUri = RingtoneManager.getActualDefaultRingtoneUri(getApplicationContext(), RingtoneManager.TYPE_RINGTONE);
mediaPlayer = MediaPlayer.create(getApplicationContext(), defaultRingtoneUri);
mediaPlayer.setLooping(true);
mediaPlayer.start();
}
private synchronized void stopRinging() {
((Vibrator) getApplicationContext().getSystemService(Context.VIBRATOR_SERVICE))
.cancel();
if (mediaPlayer != null || mediaPlayer.isPlaying()) mediaPlayer.stop();
}
}
}
Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="zlotnikov.sipexample">
<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.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-feature android:name="android.hardware.sip.voip" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".MainActivity$IncomingCallReceiver" android:label="Call Receiver" />
</application>

Android sip registration failed with error "IN_PROGRESS"

I am working on simple SIP-client Android app.
But when I try to register sipProfile on Server, I get errorCode = -9 and errorMessage= 0.
Here is my activity:
public SipManager sipManager;
private SipProfile sipProfile;
// here is the data, I've just erased it
private String USERNAME = "";
private String AUTHUSERNAME = "";
private String DOMAIN = "";
private String PASSWORD = "";
private int PORT = 5060;
public SipAudioCall call = null;
public String sipAddress = null;
private Button btnRegister, btnCloseProfile;
private TextView tvStatus;
public IncomingCallReceiver callReceiver;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnRegister = (Button) findViewById(R.id.btnRegister);
tvStatus = (TextView) findViewById(R.id.tvStatus);
btnCloseProfile = (Button) findViewById(R.id.btnCloseProfile);
btnRegister.setOnClickListener(register);
btnCloseProfile.setOnClickListener(closeProfile);
IntentFilter filter = new IntentFilter();
filter.addAction("android.SipDemo.INCOMING_CALL");
callReceiver = new IncomingCallReceiver();
this.registerReceiver(callReceiver, filter);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
View.OnClickListener closeProfile = new View.OnClickListener() {
#Override
public void onClick(View v) {
closeLocalProfile();
}
};
View.OnClickListener register = new View.OnClickListener() {
#Override
public void onClick(View v) {
initializeManager();
}
};
void initializeManager(){
if(sipManager == null) {
sipManager = SipManager.newInstance(this);
}
initializeLocalProfile();
}
#Override
protected void onStart() {
super.onStart();
initializeManager();
}
public void initializeLocalProfile(){
if (sipManager == null){
return;
}
if (sipProfile != null){
closeLocalProfile();
}
try {
SipProfile.Builder builder = new SipProfile.Builder(USERNAME, DOMAIN);
builder.setPassword(PASSWORD);
builder.setAuthUserName(AUTHUSERNAME);
sipProfile = builder.build();
Intent intent = new Intent();
intent.setAction("ru.tenet.apdu.INCOMING_CALL");
PendingIntent pi = PendingIntent.getBroadcast(this, 0, intent, Intent.FILL_IN_DATA);
sipManager.open(sipProfile, pi, null);
sipManager.setRegistrationListener(sipProfile.getUriString(), new SipRegistrationListener() {
#Override
public void onRegistering(String localProfileUri) {
updateStatus("Registering with SIP Server...");
}
#Override
public void onRegistrationDone(String localProfileUri, long expiryTime) {
updateStatus("Ready");
}
#Override
public void onRegistrationFailed(String localProfileUri, int errorCode, String errorMessage) {
updateStatus("Registration failed with error:\n" + SipErrorCode.toString(errorCode) +"\n"+errorMessage);
}
});
}
catch (SipException e){
e.printStackTrace();
updateStatus("SipException");
} catch (ParseException e) {
e.printStackTrace();
updateStatus("ParseException");
}
}
#Override
protected void onDestroy() {
super.onDestroy();
if (call != null) {
call.close();
}
closeLocalProfile();
if (callReceiver != null) {
this.unregisterReceiver(callReceiver);
}
}
public void closeLocalProfile() {
if (sipManager == null) {
return;
}
try {
if (sipProfile != null) {
sipManager.close(sipProfile.getUriString());
}
} catch (Exception ee) {
Log.d("StatusWindow/onDestroy", "Failed to close local profile.", ee);
}
}
void updateStatus(final String status){
Log.d("mylog","status = " +status);
runOnUiThread(new Runnable() {
#Override
public void run() {
tvStatus.setText(status);
}
});
}
public void updateStatus(SipAudioCall call) {
String useName = call.getPeerProfile().getDisplayName();
if(useName == null) {
useName = call.getPeerProfile().getUserName();
}
updateStatus(useName + "#" + call.getPeerProfile().getSipDomain());
}
And my Permissions:
<uses-permission android:name="android.permission.USE_SIP"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<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" />
If I try with following code:
sipManager.open(sipProfile, pi, null);
sipManager.register(sipProfile, 20, new SipRegistrationListener() {
#Override
public void onRegistering(String localProfileUri) {
updateStatus("Registering with SIP Server...");
}
#Override
public void onRegistrationDone(String localProfileUri, long expiryTime) {
updateStatus("Ready");
}
#Override
public void onRegistrationFailed(String localProfileUri, int errorCode, String errorMessage) {
updateStatus("Registration failed with error:\n" + SipErrorCode.toString(errorCode) +"\n"+errorMessage);
}
});
I get SipException:
android.net.sip.SipException: SipService.createSession() returns null
FIXED
It looks like one of the sip sessions has been frozen on device.
After physical reboot I got my registration
In case this error you need close local profile and repeat create session
manager.setRegistrationListener(me.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) {
if(errorCode == SipErrorCode.IN_PROGRESS) {
closeLocalProfile();
try {
manager.open(me, pi, null);
} catch (SipException e) {
e.printStackTrace();
}
}
}
});
After lot of searching and going through multiple stackoverflow answers and wasting 2 days on registration errors, here are the things that you should consider to get the registration done ! These worked for me. Reply to this answer if they work for you too :)
Check for the following your code:
First of all, check whether all required permissions are given or not
Use open method instead of register & close instead of unregister
Set your SipRegisterationListener after calling open method, pass null as a parameter in open method for listener and call sipManager.setRegisterationListener(listener) to set the listener.
Your domain must not include port number it should be simple server domain link ; For example com.google.com
First try running the app without setting the port number in SipProfile.Builder ; if that fails, add port manually using builder.setPort(xxxx)
Try changing the protocol. Currently only UDP & TCP are the options available as mentioned in this documentation
Check that your profile uri built is of the format sip:<username>#<domain>. For example if the username is abcd and domain is com.google.com, the SipProfile uri string should be sip:abcd#com.google.com
Try the following things if your android code is correct :
Check the username and password properly / try some other username and password. Before trying with other credentials, close the existing SipProfile until is is successfully closed.
Clear data of Phone Service system apps from your phone
Clear data of your developed SIP app also
Close any open / existing SIP accounts on the device from Phone > Settings > Calling Accouts > Sip Accounts;
Reboot your phone

I want to make a voip Call using my program

I'm currently developing an application for making VoIP/SIP calls, but I don't know why I cannot make a call to a number using my program. I have a valid SIP server_id, password and domain. Using that domain call can be made. Programming code is given below. Can anyone help me out?
public class CallActivity extends Activity {
public String sipAddress = "nizamcs#sip2sip.info";
public SipManager manager = null;
public SipProfile me = null;
public SipAudioCall call = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.calling);
initializeManager();
}
public void initializeManager() {
if (manager == null) {
manager = SipManager.newInstance(this);
}
initializeLocalProfile();
}
public void initializeLocalProfile() {
if (manager == null) {
return;
}
if (me != null) {
closeLocalProfile();
}
String username = "my_username";
String domain = "my_domain";
String password = "my_password";
if (username.length() == 0 || domain.length() == 0 || password.length() == 0) {
return;
}
try {
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) {
Log.d("onRegistering", "Registering with SIP Server...");
}
public void onRegistrationDone(String localProfileUri, long expiryTime) {
Log.d("onRegistrationDone", "RegistrationDone..Ready");
}
public void onRegistrationFailed(String localProfileUri, int errorCode,
String errorMessage) {
Log.d("onRegistrationFailed", "RegistrationFailed");
}
});
} catch (ParseException pe) {
} catch (SipException se) {
}
initiateCall();
}
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);
}
}
public void initiateCall() {
try {
SipAudioCall.Listener listener = new SipAudioCall.Listener() {
#Override
public void onCallEstablished(SipAudioCall call) {
call.startAudio();
call.setSpeakerMode(true);
call.toggleMute();
// updateStatus(call);
}
#Override
public void onCallEnded(SipAudioCall call) {
}
};
call = manager.makeAudioCall(me.getUriString(), sipAddress, listener, 300);
}
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();
}
}
}
}
Please check if your request is being send by using wireshark and see the response you get from the sip server. By doing it you can make sure if the request is actually being send or not.

android sip not receiving any calls

I'm unable to receive any calls on my android SIP application, I can register successfully with the SIP server, I can initiate call and invite other users successfully but I can't receive any calls. I don't think I have anything wrong in my SIP server or my devices as I'm able to use Sipdroid application and initiate and receive calls.
My code is as follows, which is based on SipDemo example:
public class WalkieTalkieActivity extends Activity implements View.OnTouchListener {
public static final String TAG = "WalkieTalkieActivity";
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;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.walkietalkie);
ToggleButton pushToTalkButton = (ToggleButton) findViewById(R.id.pushToTalk);
pushToTalkButton.setOnTouchListener(this);
// Set up the intent filter. This will be used to fire an
// IncomingCallReceiver when someone calls the SIP address used by this
// application.
IntentFilter filter = new IntentFilter();
filter.addAction("android.SipDemo.INCOMING_CALL");
callReceiver = new IncomingCallReceiver();
this.registerReceiver(callReceiver, filter);
// "Push to talk" can be a serious pain when the screen keeps turning off.
// Let's prevent that.
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
initializeManager();
}
#Override
public 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();
}
#Override
public 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", "XXX");
String domain = prefs.getString("domainPref", "192.168.1.11");
String password = prefs.getString("passPref", "");
if (username.length() == 0 || domain.length() == 0 || password.length() == 0) {
showDialog(UPDATE_SETTINGS_DIALOG);
return;
}
try {
SipProfile.Builder builder = new SipProfile.Builder(username, domain);
builder.setPassword(password);
builder.setOutboundProxy(domain);
builder.setPort(8090);
builder.setProtocol("UDP");
me = builder.build();
Log.d(TAG, "Auto Registration: " + me.getAutoRegistration());
Log.d(TAG, "SipProfile: " + me.getUriString());
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);
Log.d(TAG, "manage.isOpen() " + manager.isOpened(me.getUriString()));
// 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...");
}
public void onRegistrationDone(String localProfileUri, long expiryTime) {
updateStatus("Ready");
Log.d(TAG,"Registration done successfully.....");
Log.d(TAG,"Local Profile URI: " + me.getUriString());
Log.d(TAG,"Local Profile URI: " + me);
}
public void onRegistrationFailed(String localProfileUri, int errorCode,
String errorMessage) {
updateStatus("Registration failed. Please check settings. " + errorMessage);
}
});
} 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.
#Override
public void onCallEstablished(SipAudioCall call) {
call.startAudio();
call.setSpeakerMode(true);
call.toggleMute();
updateStatus(call);
}
#Override
public void onCallEnded(SipAudioCall call) {
updateStatus("Ready.");
}
};
Log.d(TAG,"Calling: " + sipAddress);
call = manager.makeAudioCall(me.getUriString(), sipAddress, listener, 30);
}
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();
}
}
}
}
public class IncomingCallReceiver extends BroadcastReceiver {
public static final String TAG = "IncomingCallReceiver";
/**
* 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) {
Log.d(TAG,"************************* Incoming call received.....");
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.manager.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();
}
}
}
}
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android.sip"
android:versionCode="1"
android:versionName="1.0" >
<application android:icon="#drawable/icon" android:label="SipDemo">
<activity android:name=".WalkieTalkieActivity"
android:configChanges="orientation|keyboardHidden">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name=".SipSettings" android:label="set_preferences"/>
<receiver android:name=".IncomingCallReceiver" android:label="Call Receiver"/>
</application>
<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" />
</manifest>
I list some features and permission that I had in my Manifest.xml, hope it help.
<uses-feature android:name="android.software.sip" android:required="false" />
<uses-feature android:name="android.software.sip.voip" android:required="false" />
<uses-feature android:name="android.hardware.telephony" android:required="false" />
<uses-permission android:name="android.permission.CONFIGURE_SIP" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />

Categories

Resources