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" />
Related
I am developing an Android application, where I have asked to implement the call record ,I have gone through SO and found One Solution which is working fine when my app is opened. If I close my app or clear it from recent apps, Call record is not working. Tried searching in the Google and SO but no luck. I am posting my code here, Can some one help me in getting the solution.
CallreCorder Service class:
public class TService extends Service {
MediaRecorder recorder;
File audiofile;
String name, phonenumber;
String audio_format;
public String Audio_Type;
int audioSource;
Context context;
private Handler handler;
Timer timer;
Boolean offHook = false, ringing = false;
Toast toast;
Boolean isOffHook = false;
private boolean recordstarted = false;
private static final String ACTION_IN = "android.intent.action.PHONE_STATE";
private static final String ACTION_OUT = "android.intent.action.NEW_OUTGOING_CALL";
private CallBr br_call;
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onDestroy() {
Log.d("service", "destroy");
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// final String terminate =(String)
// intent.getExtras().get("terminate");//
// intent.getStringExtra("terminate");
// Log.d("TAG", "service started");
//
// TelephonyManager telephony = (TelephonyManager)
// getSystemService(Context.TELEPHONY_SERVICE); // TelephonyManager
// // object
// CustomPhoneStateListener customPhoneListener = new
// CustomPhoneStateListener();
// telephony.listen(customPhoneListener,
// PhoneStateListener.LISTEN_CALL_STATE);
// context = getApplicationContext();
final IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_OUT);
filter.addAction(ACTION_IN);
this.br_call = new CallBr();
this.registerReceiver(this.br_call, filter);
// if(terminate != null) {
// stopSelf();
// }
return START_NOT_STICKY;
}
public class CallBr extends BroadcastReceiver {
Bundle bundle;
String state;
String inCall, outCall;
public boolean wasRinging = false;
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(ACTION_IN)) {
if ((bundle = intent.getExtras()) != null) {
state = bundle.getString(TelephonyManager.EXTRA_STATE);
if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
inCall = bundle.getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
wasRinging = true;
Toast.makeText(context, "IN : " + inCall, Toast.LENGTH_LONG).show();
} else if (state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) {
if (wasRinging == true) {
Toast.makeText(context, "ANSWERED", Toast.LENGTH_LONG).show();
String out = new SimpleDateFormat("dd-MM-yyyy hh-mm-ss").format(new Date());
File sampleDir = new File(Environment.getExternalStorageDirectory(), "/TestRecordingDasa");
if (!sampleDir.exists()) {
sampleDir.mkdirs();
}
Log.d("TService", "onReceive: "+sampleDir);
String file_name = "Outgoing";
try {
audiofile = File.createTempFile(file_name, ".wav", sampleDir);
} catch (IOException e) {
e.printStackTrace();
}
String path = Environment.getExternalStorageDirectory().getAbsolutePath();
recorder = new MediaRecorder();
// recorder.setAudioSource(MediaRecorder.AudioSource.VOICE_CALL);
// recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
recorder.setOutputFile(audiofile.getAbsolutePath());
try {
recorder.prepare();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
recorder.start();
recordstarted = true;
}
} else if (state.equals(TelephonyManager.EXTRA_STATE_IDLE)) {
wasRinging = false;
Toast.makeText(context, "REJECT || DISCO", Toast.LENGTH_LONG).show();
if (recordstarted) {
recorder.stop();
recordstarted = false;
}
}
}
} else if (intent.getAction().equals(ACTION_OUT)) {
if ((bundle = intent.getExtras()) != null) {
outCall = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
Toast.makeText(context, "OUT : " + outCall, Toast.LENGTH_LONG).show();
File sampleDir = new File(Environment.getExternalStorageDirectory(), "/TestRecordingDasa");
if (!sampleDir.exists()) {
sampleDir.mkdirs();
}
Log.d("TService", "onReceive: "+sampleDir);
String file_name = "Record";
try {
audiofile = File.createTempFile(file_name, ".wav", sampleDir);
} catch (IOException e) {
e.printStackTrace();
}
String path = Environment.getExternalStorageDirectory().getAbsolutePath();
recorder = new MediaRecorder();
// recorder.setAudioSource(MediaRecorder.AudioSource.VOICE_CALL);
// recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
recorder.setOutputFile(audiofile.getAbsolutePath());
try {
recorder.prepare();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
recorder.start();
recordstarted = true;
}
}
LocalBroadcastManager.getInstance(context).sendBroadcast(new Intent("callRecord"));
}
}
}
Receiver class:
public class DeviceAdminDemo extends DeviceAdminReceiver {
#Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
}
public void onEnabled(Context context, Intent intent) {
};
public void onDisabled(Context context, Intent intent) {
};
}
MainActivity Class
public class MainActivity extends Activity {
private static final int REQUEST_CODE = 0;
private DevicePolicyManager mDPM;
private ComponentName mAdminName;
private static final int PERMISSION_REQUEST_CODE= 123;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (checkPermission()){
Toast.makeText(this, "Permission granted", Toast.LENGTH_SHORT).show();
}else{
requestPermission();
}
try {
// Initiate DevicePolicyManager.
mDPM = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
mAdminName = new ComponentName(this, DeviceAdminDemo.class);
if (!mDPM.isAdminActive(mAdminName)) {
Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, mAdminName);
intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, "Click on Activate button to secure your application.");
startActivityForResult(intent, REQUEST_CODE);
} else {
// mDPM.lockNow();
// Intent intent = new Intent(MainActivity.this,
// TrackDeviceService.class);
// startService(intent);
}
} catch (Exception e) {
e.printStackTrace();
}
LocalBroadcastManager.getInstance(MainActivity.this).registerReceiver(receiver, new IntentFilter("callRecord"));
Intent intent = new Intent(MainActivity.this, TService.class);
startService(intent);
}
private BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equalsIgnoreCase("callRecord")) {
Toast.makeText(MainActivity.this, "Call record", Toast.LENGTH_SHORT).show();
}
}
};
private boolean checkPermission(){
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED){
return true;
}else{
return false;
}
}
private void requestPermission(){
if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,Manifest.permission.ACCESS_FINE_LOCATION)
|| ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,Manifest.permission.ACCESS_COARSE_LOCATION)
|| ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,Manifest.permission.CALL_PHONE)
|| ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,Manifest.permission.SEND_SMS)
|| ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,Manifest.permission.READ_CONTACTS)
|| ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE)
|| ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
|| ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.READ_PHONE_STATE)
|| ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.PROCESS_OUTGOING_CALLS)
|| ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.RECORD_AUDIO)
|| ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.CAPTURE_AUDIO_OUTPUT)){
Toast.makeText(MainActivity.this,"Allow Us pemissions. Please allow in App Settings for additional functionality.",Toast.LENGTH_LONG).show();
} else {
ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.CALL_PHONE, Manifest.permission.SEND_SMS, Manifest.permission.READ_CONTACTS,
Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_PHONE_STATE,
Manifest.permission.PROCESS_OUTGOING_CALLS, Manifest.permission.RECORD_AUDIO, Manifest.permission.CAPTURE_AUDIO_OUTPUT}, PERMISSION_REQUEST_CODE);
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case PERMISSION_REQUEST_CODE:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "Permission Granted, ", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "Permission not Granted", Toast.LENGTH_SHORT).show();
}
break;
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (REQUEST_CODE == requestCode) {
Intent intent = new Intent(MainActivity.this, TService.class);
startService(intent);
}
}
#Override
public void onResume() {
LocalBroadcastManager.getInstance(this).registerReceiver(receiver, new IntentFilter("callRecord"));
super.onResume();
}
#Override
public void onPause() {
super.onPause();
LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver);
}
}
Manifest file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.practice.callrecorder">
<uses-permission android:name="android.permission.CAPTURE_AUDIO_OUTPUT"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.STORAGE" />
<uses-permission android:name="android.permission.CALL_PHONE"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.SEND_SMS"/>
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<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">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver
android:name=".DeviceAdminDemo"
android:description="#string/app_name"
android:label="#string/app_name"
android:permission="android.permission.BIND_DEVICE_ADMIN">
<meta-data
android:name="android.app.device_admin"
android:resource="#xml/my_admin" />
<intent-filter>
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
<action android:name="android.app.action.DEVICE_ADMIN_DISABLED" />
<action android:name="android.app.action.DEVICE_ADMIN_DISABLE_REQUESTED" />
</intent-filter>
</receiver>
<service
android:name=".TService"
android:enabled="true"
android:exported="true">
</service>
</application>
my_admin.xml
<device-admin xmlns:android="http://schemas.android.com/apk/res/android" >
<uses-policies>
<force-lock />
</uses-policies>
any help would be grateful!!!
Thanks in advance!!
use START_STICKY as return param of onStartCommand() so when you kill you app it will restart the service
for reference you can check android developer guide
https://developer.android.com/reference/android/app/Service.html
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>
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 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/
In my application i want to send push notifications using third party push woosh.I am using jar file.when i run application it is showing status of register and register id but if i push messages they are not displayed in phone.
public class MainActivity extends FragmentActivity implements SendTagsCallBack
{
private static final String SEND_TAGS_STATUS_FRAGMENT_TAG ="send_tags_status_fragment_tag";
private static final String APP_ID = "554B5-9B410";
private static final String SENDER_ID = "944240090087";
private TextView mTagsStatus;
private EditText mIntTags;
private EditText mStringTags;
private Button mSubmitTagsButton;
private TextView mGeneralStatus;
/**
* Called when the activity is first created.
*/
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//NetworkUtils.useSSL = true;
PushManager pushManager = new PushManager(this, APP_ID, SENDER_ID);
pushManager.onStartup(this);
mGeneralStatus = (TextView) findViewById(R.id.general_status);
mTagsStatus = (TextView) findViewById(R.id.status);
mIntTags = (EditText) findViewById(R.id.tag_int);
mStringTags = (EditText) findViewById(R.id.tag_string);
checkMessage(getIntent());
mSubmitTagsButton = (Button) findViewById(R.id.submit_tags);
mSubmitTagsButton.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
checkAndSendTagsIfWeCan();
}
});
SendTagsFragment sendTagsFragment = getSendTagsFragment();
mTagsStatus.setText(sendTagsFragment.getSendTagsStatus());
mSubmitTagsButton.setEnabled(sendTagsFragment.canSendTags());
}
/**
* Called when the activity receives a new intent.
*/
public void onNewIntent(Intent intent)
{
super.onNewIntent(intent);
checkMessage(intent);
}
#Override
public void onStatusChange(int sendTagsStatus)
{
mTagsStatus.setText(sendTagsStatus);
}
#Override
public void onTaskEnds()
{
mSubmitTagsButton.setEnabled(true);
}
#Override
public void onTaskStarts()
{
mSubmitTagsButton.setEnabled(false);
}
private void checkAndSendTagsIfWeCan()
{
SendTagsFragment sendTagsFragment = getSendTagsFragment();
if (sendTagsFragment.canSendTags())
{
sendTagsFragment
.submitTags(this, mIntTags.getText().toString().trim(), mStringTags.getText().toString().trim());
}
}
/**
* Will check PushWoosh extras in this intent, and fire actual method
*
* #param intent activity intent
*/
private void checkMessage(Intent intent)
{
if (null != intent)
{
if (intent.hasExtra(PushManager.PUSH_RECEIVE_EVENT))
{
doOnMessageReceive(intent.getExtras().getString(PushManager.PUSH_RECEIVE_EVENT));
}
else if (intent.hasExtra(PushManager.REGISTER_EVENT))
{
doOnRegistered(intent.getExtras().getString(PushManager.REGISTER_EVENT));
}
else if (intent.hasExtra(PushManager.UNREGISTER_EVENT))
{
doOnUnregisteredError(intent.getExtras().getString(PushManager.UNREGISTER_EVENT));
}
else if (intent.hasExtra(PushManager.REGISTER_ERROR_EVENT))
{
doOnRegisteredError(intent.getExtras().getString(PushManager.REGISTER_ERROR_EVENT));
}
else if (intent.hasExtra(PushManager.UNREGISTER_ERROR_EVENT))
{
doOnUnregistered(intent.getExtras().getString(PushManager.UNREGISTER_ERROR_EVENT));
}
resetIntentValues();
}
}
public void doOnRegistered(String registrationId)
{
mGeneralStatus.setText(getString(R.string.registered, registrationId));
}
public void doOnRegisteredError(String errorId)
{
mGeneralStatus.setText(getString(R.string.registered_error, errorId));
}
public void doOnUnregistered(String registrationId)
{
mGeneralStatus.setText(getString(R.string.unregistered, registrationId));
}
public void doOnUnregisteredError(String errorId)
{
mGeneralStatus.setText(getString(R.string.unregistered_error, errorId));
}
public void doOnMessageReceive(String message)
{
mGeneralStatus.setText(getString(R.string.on_message, message));
}
/**
* Will check main Activity intent and if it contains any PushWoosh data, will clear it
*/
private void resetIntentValues()
{
Intent mainAppIntent = getIntent();
if (mainAppIntent.hasExtra(PushManager.PUSH_RECEIVE_EVENT))
{
mainAppIntent.putExtra(PushManager.PUSH_RECEIVE_EVENT, (String) null);
}
else if (mainAppIntent.hasExtra(PushManager.REGISTER_EVENT))
{
mainAppIntent.putExtra(PushManager.REGISTER_EVENT, (String) null);
}
else if (mainAppIntent.hasExtra(PushManager.UNREGISTER_EVENT))
{
mainAppIntent.putExtra(PushManager.UNREGISTER_EVENT, (String) null);
}
else if (mainAppIntent.hasExtra(PushManager.REGISTER_ERROR_EVENT))
{
mainAppIntent.putExtra(PushManager.REGISTER_ERROR_EVENT, (String) null);
}
else if (mainAppIntent.hasExtra(PushManager.UNREGISTER_ERROR_EVENT))
{
mainAppIntent.putExtra(PushManager.UNREGISTER_ERROR_EVENT, (String) null);
}
setIntent(mainAppIntent);
}
private SendTagsFragment getSendTagsFragment()
{
FragmentManager fragmentManager = getSupportFragmentManager();
SendTagsFragment sendTagsFragment =
(SendTagsFragment) fragmentManager.findFragmentByTag(SEND_TAGS_STATUS_FRAGMENT_TAG);
if (null == sendTagsFragment)
{
sendTagsFragment = new SendTagsFragment();
sendTagsFragment.setRetainInstance(true);
fragmentManager.beginTransaction().add(sendTagsFragment, SEND_TAGS_STATUS_FRAGMENT_TAG).commit();
fragmentManager.executePendingTransactions();
}
return sendTagsFragment;
}
#Override
protected void onDestroy()
{
super.onDestroy();
mIntTags = null;
mStringTags = null;
mTagsStatus = null;
mSubmitTagsButton = null;
}
}
/*SendTagsFragment*/
public class SendTagsFragment extends Fragment implements SendPushTagsCallBack
{
private final Object mSyncObject = new Object();
private int mSendTagsStatus = R.string.status_ready;
private AsyncTask<Void, Void, Void> mTask;
public SendTagsFragment()
{
}
public boolean canSendTags()
{
synchronized (mSyncObject)
{
return mTask == null;
}
}
public void submitTags(final Context context, String tagInt, String tagString)
{
synchronized (mSyncObject)
{
if (!canSendTags())
{
return;
}
if (!goodAllInputData(tagInt, tagString))
{
return;
}
mSendTagsStatus = R.string.status_started;
transfareTaskStartsToActivity();
final Map<String, Object> tags = generateTags(tagInt, tagString);
mTask = new AsyncTask<Void, Void, Void>()
{
#Override
protected Void doInBackground(Void... params)
{
PushManager.sendTags(context, tags, SendTagsFragment.this);
return null;
}
};
mTask.execute((Void) null);
}
}
public int getSendTagsStatus()
{
synchronized (mSyncObject)
{
return mSendTagsStatus;
}
}
#Override
public void taskStarted()
{
synchronized (mSyncObject)
{
mSendTagsStatus = R.string.status_started;
transfareStatusToActivity();
}
}
#Override
public void onSentTagsSuccess(Map<String, String> stringStringMap)
{
synchronized (mSyncObject)
{
mSendTagsStatus = R.string.status_success;
mTask = null;
transfareStatusToActivity();
transfareTaskEndsToActivity();
}
}
#Override
public void onSentTagsError(PushWooshException e)
{
synchronized (mSyncObject)
{
mSendTagsStatus = R.string.status_error;
if (null != e)
{
e.printStackTrace();
}
mTask = null;
transfareStatusToActivity();
transfareTaskEndsToActivity();
}
}
private boolean goodAllInputData(String tagInt, String tagString)
{
if (tagInt.length() == 0 && tagString.length() == 0)
{
mSendTagsStatus = R.string.status_init_error;
transfareStatusToActivity();
transfareTaskEndsToActivity();
return false;
}
if (tagInt.length() != 0)
{
try
{
Integer.parseInt(tagInt);
}
catch (Exception e)
{
mSendTagsStatus = R.string.status_int_parse_error;
transfareStatusToActivity();
transfareTaskEndsToActivity();
return false;
}
}
return true;
}
private void transfareTaskStartsToActivity()
{
SendTagsCallBack sendTagsCallBack = (SendTagsCallBack) getActivity();
if (null != sendTagsCallBack)
{
sendTagsCallBack.onTaskStarts();
}
}
private void transfareTaskEndsToActivity()
{
SendTagsCallBack sendTagsCallBack = (SendTagsCallBack) getActivity();
if (null != sendTagsCallBack)
{
sendTagsCallBack.onTaskEnds();
}
}
private void transfareStatusToActivity()
{
SendTagsCallBack sendTagsCallBack = (SendTagsCallBack) getActivity();
if (null != sendTagsCallBack)
{
sendTagsCallBack.onStatusChange(mSendTagsStatus);
}
}
private Map<String, Object> generateTags(String tagInt, String tagString)
{
Map<String, Object> tags = new HashMap<String, Object>();
if (tagInt.length() != 0)
{
tags.put("FavNumber", Integer.parseInt(tagInt));
}
if (tagString.length() != 0)
{
tags.put("Alias", tagString);
}
return tags;
}
}
I gave these permissions in Manifest file
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<!--library-->
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<!-- GCM connects to Google Services. -->
<uses-permission android:name="android.permission.INTERNET"/>
<!-- GCM requires a Google account. -->
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
<!-- Keeps the processor from sleeping when a message is received. -->
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<!--
Creates a custom permission so only this app can receive its messages.
NOTE: the permission *must* be called PACKAGE.permission.C2D_MESSAGE,
where PACKAGE is the application's package name.
-->
<permission
android:name="com.pushwoosh.test.tags.sample.app.permission.C2D_MESSAGE"
android:protectionLevel="signature"/>
<uses-permission
android:name="com.pushwoosh.test.tags.sample.app.permission.C2D_MESSAGE"/>
<!-- This app has permission to register and receive data message. -->
<uses-permission
android:name="com.google.android.c2dm.permission.RECEIVE"/>
<intent-filter>
<action android:name="com.pushwoosh.test.tags.sample.app.MESSAGE"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
<activity android:name="com.arellomobile.android.push.PushWebview"/>
<activity android:name="com.arellomobile.android.push.MessageActivity"/>
<activity android:name="com.arellomobile.android.push.PushHandlerActivity"/>
<!--
BroadcastReceiver that will receive intents from GCM
services and handle them to the custom IntentService.
The com.google.android.c2dm.permission.SEND permission is necessary
so only GCM services can send data messages for the app.
-->
<receiver
android:name="com.google.android.gcm.GCMBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND"
>
<intent-filter>
<!-- Receives the actual messages. -->
<action android:name="com.google.android.c2dm.intent.RECEIVE"/>
<!-- Receives the registration id. -->
<action android:name="com.google.android.c2dm.intent.REGISTRATION"/>
<category android:name="com.pushwoosh.test.tags.sample.app"/>
</intent-filter>
</receiver>
<!--
Application-specific subclass of PushGCMIntentService that will
handle received messages.
-->
<service android:name="com.arellomobile.android.push.PushGCMIntentService"/>
<!--
Service for sending location updates
-->
<service android:name="com.arellomobile.android.push.GeoLocationService"/>
In 1]Sender_Id put your "GCM App ID" and in 2]In APP ID put your "PushWoosh APP KEY" correctly
then go to PushWoosh website after logging in, go to Application part then Woosh your message.