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>
Related
Currently i'm using PN7150 with android board.
The NFC reader (PN7150) can be used to read type A cards, but cannot detect type B cards at all.
Below is the PCB antenna that I used :
The following is a schematic for the antenna matching circuit:
Smith chart simulation results from RFSim99:
Below is the signal shape (Smith chart) of the measurement results on the PCB board using Nano VNA.
This is my android code :
MainActivity.java
package com.iwjo.nfcfieldstrength;
public class MainActivity extends AppCompatActivity implements NfcAdapter.ReaderCallback, NfcThread.UiCallback{
public static final boolean mbUsbExternalUSBManager = false;
private static final String ACTION_USB_PERMISSION = "com.iwjo.ktpfieldstrength.USB_PERMISSION";
private UsbManager mUsbManager = null;
private PendingIntent mPermissionIntent= null;
public static final int REQUEST_WRITE_PERMISSION = 786;
private static final int REQUEST_WRITE_STORAGE_REQUEST_CODE = 112;
private NfcAdapter nfcadapter;
private String[][] nfctechfilter = new String[][] { new String[] { NfcA.class.getName() } };
private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver(){
public void onReceive(Context context, Intent intent){
String action = intent.getAction();
if(ACTION_USB_PERMISSION.equals(action)){
synchronized(this){
if (action.equals(NfcAdapter.ACTION_ADAPTER_STATE_CHANGED)) {
int state = intent.getIntExtra(NfcAdapter.EXTRA_ADAPTER_STATE,
NfcAdapter.STATE_ON);
if (state == NfcAdapter.STATE_ON
|| state == NfcAdapter.STATE_TURNING_ON) {
///Log.d(TAGCL, "state: " + state);
if (state == NfcAdapter.STATE_ON) {
nfcadapter.enableReaderMode(
MainActivity.this,
MainActivity.this,
NfcAdapter.FLAG_READER_NFC_A
| NfcAdapter.FLAG_READER_NFC_B
//| NfcAdapter.FLAG_READER_NFC_F
//| NfcAdapter.FLAG_READER_NFC_V
//| NfcAdapter.FLAG_READER_NFC_BARCODE
//| NfcAdapter.FLAG_READER_NO_PLATFORM_SOUNDS
| NfcAdapter.FLAG_READER_SKIP_NDEF_CHECK,
null);
}
} else {
showMessage(getString(R.string.nfc_not_activated));
}
}
}
}
}
};
private void requestPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_WRITE_PERMISSION);
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == REQUEST_WRITE_PERMISSION && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
/////--Log.d(TAGSAM, "permission granted");
}
}
#Override
protected void onPostResume() {
//bindComponents();
super.onPostResume();
if (!nfcadapter.isEnabled()) {
showMessage(getString(R.string.nfc_not_activated));
return;
}
IntentFilter filter = new IntentFilter(
NfcAdapter.ACTION_ADAPTER_STATE_CHANGED);
//registerReceiver(mBroadcastReceiver, filter);
nfcadapter.enableReaderMode(this, this, NfcAdapter.FLAG_READER_NFC_A
| NfcAdapter.FLAG_READER_SKIP_NDEF_CHECK | NfcAdapter.FLAG_READER_NFC_B | NfcAdapter.FLAG_READER_NFC_F, null);
}
#Override
protected void onPause() {
super.onPause();
//unregisterReceiver(mBroadcastReceiver);
nfcadapter.disableReaderMode(this);
}
#Override
protected void onDestroy() {
if( mbUsbExternalUSBManager ){
unregisterReceiver(mUsbReceiver);
}
if( mbUsbExternalUSBManager ){
unregisterReceiver(mUsbReceiver);
}
super.onDestroy();
}
#Override
public void showMessage(final String msg) {
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(MainActivity.this, msg, Toast.LENGTH_LONG).show();
}
});
}
#Override
public void setEditText(final int id, final String txt, final int status) {
runOnUiThread(new Runnable() {
#Override
public void run() {
//EditText edit = (EditText) findViewById(id);
//eMessage.setText(txt);
setMessageText(txt, status);
}
});
}
public void setMessageText(String text, int status)
{
// status 0 : normal proses, 1 : berhasil, 2 : error
}
#Override
public void setBiodata(final Biodata bio) {
runOnUiThread(new Runnable() {
#Override
public void run() {
}
});
}
#Override
public void setProgressBar(final int id, final int value) {
runOnUiThread(new Runnable() {
#Override
public void run() {
ProgressBar pbar = (ProgressBar) findViewById(id);
pbar.setProgress(value);
}
});
}
private void setErrorMessage(String text)
{
//eMessage.setBackground(Color.red());
}
#Override
public void onTagDiscovered(Tag tag) {
if(isSam_authenticate) {
Runnable nfcr = new NfcThread(this, tag, this);
new Thread(nfcr).start();
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ActionBar actionBar = getSupportActionBar();
//actionBar.setIcon(R.mipmap.ic_launcher);
actionBar.setDisplayShowHomeEnabled(true);
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
progressBar = (ProgressBar) findViewById(R.id.progressBar);
eMessage = (TextView) findViewById(R.id.eMessage);
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
try {
nfcadapter = NfcAdapter.getDefaultAdapter(this);
if (nfcadapter == null) {
Toast.makeText(this, getString(R.string.nfc_unavailable), Toast.LENGTH_LONG).show();
finish();
}
} catch (Exception f) {
}
mainContext = this;
requestAppPermissions();
}
private void requestAppPermissions() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
return;
}
if (hasReadPermissions() && hasWritePermissions()) {
return;
}
ActivityCompat.requestPermissions(this,
new String[] {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
}, REQUEST_WRITE_STORAGE_REQUEST_CODE); // your request code
}
private boolean hasReadPermissions() {
return (ContextCompat.checkSelfPermission(getBaseContext(), Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED);
}
private boolean hasWritePermissions() {
return (ContextCompat.checkSelfPermission(getBaseContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED);
}
}
NfcThread.java
package com.iwjo.nfcfieldstrength;
import android.content.Context;
import android.nfc.Tag;
import android.nfc.tech.IsoDep;
import android.util.Log;
import com.iwjo.ktpfieldstrength.R;
import java.io.IOException;
public class NfcThread implements Runnable {
public static final String TAG_CL_IN = ">>";
public static final String TAG_CL_OUT = "<<";
public interface UiCallback {
void showMessage(String msg);
void setEditText(int id, String txt, int status);
void setBiodata(Biodata bio);
void setProgressBar(int id, int value);
}
private Context context;
private Tag tag;
private UiCallback cb;
public NfcThread(Context context, Tag tag, UiCallback cb) {
this.context = context;
this.tag = tag;
this.cb = cb;
}
private IsoDep iso;
#Override
public void run() {
iso = IsoDep.get(tag);
if (iso == null) {
cb.showMessage(context.getString(R.string.non_iso));
return;
}
try {
iso.connect();
} catch (IOException e) {
cb.showMessage(context.getString(R.string.iso_connect_error));
Log.e(TAG, context.getString(R.string.iso_connect_error) + " : " + e.getMessage());
return;
}
try {
byte[] uid = iso.getTag().getId();
String ret = StringUtils.convertByteArrayToHexString(uid);
cb.showMessage("Card detected, UID : "+ret);
cb.setEditText(R.id.eMessage, "", 0);
} catch (Exception e) {
} finally {
try {
iso.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
private String send_apdu(String sapdu) throws IOException {
//Log.i(TAG, "SEND -> " + sapdu);
final byte [] apdu = StringUtils.convertHexStringToByteArray(StringUtils.removeSpaces(sapdu));
byte [] recv = iso.transceive(apdu);
String ret = StringUtils.convertByteArrayToHexString(recv);
Log.i(TAG_CL_OUT, ret);
return ret;
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.iwjo.nfcfieldstrength">
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.NFC" />
<uses-feature android:name="android.hardware.nfc" android:required="true" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<permission android:name="android.permission.REBOOT" />
<permission android:name="android.permission.MODIFY_PHONE_STATE" />
<permission android:name="android.permission.DEVICE_POWER" />
<uses-feature android:name="android.hardware.usb.host" />
<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:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Please give me advice..
I'm trying to get the user's locations in real time using service. The problem happens when I try to do this below Android 8.0 because of the foreground service, I looked for several ways to do this but I didn't find any that work below Android 8.0.
Code that i used:
MainActivity
public class MainActivity extends AppCompatActivity {
#BindView(R.id.btn_start_tracking)
Button btnStartTracking;
#BindView(R.id.btn_stop_tracking)
Button btnStopTracking;
#BindView(R.id.txt_status)
TextView txtStatus;
public BackgroundService gpsService;
public boolean mTracking = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
final Intent intent = new Intent(this.getApplication(), BackgroundService.class);
this.getApplication().startService(intent);
this.getApplication().startForegroundService(intent);
this.getApplication().bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
}
#OnClick(R.id.btn_start_tracking)
public void startLocationButtonClick() {
Dexter.withActivity(this)
.withPermission(Manifest.permission.ACCESS_FINE_LOCATION)
.withListener(new PermissionListener() {
#Override
public void onPermissionGranted(PermissionGrantedResponse response) {
gpsService.startTracking();
mTracking = true;
toggleButtons();
}
#Override
public void onPermissionDenied(PermissionDeniedResponse response) {
if (response.isPermanentlyDenied()) {
openSettings();
}
}
#Override
public void onPermissionRationaleShouldBeShown(PermissionRequest permission, PermissionToken token) {
token.continuePermissionRequest();
}
}).check();
}
#OnClick(R.id.btn_stop_tracking)
public void stopLocationButtonClick() {
mTracking = false;
gpsService.stopTracking();
toggleButtons();
}
private void toggleButtons() {
btnStartTracking.setEnabled(!mTracking);
btnStopTracking.setEnabled(mTracking);
txtStatus.setText( (mTracking) ? "TRACKING" : "GPS Ready" );
}
private void openSettings() {
Intent intent = new Intent();
intent.setAction( Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", BuildConfig.APPLICATION_ID, null);
intent.setData(uri);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
private ServiceConnection serviceConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
String name = className.getClassName();
if (name.endsWith("BackgroundService")) {
gpsService = ((BackgroundService.LocationServiceBinder) service).getService();
btnStartTracking.setEnabled(true);
txtStatus.setText("GPS Ready");
}
}
public void onServiceDisconnected(ComponentName className) {
if (className.getClassName().equals("BackgroundService")) {
gpsService = null;
}
}
};
}
Background service class
public class BackgroundService extends Service {
private final LocationServiceBinder binder = new LocationServiceBinder();
private final String TAG = "BackgroundService";
private LocationListener mLocationListener;
private LocationManager mLocationManager;
private NotificationManager notificationManager;
private final int LOCATION_INTERVAL = 500;
private final int LOCATION_DISTANCE = 10;
#Override
public IBinder onBind(Intent intent) {
return binder;
}
private class LocationListener implements android.location.LocationListener {
private Location lastLocation = null;
private final String TAG = "LocationListener";
private Location mLastLocation;
public LocationListener(String provider) {
mLastLocation = new Location(provider);
}
#Override
public void onLocationChanged(Location location) {
mLastLocation = location;
Log.i(TAG, "LocationChanged: "+location);
}
#Override
public void onProviderDisabled(String provider) {
Log.e(TAG, "onProviderDisabled: " + provider);
}
#Override
public void onProviderEnabled(String provider) {
Log.e(TAG, "onProviderEnabled: " + provider);
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
Log.e(TAG, "onStatusChanged: " + status);
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
return START_STICKY;
}
#Override
public void onCreate() {
Log.i(TAG, "onCreate");
startForeground(12345678, getNotification());
}
#Override
public void onDestroy() {
super.onDestroy();
if (mLocationManager != null) {
try {
mLocationManager.removeUpdates(mLocationListener);
} catch (Exception ex) {
Log.i(TAG, "fail to remove location listners, ignore", ex);
}
}
}
private void initializeLocationManager() {
if (mLocationManager == null) {
mLocationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
}
}
public void startTracking() {
initializeLocationManager();
mLocationListener = new LocationListener(LocationManager.GPS_PROVIDER);
try {
mLocationManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE, mLocationListener);
} catch (java.lang.SecurityException ex) {
// Log.i(TAG, "fail to request location update, ignore", ex);
} catch (IllegalArgumentException ex) {
// Log.d(TAG, "gps provider does not exist " + ex.getMessage());
}
}
public void stopTracking() {
this.onDestroy();
}
private Notification getNotification() {
NotificationChannel channel = new NotificationChannel("channel_01", "My Channel", NotificationManager.IMPORTANCE_DEFAULT);
NotificationManager notificationManager = getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);
Notification.Builder builder = new Notification.Builder(getApplicationContext(), "channel_01").setAutoCancel(true);
return builder.build();
}
public class LocationServiceBinder extends Binder {
public BackgroundService getService() {
return BackgroundService.this;
}
}
}
Manifest
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="ac.myapp">
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_GPS" />
<uses-permission android:name="android.permission.ACCESS_LOCATION" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<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=".maps"></activity>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:enabled="true"
android:name=".BootUpReceiver"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<service android:name=".BackgroundService"/>
</application>
</manifest>
I'm developing a sip client based on the SipDemo app. My app receives incoming calls successfully at first, but after some time my app cannot receive calls. BroadcastReceiver doesn't receive anything. What could cause this?
My manifest file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.kasenna.android.kasip">
<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.ACCESS_NETWORK_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" />
<application android:icon="#drawable/icon" android:label="KaSip">
<activity android:name=".MainActivity"
android:launchMode="singleTask"
android:taskAffinity="">
<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="Настройки"/>
<receiver android:name=".IncomingCallReceiver" android:label="Call Receiver"/>
<service android:name=".MainService" android:exported="false"/>
</application>
</manifest>
Main activity:
package com.kasenna.android.kasip;
public class MainActivity extends FragmentActivity implements
IncallFragmentClass.IncallButtonsEventListener,
IncallCallEndFragmentClass.IncallCallEndButtonsEventListener,
MakeCallFragmentClass.MakeCallButtonsEventListener,
DialpadFragmentClass.DialpadButtonsEventListener
{
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
setContentView(R.layout.main);
mswitch=(Switch)findViewById(R.id.regswitch);
mswitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener(){
public void onCheckedChanged(CompoundButton buttonView,boolean isChecked){
if(isChecked){
SharedPreferences prefs=PreferenceManager.getDefaultSharedPreferences(getBaseContext());
String username=prefs.getString("namePref","");
String password=prefs.getString("passPref","");
if(username.length()==0||password.length()==0){
showDialog(UPDATE_SETTINGS_DIALOG);
}else {
accRegistered = true;
//registrationWorker("start");
initializeLocalProfile();
}
}else{
SharedPreferences prefs=PreferenceManager.getDefaultSharedPreferences(getBaseContext());
String username=prefs.getString("namePref","");
String password=prefs.getString("passPref","");
if(username.length()==0||password.length()==0){
}else {
accRegistered = false;
//registrationWorker("stop");
closeLocalProfile();
}
}
}
});
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
AudioManager manager=(AudioManager)getApplicationContext().getSystemService(Context.AUDIO_SERVICE);
manager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
Uri notification=RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE);
ring = RingtoneManager.getRingtone(getApplicationContext(),notification);
getSupportFragmentManager().beginTransaction().add(R.id.fragment_container_dialpad, (new DialpadFragmentClass())).commit();
ImageButton delButton = (ImageButton) findViewById(R.id.buttonDel);
delButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
TextView labelView=(TextView)findViewById(R.id.sipLabelDialpad);
String currentString = labelView.getText().toString();
String needText = currentString.equals("") ? "" : currentString.substring(0,currentString.length()-1);
updateStatus(needText,true);
if((!currentString.equals(""))&(needText.equals(""))){
getSupportFragmentManager().beginTransaction().remove(mMakeCallClass).commit();
}
}
});
initializeManager();
}
public void initializeManager(){
IntentFilter filter = new IntentFilter();
filter.addAction("android.KaSip.INCOMING_CALL");
callReceiver = new IncomingCallReceiver();
this.registerReceiver(callReceiver,filter);
if(manager == null){
manager = SipManager.newInstance(this);
Log.v("KaSip_logs","manager created: "+manager.toString());
}
}
public void initializeLocalProfile(){
if(manager == null){
return;
}
if(me != null){
closeLocalProfile();
}
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
String username = prefs.getString("namePref","");
String password = prefs.getString("passPref","");
try{
SipProfile.Builder builder = new SipProfile.Builder(username,"cgp.cittel.ru");
builder.setPassword(password);
ConnectivityManager connManager=(ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo mWifi=connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
if(mWifi.isConnected()){
builder.setProtocol("TCP");
}else{
builder.setProtocol("UDP");
}
builder.setSendKeepAlive(true);
builder.setAutoRegistration(true);
me=builder.build();
updateStatus("регистрация...");
Intent mServiceIntent = new Intent(this,MainService.class);
String dataUrl = me.getUriString();
mServiceIntent.setData(Uri.parse(dataUrl));
startService(mServiceIntent);
Intent i = new Intent();
i.setAction("android.KaSip.INCOMING_CALL");
PendingIntent pi = PendingIntent.getBroadcast(this,0,i,Intent.FILL_IN_DATA);
Log.v("KaSip_logs","SipProfile="+me.getUriString());
manager.open(me,pi,null);
Log.v("KaSip_logs","after manager open");
SipRegistrationListener mListener = new SipRegistrationListener(){
public void onRegistering(String localProfileUri){
}
public void onRegistrationDone(String localProfileUri,long expiryTime){
updateStatus("зарегистрирован");
}
public void onRegistrationFailed(String localProfileUri,int errorCode,String errorMessage){
Log.v("KaSip_logs","SipRegistrationListener error="+errorMessage);
}
};
manager.setRegistrationListener(me.getUriString(),mListener);
manager.register(me,60,mListener);
Log.v("KaSip_logs","manager register");
}catch(ParseException pe){
pe.printStackTrace();
}catch(SipException se){
Log.v("KaSip_logs","SipException="+se.getMessage());
}
}
public void closeLocalProfile(){
if(manager==null){
return;
}
try{
if(me!=null){
manager.close(me.getUriString());
}
}catch(Exception ee){
ee.printStackTrace();
}
updateStatus("не зарегистрирован");
}
public void updatePreferences(){
Intent settingsActivity=new Intent(getBaseContext(),
SipSettings.class);
startActivity(settingsActivity);
}
public void onReceiveCallBroadcast(Intent intent){
SipAudioCall.Listener listener=new SipAudioCall.Listener(){
#Override
public void onRinging(SipAudioCall call,SipProfile caller){
super.onRinging(call,caller);
remoteCall=call;
Log.v("KaSip_logs","onReceiveCallBroadcast, onRinging, caller="+caller.getUriString());
}
#Override
public void onCallEnded(SipAudioCall call){
super.onCallEnded(call);
callTimer("stop");
updateStatus("", true);
if(ring.isPlaying()){
ring.stop();
}
if (loadedActionFragment.equals("incall")) {
getSupportFragmentManager().beginTransaction().remove(mIncallFragmentClass).commit();
loadedActionFragment = "";
}else if (loadedActionFragment.equals("incallcallstart")){
getSupportFragmentManager().beginTransaction().remove(mIncallCallEndFragmentClass).commit();
loadedActionFragment = "";
}
}
#Override
public void onCallEstablished(SipAudioCall call){
super.onCallEstablished(call);
callTimer("start");
createUI("incallcallstart");
}
#Override
public void onError(SipAudioCall call, int errorCode, String errorMessage){
super.onError(call,errorCode,errorMessage);
callTimer("stop");
updateStatus("",true);
if (loadedActionFragment.equals("incall")) {
getSupportFragmentManager().beginTransaction().remove(mIncallFragmentClass).commit();
loadedActionFragment = "";
}else if (loadedActionFragment.equals("incallcallstart")){
getSupportFragmentManager().beginTransaction().remove(mIncallCallEndFragmentClass).commit();
loadedActionFragment = "";
}
}
};
try{
incomingCall=manager.takeAudioCall(intent,listener);
}catch(SipException se){
Log.v("KaSip_logs","onReceiveCallBroadcast error="+se.getMessage());
if(incomingCall!=null){
incomingCall.close();
}
if(remoteCall!=null){
remoteCall.close();
}
}
Window window=this.getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
ring.play();
updateStatus(incomingCall);
}
#Override
public void OnClick_buttonStart() {
updateStatus("",true);
if (ring.isPlaying()) {
ring.stop();
}
try {
if (remoteCall != null) {
remoteCall.answerCall(30);
}
incomingCall.answerCall(30);
incomingCall.startAudio();
if (incomingCall.isMuted()) {
incomingCall.toggleMute();
}
} catch (SipException se) {
Log.v("KaSip_logs", "onReceiveCallBroadcast error=" + se.getMessage());
if (incomingCall != null) {
incomingCall.close();
}
if (remoteCall != null) {
remoteCall.close();
}
}
}
#Override
public void OnClick_buttonStop() {
if (ring.isPlaying()) {
ring.stop();
}
try {
if (remoteCall != null) {
remoteCall.endCall();
}
if (incomingCall != null) {
incomingCall.endCall();
incomingCall.close();
}
if (remoteCall != null) {
remoteCall.close();
}
} catch (SipException se) {
Log.v("KaSip_logs", "onReceiveCallBroadcast error=" + se.getMessage());
}
callTimer("stop");
synchronized (this) {
try {
this.wait(1000);
} catch (InterruptedException ie) {
ie.printStackTrace();
}
}
updateStatus("", true);
getSupportFragmentManager().beginTransaction().remove(mIncallFragmentClass).commit();
loadedActionFragment = "";
}
#Override
public void OnClick_buttonCallEnd() {
try {
if (remoteCall != null) {
remoteCall.endCall();
}
if (incomingCall != null) {
incomingCall.endCall();
incomingCall.close();
}
if (outgoingCall != null) {
outgoingCall.endCall();
outgoingCall.close();
}
if (remoteCall != null) {
remoteCall.close();
}
} catch (SipException se) {
Log.v("KaSip_logs", "onReceiveCallBroadcast error=" + se.getMessage());
}
callTimer("stop");
generateRingback("stop");
updateStatus("", true);
getSupportFragmentManager().beginTransaction().remove(mIncallCallEndFragmentClass).commit();
loadedActionFragment = "";
}
#Override
public void OnClick_buttonMakeCall(){
if (accRegistered) {
createUI("incallcallstart");
TextView labelView = (TextView) findViewById(R.id.sipLabelDialpad);
sipAddress = labelView.getText().toString();
try {
SipAudioCall.Listener listener = new SipAudioCall.Listener() {
#Override
public void onCallEstablished(SipAudioCall call) {
super.onCallEstablished(call);
generateRingback("stop");
call.startAudio();
callTimer("start");
updateStatus("", true);
}
#Override
public void onCallEnded(SipAudioCall call) {
super.onCallEnded(call);
callTimer("stop");
generateRingback("stop");
updateStatus("", true);
getSupportFragmentManager().beginTransaction().remove(mIncallCallEndFragmentClass).commit();
loadedActionFragment = "";
}
#Override
public void onCallBusy(SipAudioCall call) {
super.onCallBusy(call);
generateRingback("stop");
updateStatus("номер занят", true);
generateBusy("start");
getSupportFragmentManager().beginTransaction().remove(mIncallCallEndFragmentClass).commit();
loadedActionFragment = "";
}
#Override
public void onRingingBack(SipAudioCall call) {
super.onRingingBack(call);
updateStatus("ждём ответа", true);
generateRingback("start");
}
#Override
public void onError(SipAudioCall call, int errorCode, String errorMessage) {
super.onError(call, errorCode, errorMessage);
callTimer("stop");
generateRingback("stop");
updateStatus("", true);
getSupportFragmentManager().beginTransaction().remove(mIncallCallEndFragmentClass).commit();
loadedActionFragment = "";
}
};
outgoingCall = manager.makeAudioCall(me.getUriString(), sipAddress + "#cgp.cittel.ru", listener, 30);
} catch (Exception e) {
e.printStackTrace();
if (me != null) {
try {
manager.close(me.getUriString());
} catch (Exception ee) {
ee.printStackTrace();
}
}
if (outgoingCall != null) {
outgoingCall.close();
}
}
}else{
Toast.makeText(this,"Сначала зарегистрируйтесь",Toast.LENGTH_LONG).show();
}
}
#Override
public void OnClick_buttonDialPad(final String button_description){
this.runOnUiThread(new Runnable(){
public void run(){
TextView labelView=(TextView)findViewById(R.id.sipLabelDialpad);
if ((loadedActionFragment.equals(""))&&(labelView.getText().toString().equals(""))){
mMakeCallClass = new MakeCallFragmentClass();
getSupportFragmentManager().beginTransaction().add(R.id.fragment_container_call_buttons, mMakeCallClass).commit();
}
updateStatus(labelView.getText()+button_description,true);
}
});
try {
if (incomingCall != null) {
if (button_description.equals("0")) {
incomingCall.sendDtmf(0);
} else if (button_description.equals("1")) {
incomingCall.sendDtmf(1);
} else if (button_description.equals("2")) {
incomingCall.sendDtmf(2);
} else if (button_description.equals("3")) {
incomingCall.sendDtmf(3);
} else if (button_description.equals("4")) {
incomingCall.sendDtmf(4);
} else if (button_description.equals("5")) {
incomingCall.sendDtmf(5);
} else if (button_description.equals("6")) {
incomingCall.sendDtmf(6);
} else if (button_description.equals("7")) {
incomingCall.sendDtmf(7);
} else if (button_description.equals("8")) {
incomingCall.sendDtmf(8);
} else if (button_description.equals("9")) {
incomingCall.sendDtmf(9);
} else if (button_description.equals("*")) {
incomingCall.sendDtmf(10);
} else if (button_description.equals("#")) {
incomingCall.sendDtmf(11);
} else if (button_description.equals("A")) {
incomingCall.sendDtmf(12);
} else if (button_description.equals("B")) {
incomingCall.sendDtmf(13);
} else if (button_description.equals("C")) {
incomingCall.sendDtmf(14);
} else if (button_description.equals("D")) {
incomingCall.sendDtmf(15);
}
}
if (outgoingCall != null) {
if (button_description.equals("0")) {
outgoingCall.sendDtmf(0);
} else if (button_description.equals("1")) {
outgoingCall.sendDtmf(1);
} else if (button_description.equals("2")) {
outgoingCall.sendDtmf(2);
} else if (button_description.equals("3")) {
outgoingCall.sendDtmf(3);
} else if (button_description.equals("4")) {
outgoingCall.sendDtmf(4);
} else if (button_description.equals("5")) {
outgoingCall.sendDtmf(5);
} else if (button_description.equals("6")) {
outgoingCall.sendDtmf(6);
} else if (button_description.equals("7")) {
outgoingCall.sendDtmf(7);
} else if (button_description.equals("8")) {
outgoingCall.sendDtmf(8);
} else if (button_description.equals("9")) {
outgoingCall.sendDtmf(9);
} else if (button_description.equals("*")) {
outgoingCall.sendDtmf(10);
} else if (button_description.equals("#")) {
outgoingCall.sendDtmf(11);
} else if (button_description.equals("A")) {
outgoingCall.sendDtmf(12);
} else if (button_description.equals("B")) {
outgoingCall.sendDtmf(13);
} else if (button_description.equals("C")) {
outgoingCall.sendDtmf(14);
} else if (button_description.equals("D")) {
outgoingCall.sendDtmf(15);
}
}
}catch (Exception e){
e.printStackTrace();
}
}
private class generateRingbackTask extends AsyncTask<Void, Void, Void> {
Context mContext;
public generateRingbackTask(Context context) {
super();
mContext = context;
}
#Override
protected Void doInBackground(Void... voids) {
int counter = 0;
ToneGenerator mRingback = new ToneGenerator(0,ToneGenerator.MAX_VOLUME);
synchronized (this) {
while (!this.isCancelled()) {
mRingback.startTone(ToneGenerator.TONE_SUP_DIAL,1000);
try {
this.wait(1000);
} catch (InterruptedException ie) {
ie.printStackTrace();
}
mRingback.stopTone();
try {
this.wait(1500);
} catch (InterruptedException ie) {
ie.printStackTrace();
}
counter = counter + 2;
}
}
return null;
}
}
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
public void generateRingback(String action){
if(action.equals("start")){
synchronized(this){
mringbackTask = new generateRingbackTask(this);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
mringbackTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
else {
mringbackTask.execute();
}
}
}else{
if (mringbackTask !=null){
mringbackTask.cancel(true);
}
}
}
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
public void generateBusy(String action){
if(action.equals("start")){
synchronized(this){
mbusyTask = new generateBusyTask(this);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
mbusyTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
else {
mbusyTask.execute();
}
}
}else{
if (mbusyTask !=null){
mbusyTask.cancel(true);
}
}
}
private class generateBusyTask extends AsyncTask<Void, Void, Void> {
Context mContext;
public generateBusyTask(Context context) {
super();
mContext = context;
}
#Override
protected void onPostExecute(Void voids) {
updateStatus("", true);
}
#Override
protected Void doInBackground(Void... voids) {
int counter;
ToneGenerator mBusy = new ToneGenerator(0,ToneGenerator.MAX_VOLUME);
synchronized (this) {
for(counter=0;counter<5;counter++){
mBusy.startTone(ToneGenerator.TONE_SUP_DIAL,300);
try {
this.wait(300);
} catch (InterruptedException ie) {
ie.printStackTrace();
}
mBusy.stopTone();
try {
this.wait(100);
} catch (InterruptedException ie) {
ie.printStackTrace();
}
}
}
return null;
}
}
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
public void registrationWorker(String action){
if(action.equals("start")){
synchronized(this){
mregistrationTask = new registrationWorkerTask(this);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
mregistrationTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
else {
mregistrationTask.execute();
}
}
}else{
if (mregistrationTask !=null){
mregistrationTask.cancel(true);
}
}
}
private class registrationWorkerTask extends AsyncTask<Void, Void, Void> {
Context mContext;
public registrationWorkerTask(Context context) {
super();
mContext = context;
}
#Override
protected void onPreExecute(){
if ((callReceiver == null)&&(manager == null)){
initializeManager();
}
}
#Override
protected void onProgressUpdate(Void... voids){
initializeLocalProfile();
}
#Override
protected Void doInBackground(Void... voids) {
synchronized (this) {
while (!this.isCancelled()) {
publishProgress(null);
try {
this.wait(58000);
} catch (InterruptedException ie) {
ie.printStackTrace();
}
}
}
Log.v("KaSip_logs", "registrationWorkerTask stopped");
return null;
}
}
}
and IncomingCallRecever.java:
package com.kasenna.android.kasip;
public class IncomingCallReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent i = new Intent(context,
MainActivity.class);
context.startActivity(i);
MainActivity mainActivity = (MainActivity) context;
mainActivity.createUI("incall");
mainActivity.onReceiveCallBroadcast(intent);
}
}
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/
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" />