I am using SMS Retriever API to get OTP but the problem I am facing is that it is not receiving SMS every time. Sometime SMS content is retrieved and some time nothing happens.
I have used the Toast (Broadcaster started) to show if it is started every time but Toast is also not displayed every time. I am unable to diagnose the problem.
Broadcast Receiver code:
public class OTPBroadcastReceiver extends BroadcastReceiver {
private String otp;
private static OTPSMSReceiveListner otpsmsReceiveListner = null;
private final Pattern p = Pattern.compile("(|^)\\d{4}");
public static void injectListner(OTPSMSReceiveListner listner){
otpsmsReceiveListner = listner;
}
#Override
public void onReceive(Context context, Intent intent) {
try {
Toast.makeText(context,"Broadcaster started",Toast.LENGTH_LONG).show();
if (SmsRetriever.SMS_RETRIEVED_ACTION.equals(intent.getAction())) {
Bundle extras = intent.getExtras();
Status status = (Status) extras.get(SmsRetriever.EXTRA_STATUS);
switch (status.getStatusCode()) {
case CommonStatusCodes.SUCCESS:
//Toast.makeText(context,"success",Toast.LENGTH_LONG).show();
// Get SMS message contents
String message = (String) extras.get(SmsRetriever.EXTRA_SMS_MESSAGE);
if (message != null) {
Matcher m = p.matcher(message);
if (m.find()) {
otp = m.group(0);
}
String token;
try {
token = CommonMethods.getSecurePref("OTP", context);
} catch (Exception ex) {
token = null;
}
if (token == null) {
//Pass on the text to our listener.
otpsmsReceiveListner.onOTPReceived(otp);
}
}
break;
case CommonStatusCodes.TIMEOUT:
Log.d("onReceive", "timed out (5 minutes)");
//Toast.makeText(context,"Timeout",Toast.LENGTH_LONG).show();
otpsmsReceiveListner.onOTPTimeout();
break;
}
}
}
catch (Exception ex){
Toast.makeText(context,ex.getLocalizedMessage(),Toast.LENGTH_LONG).show();
}
}
public interface OTPSMSReceiveListner{
void onOTPReceived(String otp);
void onOTPTimeout();
}
}
OTP class:
SmsRetrieverClient client = SmsRetriever.getClient(mContext);
Task<Void> task = client.startSmsRetriever();
task.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
try
{
Log.e("onSuccess","Successfully started retriever");
}
catch (Exception ex)
{
Log.e("onSuccess",ex.getMessage());
}
}
});
task.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.e("onFailure", "Failed to start retriever");
}
});
OTPBroadcastReceiver.injectListner(new OTPBroadcastReceiver.OTPSMSReceiveListner() {
#Override
public void onOTPReceived(String otp) {
if(otp.length() == 4) {
otpField.setText(otp);
btnVerify.performClick();
}
}
#Override
public void onOTPTimeout() {
Log.e("onOTPTimeout","onOTPTimeout");
}
});
Manifest:
<receiver
android:name=".helpers.OTPBroadcastReceiver"
android:exported="true">
<intent-filter>
<action android:name="com.google.android.gms.auth.api.phone.SMS_RETRIEVED" />
</intent-filter>
</receiver>
SMS:
<#> your App OTP is:8149 585dyDy8cbh
See this answer https://stackoverflow.com/a/55374780/10449332. Please register the BroadcastReceiver inside SmsRetriever addOnSuccessListener callback.
Related
I've all things setup in both server and android side. My flow is working fine. I generated hashkey also, but now don't know where to use it.
Note: I removed RECEIVE_SMS permission and now listener is not calling.
Code:
private void startSMSListener() {
try {
smsReceiver = new SMSReceiver();
smsReceiver.setOTPListener(this);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(SmsRetriever.SMS_RETRIEVED_ACTION);
this.registerReceiver(smsReceiver, intentFilter);
SmsRetrieverClient client = SmsRetriever.getClient(this);
Task<Void> task = client.startSmsRetriever();
task.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
// API successfully started
}
});
task.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
// Fail to start API
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
Update: I'm not getting OTP:
Server side code:
//Prepare Url
OkHttpClient client=new OkHttpClient();
Request request = new Request.Builder()
.url("http://msg.msgclub.net/rest/services/sendSMS/sendGroupSms?AUTH_KEY="+authKey+"&message=<#>You OTP is:"+randomPIN+"TthI79n9NvR&senderId=REMIND&routeId=1&mobileNos="+mobNo+"&smsContentType=english")
.get()
.addHeader("Cache-Control", "no-cache")
.build();
which logic should I try inside onReeive method? can anyone please guide me?
Code:
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import com.google.android.gms.auth.api.phone.SmsRetriever;
import com.google.android.gms.common.api.CommonStatusCodes;
import com.google.android.gms.common.api.Status;
import com.tekitsolution.remindly.Dialog.PaymentListDialog;
import com.tekitsolution.remindly.Listener.SMSListener;
public class SMSReceiver extends BroadcastReceiver {
private static final String TAG = SMSReceiver.class.getSimpleName();
private SMSListener mListener;
/**
* #param mListener
*/
public void setOTPListener(SMSListener mListener) {
this.mListener = mListener;
}
/**
* #param context
* #param intent
*/
#Override
public void onReceive(Context context, Intent intent) {
showLog("Inside SMS Receiver");
if (SmsRetriever.SMS_RETRIEVED_ACTION.equals(intent.getAction())) {
Bundle extras = intent.getExtras();
Status status = (Status) extras.get(SmsRetriever.EXTRA_STATUS);
switch (status.getStatusCode()) {
case CommonStatusCodes.SUCCESS:
//This is the full message
String message = (String) extras.get(SmsRetriever.EXTRA_SMS_MESSAGE);
showLog("message: "+ message);
/*<#> Your ExampleApp code is: 123ABC78
FA+9qCX9VSu*/
//Extract the OTP code and send to the listener
if (mListener != null) {
mListener.onOTPReceived(message);
}
break;
case CommonStatusCodes.API_NOT_CONNECTED:
if (mListener != null) {
mListener.onOTPReceivedError("API NOT CONNECTED");
}
break;
case CommonStatusCodes.NETWORK_ERROR:
if (mListener != null) {
mListener.onOTPReceivedError("NETWORK ERROR");
}
break;
case CommonStatusCodes.ERROR:
if (mListener != null) {
mListener.onOTPReceivedError("SOME THING WENT WRONG");
}
break;
}
}
}
private void showLog(String msg) {
Log.d(TAG, msg);
}
}
OTP activity: called this method inside onCreate:
private void startSMSListener() {
try {
smsReceiver = new SMSReceiver();
smsReceiver.setOTPListener(this);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(SmsRetriever.SMS_RETRIEVED_ACTION);
this.registerReceiver(smsReceiver, intentFilter);
SmsRetrieverClient client = SmsRetriever.getClient(this);
Task<Void> task = client.startSmsRetriever();
task.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
showLog("success");
}
});
task.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
showLog("failure");
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
Your sms format should be
<#> SampleApp: Your verification code is 143567
QbwSot12oP
1) The message should start with <#>, that will indicate this is an OTP message to the system.
2) The message should end with Hashcode e.g QbwSot12oP at the end of the message.
So you have to pass your generated hash to server and append it at last of this sms.
Following is the complete example of retrive api. I used it and it is working in my case
https://medium.com/android-dev-hacks/autofill-otp-verification-with-latest-sms-retriever-api-73c788636783
Generate hash key pragmatically via AppSignatureHelper in given example. And pass it to your server and make message format like I show you before.
I want to retrieve the incoming/outgoing call's phone number, but sometimes the delivered phone number is null. I'm unable to reproduce it, but my clients are reporting that sometimes it's not working. I can confirm this because I have logs about this (~1000 times a day the phone number is empty).
I have 2 different BroadcastReceiver's which extends WakeLockBroadcast. The IntentServices are declared in Android's manifest file.
This is the outgoing call's receiver:
public class OutgoingCallReceiver extends WakeLockBroadcast {
#Override
public void onReceive(Context context, Intent intent) {
Intent service = new Intent(context, OutgoingCallReceiver.PhoneService.class);
if (intent != null && intent.getExtras() != null) {
service.setAction(intent.getAction());
Bundle bundle = new Bundle(intent.getExtras());
service.putExtras(bundle);
}
startWakefulService(context, service);
}
public static class PhoneService extends IntentService {
public PhoneService() {
super("PhoneService outgoing call");
}
#Override
protected void onHandleIntent(#Nullable Intent intent) {
try {
if (intent != null) {
String action = intent.getAction();
if (action != null) {
Bundle bundle = intent.getExtras();
if (bundle != null) {
if (action.equals("android.intent.action.NEW_OUTGOING_CALL")) {
String number = bundle.getString(Intent.EXTRA_PHONE_NUMBER, null);
onOutgoingCall(number);
}
}
}
}
}
catch (Exception e) {
e.printStackTrace();
}
catch (Error e) {
e.printStackTrace();
}
finally {
try {
if (intent != null)
completeWakefulIntent(intent);
}
catch (NullPointerException e) {
e.printStackTrace();
}
}
}
private void onOutgoingCall(String number) {
if (TextUtils.isEmpty(number))
return;
Log.d(APPNAME, "Outgoing call: " + number);
}
}
}
This is the incoming call's receiver:
public class IncomingCallReceiver extends WakeLockBroadcast {
#Override
public void onReceive(Context context, Intent intent) {
Intent service = new Intent(context, IncomingCallReceiver.PhoneService.class);
if (intent != null && intent.getExtras() != null) {
service.setAction(intent.getAction());
Bundle bundle = new Bundle(intent.getExtras());
service.putExtras(bundle);
}
startWakefulService(context, service);
}
public static class PhoneService extends IntentService {
public PhoneService() {
super("PhoneService incoming call");
}
#Override
protected void onHandleIntent(#Nullable Intent intent) {
try {
if (intent != null) {
String action = intent.getAction();
if (action != null) {
Bundle bundle = intent.getExtras();
if (bundle != null) {
// Incoming call
if (action.equals("android.intent.action.PHONE_STATE")) {
String stateStr = bundle.getString(TelephonyManager.EXTRA_STATE, "");
String number = bundle.getString(TelephonyManager.EXTRA_INCOMING_NUMBER, "");
int state = 0;
if (stateStr.equals(TelephonyManager.EXTRA_STATE_IDLE)) {
state = TelephonyManager.CALL_STATE_IDLE;
} else if (stateStr.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) {
state = TelephonyManager.CALL_STATE_OFFHOOK;
} else if (stateStr.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
state = TelephonyManager.CALL_STATE_RINGING;
}
if (state == TelephonyManager.CALL_STATE_IDLE) {
onCallEnd();
}
else if (state == TelephonyManager.CALL_STATE_RINGING) {
onIncomingCall(number);
}
}
}
}
}
}
catch (Exception e) {
e.printStackTrace();
}
catch (Error e) {
e.printStackTrace();
}
finally {
try {
if (intent != null)
completeWakefulIntent(intent);
}
catch (NullPointerException e) {
e.printStackTrace();
}
}
}
private void onCallEnd() {
}
private void onIncomingCall(String phoneNumber) {
if (TextUtils.isEmpty(phoneNumber))
return;
Log.d("APPNAME", "Incoming call: " + phoneNumber);
}
}
}
The Android's manifest file:
<receiver android:name=".broadcast.IncomingCallReceiver">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>
<receiver android:name=".broadcast.OutgoingCallReceiver">
<intent-filter>
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
</intent-filter>
</receiver>
Services:
<service android:name=".broadcast.IncomingCallReceiver$PhoneService" />
<service android:name=".broadcast.OutgoingCallReceiver$PhoneService" />
I might think that the intent or the intent's bundle is empty. As you can see, I'm making a check before if intent or bundle is different than null and after that setting the data to the newly created intent.
I am writing an app for android which communicates to the device and back to the wear. This is the code of onclick on wear.
message1Button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Wearable.MessageApi.sendMessage(apiClient, remoteNodeId, MESSAGE1_PATH, null).setResultCallback(new ResultCallback<MessageApi.SendMessageResult>() {
#Override
public void onResult(MessageApi.SendMessageResult sendMessageResult) {
Intent intent = new Intent(getApplicationContext(), ConfirmationActivity.class);
if (sendMessageResult.getStatus().isSuccess()) {
intent.putExtra(ConfirmationActivity.EXTRA_ANIMATION_TYPE, ConfirmationActivity.SUCCESS_ANIMATION);
intent.putExtra(ConfirmationActivity.EXTRA_MESSAGE, getString(R.string.message1_sent));
} else {
intent.putExtra(ConfirmationActivity.EXTRA_ANIMATION_TYPE, ConfirmationActivity.FAILURE_ANIMATION);
intent.putExtra(ConfirmationActivity.EXTRA_MESSAGE, getString(R.string.error_message1));
}
startActivity(intent);
}
});
The following is the code for on received on Handheld device.
public void onMessageReceived(MessageEvent messageEvent) {
if (messageEvent.getPath().equals(MESSAGE1_PATH)) {
handler.post(new Runnable() {
#Override
public void run() {
receivedMessagesEditText.append("\n" + getString(R.string.received_message1));
String serverURL = "A Working URL";
try {
ArrayList<String> list=new ArrayList<String>();
list.add(0,serverURL);
list.add(1,"SELECT DISTINCT ACCOUNTNO FROM CUSTOMR_WISE_WALLET_POINTS ORDER BY ACCOUNTNO");
jsonContent= new LongOperation().execute(list).get();
} catch (InterruptedException e) {
Log.e("Error",e.getMessage());
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
Log.d("Value of json",jsonContent);
}
});
Wearable.MessageApi.sendMessage(apiClient, remoteNodeId, MESSAGE4_PATH, jsonContent.getBytes()).setResultCallback(new ResultCallback<MessageApi.SendMessageResult>() {
#Override
public void onResult(MessageApi.SendMessageResult sendMessageResult) {
if (sendMessageResult.getStatus().isSuccess())
Toast.makeText(getApplication(), "Message 4 sent", Toast.LENGTH_SHORT).show();
else
Toast.makeText(getApplication(), getString(R.string.error_message1), Toast.LENGTH_SHORT).show();
}
});
} else if (messageEvent.getPath().equals(MESSAGE2_PATH)) {
handler.post(new Runnable() {
#Override
public void run() {
receivedMessagesEditText.append("\n" + getString(R.string.received_message2));
}
});
}
}
The handheld device shows "Message 4 sent" toast. but the message listener on the wear is never triggered.The code for which is.
messageListener = new MessageApi.MessageListener() {
#Override
public void onMessageReceived(final MessageEvent messageEvent) {
Log.d("Inside","On message recieved");
if (messageEvent.getPath().equals(MESSAGE1_PATH)) {
handler.post(new Runnable() {
#Override
public void run() {
receivedMessagesEditText.append("\n" + getString(R.string.received_message1));
/*COde to send another request*/
Wearable.MessageApi.sendMessage(apiClient, remoteNodeId, MESSAGE3_PATH, "Hello".getBytes()).setResultCallback(new ResultCallback<MessageApi.SendMessageResult>() {
#Override
public void onResult(MessageApi.SendMessageResult sendMessageResult) {
Intent intent = new Intent(getApplicationContext(), ConfirmationActivity.class);
if (sendMessageResult.getStatus().isSuccess()) {
intent.putExtra(ConfirmationActivity.EXTRA_ANIMATION_TYPE, ConfirmationActivity.SUCCESS_ANIMATION);
intent.putExtra(ConfirmationActivity.EXTRA_MESSAGE, "Message 3 sent");
} else {
intent.putExtra(ConfirmationActivity.EXTRA_ANIMATION_TYPE, ConfirmationActivity.FAILURE_ANIMATION);
intent.putExtra(ConfirmationActivity.EXTRA_MESSAGE, getString(R.string.error_message2));
}
startActivity(intent);
}
});
}
});
} else if (messageEvent.getPath().equals(MESSAGE2_PATH)) {
handler.post(new Runnable() {
#Override
public void run() {
receivedMessagesEditText.append("\n" + getString(R.string.received_message2));
}
});
}
else if(messageEvent.getPath().equals(MESSAGE4_PATH)){
handler.post(new Runnable() {
#Override
public void run() {
receivedMessagesEditText.append("\n" + getString(R.string.received_message1));
/*COde to send another request*/
// String jsonInString=new String(messageEvent.getData());
Log.d("Inside Message 4","Inside");
String[] items = new String[]{"Select User", "2", "three"};
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_spinner_dropdown_item, items);
dropdown.setAdapter(adapter);
message2Button.setEnabled(true);
}
});
}
}
};
To summarize, I can send the message from wear and trigger messagerecieved on the handhled. The message is successfully sent from handheld but the on message received is not triggered on the wear when called from within the scope of messagelistener . I checked the app Id , they are same.I also tested on message recieved on the wear by triggering with button2 from handheld.It works fine. Thanks in advance
MessageApi does not guarantee that a message will be received even a successful result code returned. Check the document here.
Note: A successful result code does not guarantee delivery of the message. If your app requires data reliability, use DataItem objects or the ChannelApi class to send data between devices.
I'm trying to use gcm to start calls in sinch, I send the push notification and I get it on the other side but when I try to start a call I get null pointer exception in my service at mCall.addCallListener( );
this is the part of the gcm intent service where I get the notification and start sinch service :
{
String callId = intent.getExtras().getString("callId");
Intent intent3 = new Intent(this, SinchClientService.class);
intent3.setAction(SinchClientService.ACTION_START_CALL);
intent3.putExtra(SinchClientService.INTENT_EXTRA_CALLID, callId);
startService(intent3);
}
this is what I do in the sinch service:
else if(intent.getAction().equals(ACTION_START_CALL))
{
String callId = intent.getStringExtra(INTENT_EXTRA_CALLID);
if(callId != null)
{
startCall(callId);
}
}
public void startCall(String callId) {
if (mCallClient != null) {
Call call = mCallClient.getCall(callId);
CurrentCall.currentCall = call;
Intent intent = new Intent(this, CallService.class);
startService(intent);
}
}
and this is how I start sinch client:
private void startSinchClient(String id, String userName) {
mSinchClient = Sinch.getSinchClientBuilder().context(this).userId(id).
applicationKey(APP_KEY).applicationSecret(APP_SECRET).environmentHost(ENVIRONMENT).build();
mSinchClient.addSinchClientListener(this);
mSinchClient.setSupportCalling(true);
mSinchClient.setSupportMessaging(true);
mSinchClient.setSupportPushNotifications(true);
mSinchClient.setSupportActiveConnectionInBackground(false);
//mSinchClient.startListeningOnActiveConnection();
mMessageClient = mSinchClient.getMessageClient();
mMessageClient.addMessageClientListener(this);
mCallClient = mSinchClient.getCallClient();
mCallClient.addCallClientListener(this);
mSinchClient.checkManifest();
mSinchClient.start();
}
and this is my onIcommingCall method:
#Override
public void onIncomingCall(CallClient client, Call call) {
Log.d(TAG, "Incoming call");
CurrentCall.currentCall = call;
Intent intent = new Intent(this, CallService.class);
startService(intent);
}
and this is the part of my call service where I get null pointer exception:
if(CurrentCall.currentCall == null)
stopSelf();
mCall = CurrentCall.currentCall;
mCall.addCallListener(this);
Note: my call service implements call listener
I never get the call, can someone help me?
Edit this is how I initialize a call:
in the sinch service:
public void callFriend(String id) {
if (mCallClient != null) {
Call call = mCallClient.callUser(id);
CurrentCall.currentCall = call;
Intent intent = new Intent(this, CallService.class);
startService(intent);
}
}
in the call service:
#Override
public void onShouldSendPushNotification(Call call, List<PushPair> pushPairs) {
Log.d(LOG_TAG, "Should send push notification");
Log.d("payload", pushPairs.get(0).getPushPayload());
asyncTask = new sendPushNotifications(this, call.getRemoteUserId(), pushPairs, call.getCallId());
asyncTask.execute();
}
class sendPushNotifications extends AutoAsyncTask {
List<PushPair> pushPairs;
String message;
String senderId;
String message_id;
String time_stamp;
String callId;
public sendPushNotifications(Context context, String senderId, List<PushPair> pushPairs, String callId) {
super(context, false);
this.pushPairs = pushPairs;
this.senderId = senderId;
this.callId = callId;
}
#Override
protected Integer doInBackground(Void... params) {
boolean connectedToInternet = connManager.getNetworkInfo( ConnectivityManager.TYPE_WIFI).isConnected()
|| connManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).isConnected();
if (connectedToInternet)
{
String regId;
//JSONArray arrayList = new JSONArray();
for(PushPair p: pushPairs)
{
regId = new String(p.getPushData());
//arrayList.put(regId);
UserFunctions.sendCallPushNotifications(senderId, regId, "call", callId);
}
asyncTask = null;
return 0;
}
else
{
asyncTask = null;
return 1;
}
}
#Override
protected void onPostExecute(Integer result) {
super.onPostExecute(result);
if (result == 0)
{
Log.d("call push sent", "sent");
}
else if (result == 1)
{
Toast.makeText(getApplicationContext(),
"No Network Connection !!", Toast.LENGTH_SHORT).show();
}
else
{
Toast.makeText(
getApplicationContext(),
"Error occured,Please Try Again Later !!",
Toast.LENGTH_SHORT).show();
}
}
}
}
latest edit so I did what you said and I only get calls in the messaging activity, my new codes are:
in the call service:
#Override
public void onShouldSendPushNotification(Call call, List<PushPair> pushPairs) {
Log.d(LOG_TAG, "Should send push notification");
Log.d("payload", pushPairs.get(0).getPushPayload());
asyncTask = new sendPushNotifications(this, call.getRemoteUserId(), pushPairs, call.getCallId());
asyncTask.execute();
}
class sendPushNotifications extends AutoAsyncTask {
List<PushPair> pushPairs;
String message;
String senderId;
String message_id;
String time_stamp;
String callId;
public sendPushNotifications(Context context, String senderId, List<PushPair> pushPairs, String callId) {
super(context, false);
this.pushPairs = pushPairs;
this.senderId = senderId;
this.callId = callId;
}
#Override
protected Integer doInBackground(Void... params) {
boolean connectedToInternet = connManager.getNetworkInfo( ConnectivityManager.TYPE_WIFI).isConnected()
|| connManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).isConnected();
if (connectedToInternet)
{
String regId;
String payload;
//JSONArray arrayList = new JSONArray();
for(PushPair p: pushPairs)
{
regId = new String(p.getPushData());
payload = new String(p.getPushPayload());
//arrayList.put(regId);
UserFunctions.sendCallPushNotifications(senderId, regId, "call", callId, payload);
}
asyncTask = null;
return 0;
}
else
{
asyncTask = null;
return 1;
}
}
#Override
protected void onPostExecute(Integer result) {
super.onPostExecute(result);
if (result == 0)
{
Log.d("call push sent", "sent");
}
else if (result == 1)
{
Toast.makeText(getApplicationContext(),
"No Network Connection !!", Toast.LENGTH_SHORT).show();
}
else
{
Toast.makeText(
getApplicationContext(),
"Error occured,Please Try Again Later !!",
Toast.LENGTH_SHORT).show();
}
}
}
the gcm intent service:
else
{
String callId = intent.getExtras().getString("callId");
String payload = intent.getExtras().getString("payload");
Intent intent3 = new Intent(this, SinchClientService.class);
intent3.setAction(SinchClientService.ACTION_START_CALL);
intent3.putExtra(SinchClientService.INTENT_EXTRA_CALLID, callId);
intent3.putExtra(SinchClientService.INTENT_EXTRA_PAYLOAD, payload);
startService(intent3);
}
the sinch service:
else if(intent.getAction().equals(ACTION_START_CALL))
{
String callId = intent.getStringExtra(INTENT_EXTRA_CALLID);
if(callId != null)
{
startCall(callId);
}
}
public void startCall(String callId) {
/*if (mCallClient != null) {
Call call = mCallClient.getCall(callId);
CurrentCall.currentCall = call;
Intent intent = new Intent(this, CallService.class);
startService(intent);
}*/
if(INTENT_EXTRA_PAYLOAD != null)
{
if(mSinchClient.isStarted())
mSinchClient.relayRemotePushNotificationPayload(INTENT_EXTRA_PAYLOAD);
else
{
DatabaseHandler handler = new DatabaseHandler(this);
UserInfo info = handler.getUserDetails();
startSinchClient(String.valueOf(info.uid), info.name);
String gcm_regId = ChatDatabaseHandler.getInstance(this).getGcmRegId();
mSinchClient.registerPushNotificationData(gcm_regId.getBytes());
}
}
}
#Override
public void onIncomingCall(CallClient client, Call call) {
Log.d(TAG, "Incoming call");
/*if(INTENT_EXTRA_CALLID != null)
{
CurrentCall.currentCall = mCallClient.getCall(INTENT_EXTRA_CALLID);
INTENT_EXTRA_CALLID = null;
}*/
CurrentCall.currentCall = call;
Intent intent = new Intent(this, CallService.class);
startService(intent);
}
that is also what I do when I bind and unbind with the service:
#Override
public boolean onUnbind(Intent intent) {
mSinchClient.stopListeningOnActiveConnection();
return super.onUnbind(intent);
}
#Override
public IBinder onBind(Intent intent) {
mSinchClient.startListeningOnActiveConnection();
return mServiceInterface;
}
You seem to be missing the code where you actually send the Sinch-specific payload in your push, you should use PushPair.getPushPayload() to retrieve it in the onShouldSendPushNotification callback and make sure to include that in the push message.
After you add that, you need to retrieve the payload on the receiver side and pass in to relayRemotePushNotificationPayload(String payload). This will give you the onIncomingCall callback on the receiver side.
I tried https://github.com/pubnub/java/tree/master/android#connection-durability-reconnecting--resuming-when-a-connection-is-lost-or-changed but still I'm not able to figure out how to use setResumeOnReconnect() .
I'm running android-service and added following code snippet inside onCreate() of the service.
pubnubBroadcastReceiver =new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
ConnectivityManager connectivityManager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
int networkType = intent.getExtras().getInt(ConnectivityManager.EXTRA_NETWORK_TYPE);
NetworkInfo networkInfo = connectivityManager.getNetworkInfo(networkType);
boolean isConnected = networkInfo.isConnected();
if(isConnected) {
ApplicationLoader.getPubnub().disconnectAndResubscribe();
// ApplicationLoader.getPubnub().setResumeOnReconnect(true);
}
}
};
registerReceiver(pubnubBroadcastReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
}
Don't know what I'm missing here.
As per PubNub sample chat, you need to implement code to get the last n messages(n: number of messages preferred).
/**
* Get last 100 messages sent on current channel from history.
*/
public void history() {
this.mPubNub.history(this.channel, 100, false, new Callback() {
#Override
public void successCallback(String channel, final Object message) {
try {
JSONArray json = (JSONArray) message;
Log.d("History", json.toString());
final JSONArray messages = json.getJSONArray(0);
final List<ChatMessage> chatMsgs = new ArrayList<ChatMessage>();
for (int i = 0; i < messages.length(); i++) {
try {
if (!messages.getJSONObject(i).has("data"))
continue;
JSONObject jsonMsg = messages.getJSONObject(i)
.getJSONObject("data");
String name = jsonMsg
.getString(Constants.JSON_USER);
String msg = jsonMsg.getString(Constants.JSON_MSG);
long time = jsonMsg.getLong(Constants.JSON_TIME);
ChatMessage chatMsg = new ChatMessage(name, msg,
time);
chatMsgs.add(chatMsg);
} catch (JSONException e) { // Handle errors silently
e.printStackTrace();
}
}
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(MainActivity.this, "RUNNIN",
Toast.LENGTH_SHORT).show();
mChatAdapter.setMessages(chatMsgs);
}
});
} catch (JSONException e) {
e.printStackTrace();
}
}
#Override
public void errorCallback(String channel, PubnubError error) {
Log.d("History", error.toString());
}
});
}