I just start android with a small project. I am trying to do the following:
STEP 1. get the response from an url [https://client.itscholarbd.com/getsmsdata]
STEP 2. send sms based on the data received from step 1
STEP 3. DELETE the data which is processed. i.e. sms is sent. this is done by DELETE request with ID
STEP 4. REPEAT from STEP 1.
Here is my code:
package com.pkappstudio.smsv20;
import android.app.Activity;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.telephony.SmsManager;
import android.util.Log;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.core.app.NotificationCompat;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonArrayRequest;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class BackgroundService extends Service {
private static final String SMS_SENT_ACTION = "com.pkappstudio.smsv20.SMS_SENT";
private static final String EXTRA_NUMBER = "number";
private static final String EXTRA_MESSAGE = "message";
private RequestQueue requestQueue;
private SmsManager smsManager;
private BroadcastReceiver resultsReceiver;
private boolean start = true;
private String base_url = "https://client.itscholarbd.com";
#Override
public void onCreate() {
super.onCreate();
smsManager = SmsManager.getDefault();
resultsReceiver = new SmsResultReceiver();
IntentFilter intentFilter = new IntentFilter(SMS_SENT_ACTION);
registerReceiver(resultsReceiver, intentFilter);
requestQueue = Volley.newRequestQueue(this);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
String macAddress = intent.getStringExtra("MAC");
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
Notification notification = new NotificationCompat.Builder(this, App.CHANNEL_ID)
.setContentTitle("SMS v2.0-Service Running")
.setContentText(macAddress)
.setSmallIcon(R.drawable.ic_message)
.setContentIntent(pendingIntent)
.build();
startForeground(1, notification);
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
//our action starts here
if (start) {
jsonParse();
}
handler.postDelayed(this, 8000);
}
}, 8000);
return START_NOT_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(resultsReceiver);
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
private void jsonParse() {
String url = base_url+"/getsmsdata?mac=" + App.MAC_ADDRESS;
JsonObjectRequest request = new JsonObjectRequest(Request.Method.POST, url, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray array = response.getJSONArray("response");
getData(array);
Log.i("reposnse", array.toString());
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.i("JSONDATA", error.toString());
}
});
requestQueue.add(request);
}
private void getData(JSONArray array) {
for (int i = 0; i < array.length(); i++) {
try {
JSONObject object = array.getJSONObject(i);
String string = object.getString("phone");
int id = Integer.parseInt(object.getString("id"));
int user_id = Integer.parseInt(object.getString("user_id"));
String message = object.getString("message");
double smsLength = message.length();
double perSmsLength = 160;
double FakeQuantity = smsLength / perSmsLength;
int quantity = (int) Math.ceil(FakeQuantity);
start = false;
Log.i("debug", message);
sendNextMessage(id, string, message, quantity, user_id);
deleteFromDB(id);
} catch (Exception e) {
e.printStackTrace();
}
}
}
private void deleteFromDB(int id) {
String url = base_url+"/deletedata?id=" + id + "&mac=" + App.MAC_ADDRESS;
StringRequest request = new StringRequest(Request.Method.DELETE, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.i("resonse", response);
jsonParse();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.i("resonse", error.toString());
}
});
requestQueue.add(request);
}
private void sendStatusToServer(JSONArray array) {
String url = base_url+"/addsmslog?mac=" + App.MAC_ADDRESS;
JsonArrayRequest request = new JsonArrayRequest(Request.Method.POST, url, array, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Log.i("response", response.toString());
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.i("response", error.toString());
}
});
requestQueue.add(request);
}
private void sendNextMessage(int id, String number, String message, int quantity, int user_id) {
int requestCode = id + Integer.parseInt(number);
Intent sentIntent = new Intent(SMS_SENT_ACTION);
sentIntent.putExtra(EXTRA_NUMBER, number);
sentIntent.putExtra(EXTRA_MESSAGE, message);
sentIntent.putExtra("quantity", quantity);
sentIntent.putExtra("user_id", user_id);
sentIntent.putExtra("id", id);
PendingIntent sentPI = PendingIntent.getBroadcast(this,
requestCode,
sentIntent,
PendingIntent.FLAG_ONE_SHOT);
// Send our message.
Log.i("dValues", id + " " + number + " " + message);
smsManager.sendTextMessage(number, null, message, sentPI, null);
}
private class SmsResultReceiver extends BroadcastReceiver {
#RequiresApi(api = Build.VERSION_CODES.M)
#Override
public void onReceive(Context context, Intent intent) {
// Get the result action.
String action = intent.getAction();
// Retrieve the recipient's number and message.
String number = intent.getStringExtra(EXTRA_NUMBER);
String message = intent.getStringExtra(EXTRA_MESSAGE);
int user_id = intent.getIntExtra("user_id", 0);
int quantity = intent.getIntExtra("quantity", 0);
String sent_result;
if (SMS_SENT_ACTION.equals(action)) {
start = true;
int resultCode = getResultCode();
sent_result = translateSentResult(resultCode);
JSONObject object = new JSONObject();
JSONArray array = new JSONArray();
try {
object.put("phone", number);
object.put("message", message);
object.put("quantity", quantity);
object.put("user_id", user_id);
object.put("status", sent_result);
object.put("delivered", null);
} catch (Exception e) {
e.printStackTrace();
}
array.put(object);
sendStatusToServer(array);
Log.i("dResponse", array.toString());
}
}
String translateSentResult(int resultCode) {
switch (resultCode) {
case Activity.RESULT_OK:
return "Sent";
case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
return "Failed";
case SmsManager.RESULT_ERROR_RADIO_OFF:
return "Radio off";
case SmsManager.RESULT_ERROR_NULL_PDU:
return "PDU Error";
case SmsManager.RESULT_ERROR_NO_SERVICE:
return "Error Service";
default:
return "Unknown error code";
}
}
}
}
Everything works like a charm. some data is being processed twice. Suppose. at step 1: we got the following json data:
{"response":[{"id":395,"phone":"01620010950","message":"testing! -
itscholarbd.com","user_id":1},{"id":396,"phone":"01673050495","message":"testing! - itscholarbd.com","user_id":1}]}
Then id: 395 is processed twice. I struggle with such problem for 2 days. at last I post here for any idea. Thanks in advance.
I guess that the problem is by calling jsonParse() again in your deleteFromDB(...) method:
private void deleteFromDB(int id) {
.......
.......
#Override
public void onResponse(String response) {
Log.i("resonse", response);
//here, I guess this is the problem
jsonParse();
}
......
......
}
Related
package kr.phpdev.call;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.telephony.PhoneNumberUtils;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.widget.Toast;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
public class PhoneStateReceiver extends BroadcastReceiver {
static String mLastState;
static final String TAG = "Call Manager";
final OkHttpClient client = new OkHttpClient();
#Override
public void onReceive(Context context, Intent intent) {
CallReceivedChk(context, intent);
}
private void CallReceivedChk(Context context, Intent intent) {
TelephonyManager telephony = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
telephony.listen(new PhoneStateListener() {
#Override
public void onCallStateChanged(int state, String incomingNumber) {
String mState = String.valueOf(state);
if (mState.equals(mLastState)) { // 두번 호출되는 문제 해결 목적
return;
} else {
mLastState = mState;
}
switch (state) {
case TelephonyManager.CALL_STATE_IDLE:
Log.d(TAG, "CALL_IDLE");
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
Log.d(TAG, "CALL_OFFHOOK");
break;
case TelephonyManager.CALL_STATE_RINGING:
Log.d(TAG, "CALL_RINGING >>> " + PhoneNumberUtils.formatNumber(incomingNumber));
RequestBody formBody = new FormBody.Builder()
.add("pn", PhoneNumberUtils.formatNumber(incomingNumber))
.build();
final Request request = new Request.Builder()
.url("http://phpdev.kr/cm/logsend.php")
.post(formBody)
.build();
AsyncTask<String, String, String> asyncTask = new AsyncTask<String, String, String>() {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... params) {
try {
Response response = client.newCall(request).execute();
if (!response.isSuccessful()) {
return null;
}
return response.body().string();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
if (s != "FAILED") {
Log.d(TAG, s);
Toast.makeText(getApplicationContext(), "토스트메시지입니다.", Toast.LENGTH_SHORT).show();
}
}
};
asyncTask.execute();
break;
}
}
}, PhoneStateListener.LISTEN_CALL_STATE);
}
}
how can i get toast message?
You need to do that on onPostExecute since it is running on the UI thread. And also in Java string comparison is like s.equals("Failed"):
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
if (!s.equals("FAILED")) {
Log.d(TAG, s);
Toast.makeText(context, "토스트메시지입니다.", Toast.LENGTH_SHORT).show();
}
}
Use Toast.makeText(context, "토스트메시지입니다.",Toast.LENGTH_SHORT).show();`
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
if (s != "FAILED") {
Log.d(TAG, s);
Toast.makeText(context, "토스트메시지입니다.", Toast.LENGTH_SHORT).show();
}
}
Error:(103, 68) error: local variable context is accessed from within inner class; needs to be declared final. You just need using "context" instead of "getApplicationContext()".
I tried the same code in Activity and it worked but the same code in fragment doesn't work.
SignUpFragment.java:
package com.conversionbug.alltee;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.Typeface;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.design.widget.Snackbar;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.content.ContextCompat;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.facebook.AccessToken;
import com.facebook.CallbackManager;
import com.facebook.FacebookCallback;
import com.facebook.FacebookException;
import com.facebook.FacebookSdk;
import com.facebook.GraphRequest;
import com.facebook.GraphResponse;
import com.facebook.LoggingBehavior;
import com.facebook.login.LoginResult;
import com.facebook.login.widget.LoginButton;
import com.google.android.gms.auth.api.Auth;
import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
import com.google.android.gms.auth.api.signin.GoogleSignInResult;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.SignInButton;
import com.google.android.gms.common.api.GoogleApiClient;
import com.twitter.sdk.android.core.Callback;
import com.twitter.sdk.android.core.Result;
import com.twitter.sdk.android.core.Twitter;
import com.twitter.sdk.android.core.TwitterAuthToken;
import com.twitter.sdk.android.core.TwitterCore;
import com.twitter.sdk.android.core.TwitterException;
import com.twitter.sdk.android.core.TwitterSession;
import com.twitter.sdk.android.core.identity.TwitterAuthClient;
import com.twitter.sdk.android.core.identity.TwitterLoginButton;
import org.json.JSONObject;
import java.util.Arrays;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import static com.conversionbug.alltee.Constants.ROOT_LOGIN;
import static com.conversionbug.alltee.Constants.ROOT_TOKEN;
import static com.conversionbug.alltee.Constants.SOCIAL_REGISTER;
import static com.facebook.FacebookSdk.getApplicationContext;
public class SignUpFragment extends Fragment implements View.OnClickListener, GoogleApiClient.OnConnectionFailedListener {
TextView loginTV;
Button nextActivity;
EditText name;
EditText email;
EditText password;
LinearLayout linear_main;
String googleName;
String googleEmail;
String googleUserAccessToken;
String googleUserSocialId;
String facebookEmail;
String facebookId;
String facebookName;
String facebookToken;
ImageButton facebook_icon1;
LoginButton facebook_sign_in_button1;
ImageButton google_plus_icon1;
SignInButton googleSignIn1;
ImageButton twitter_icon;
TwitterLoginButton twitter1;
CallbackManager callbackManager;
private GoogleApiClient googleApiClient1;
private static final int REQ_CODE = 9001;
GoogleSignInOptions signInOptions;
TwitterSession session;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_sign_up, container, false);
FacebookSdk.sdkInitialize(getApplicationContext());
callbackManager = CallbackManager.Factory.create();
Twitter.initialize(getActivity()); //Twitter is initialized
loginTV = (TextView) view.findViewById(R.id.loginTV);
nextActivity = (Button) view.findViewById(R.id.nextActivity);
name = (EditText) view.findViewById(R.id.name);
email = (EditText) view.findViewById(R.id.email);
password = (EditText) view.findViewById(R.id.password);
linear_main = (LinearLayout) view.findViewById(R.id.linearMain1);
facebook_icon1 = (ImageButton) view.findViewById(R.id.facebook_icon1);
facebook_sign_in_button1 = (LoginButton) view.findViewById(R.id.facebook_sign_in_button1);
facebook_sign_in_button1.setReadPermissions(Arrays.asList("email"));
twitter1 = (TwitterLoginButton) view.findViewById(R.id.twitter1);
twitter_icon = (ImageButton) view.findViewById(R.id.twitter_icon);
google_plus_icon1 = (ImageButton) view.findViewById(R.id.google_plus_icon1);
googleSignIn1 = (SignInButton) view.findViewById(R.id.googleSignIn1);
facebook_sign_in_button1.setFragment(this);
signInOptions = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN).requestIdToken(getString(R.string.default_web_client_id)).requestEmail().build();
googleApiClient1 = new GoogleApiClient.Builder(getActivity())
//.enableAutoManage(getActivity() /* FragmentActivity */, 1, this /* OnConnectionFailedListener */)
.addApi(Auth.GOOGLE_SIGN_IN_API, signInOptions)
.build();
try {
session = TwitterCore.getInstance().getSessionManager().getActiveSession();
} catch (Exception exception) {
exception.printStackTrace();
}
facebook_icon1.setOnClickListener(this);
google_plus_icon1.setOnClickListener(this);
twitter_icon.setOnClickListener(this);
facebook_sign_in_button1.registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
GraphRequest request = GraphRequest.newMeRequest(
loginResult.getAccessToken(),
new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(JSONObject object, GraphResponse response) {
FacebookSdk.setIsDebugEnabled(true);
FacebookSdk.addLoggingBehavior(LoggingBehavior.INCLUDE_ACCESS_TOKENS);
facebookToken = AccessToken.getCurrentAccessToken().getToken();
try {
facebookEmail = object.getString("email");
facebookId = object.getString("id");
facebookName = object.getString("name");
Toast.makeText(getActivity(), "Email: " + facebookEmail + " Id: " + facebookId + " Name: " + facebookName + " Access Token: " + facebookToken, Toast.LENGTH_LONG).show();
} catch (Exception e) {
e.printStackTrace();
}
FacebookRegisterTask facebookRegisterTask = new FacebookRegisterTask();
facebookRegisterTask.execute(SOCIAL_REGISTER);
}
});
Bundle parameters = new Bundle();
parameters.putString("fields", "email,id,name");
request.setParameters(parameters);
request.executeAsync();
}
#Override
public void onCancel() {
Toast.makeText(getApplicationContext(), "Login Cancel", Toast.LENGTH_LONG).show();
}
#Override
public void onError(FacebookException e) {
Toast.makeText(getApplicationContext(), "Login Error", Toast.LENGTH_LONG).show();
}
});
loginTV.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view1) {
Fragment fragment = new LoginFragment();
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.addToBackStack(null);
fragmentTransaction.replace(R.id.container_body, fragment);
fragmentTransaction.commit();
}
});
nextActivity.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
RegisterTask registerTask = new RegisterTask();
registerTask.execute(ROOT_LOGIN);
String nameValidation = name.getText().toString().trim();
String emailValidation = email.getText().toString().trim();
String passwordValidation = password.getText().toString().trim();
String namePattern = "[A-Za-z. ]+";
String emailPattern = "[a-z0-9._]+#[a-z]+\\.+[a-z]+";
if (nameValidation.matches(namePattern) && name.length() <= 255 && emailValidation.matches(emailPattern) && passwordValidation.length() >= 6) {
} else {
Snackbar snackbar = Snackbar.make(linear_main, "Wrong Username or Password !!!", Snackbar.LENGTH_LONG);
View sbView = snackbar.getView();
TextView textView = (TextView) sbView.findViewById(android.support.design.R.id.snackbar_text);
textView.setTextColor(Color.RED);
textView.setTypeface(null, Typeface.BOLD);
textView.setTextSize(16f);
sbView.setBackgroundColor(ContextCompat.getColor(getActivity(), R.color.red));
textView.setTextColor(ContextCompat.getColor(getActivity(), R.color.white));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1)
textView.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
else
textView.setGravity(Gravity.CENTER_HORIZONTAL);
snackbar.show();
}
}
});
twitter1.setCallback(new Callback<TwitterSession>() {
#Override
public void success(Result<TwitterSession> result) {
TwitterAuthToken authToken = session.getAuthToken();
String token = authToken.token;
String secret = authToken.secret;
session = result.data;
String userName = session.getUserName().toString();
long userId = session.getId();
if(userName.isEmpty()) {
Toast.makeText(getActivity(), "Data isn't fetched", Toast.LENGTH_LONG).show();
}
else {
Toast.makeText(getActivity(), "Login Successful with token: " + token + "\n secret: " + secret + "\n User Name: " + userName + "\n Id: " + userId, Toast.LENGTH_LONG).show();
}
/*getUserData();*/
}
#Override
public void failure(TwitterException exception) {
Toast.makeText(getApplicationContext(), "Login Failure", Toast.LENGTH_LONG).show();
}
});
return view;
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
callbackManager.onActivityResult(requestCode, resultCode, data);
Toast.makeText(getActivity(),"inside onActivityResult",Toast.LENGTH_LONG).show();
if (requestCode == REQ_CODE) {
GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
handleResult(result);
}
Fragment fragment = getFragmentManager().findFragmentById(R.id.linearMain1);
if (fragment != null) {
fragment.onActivityResult(requestCode, resultCode, data);
}
}
/*void getUserData() {
TwitterAuthClient authClient = new TwitterAuthClient();
authClient.requestEmail(session, new Callback<String>() {
#Override
public void success(Result<String> result1) {
String s1 = result1.data.toString().toLowerCase();
if(s1.isEmpty()) {
Toast.makeText(getActivity(),"No EmailId",Toast.LENGTH_LONG).show();
}
else {
Toast.makeText(getActivity(),"Email: "+s1,Toast.LENGTH_LONG).show();
}
}
#Override
public void failure(TwitterException exception) {
}
});
}
*/
#Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.facebook_icon1:
facebook_sign_in_button1.performClick();
break;
case R.id.google_plus_icon1:
signIn();
break;
case R.id.twitter_icon:
twitter1.performClick();
break;
}
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
Toast.makeText(getApplicationContext(), "Connection failed G+", Toast.LENGTH_SHORT).show();
}
private void handleResult(GoogleSignInResult result) {
if (result.isSuccess()) {
GoogleSignInAccount account = result.getSignInAccount();
googleName = account.getDisplayName();
googleEmail = account.getEmail();
googleUserAccessToken = account.getIdToken();
googleUserSocialId = account.getId();
Toast.makeText(getActivity(), "Name: " + googleName + " Email: " + googleEmail + " UserAccessToken: " + googleUserAccessToken + " UserSocialId " + googleUserSocialId, Toast.LENGTH_SHORT).show();
GoogleRegisterTask googleRegisterTask = new GoogleRegisterTask();
googleRegisterTask.execute(SOCIAL_REGISTER);
}
}
private void signIn() {
Intent intent = Auth.GoogleSignInApi.getSignInIntent(googleApiClient1);
startActivityForResult(intent, REQ_CODE);
}
#Override
public void onStart() {
super.onStart();
if (googleApiClient1 != null)
googleApiClient1.connect();
}
#Override
public void onStop() {
if (googleApiClient1 != null && googleApiClient1.isConnected()) {
googleApiClient1.disconnect();
}
super.onStop();
}
public class RegisterTask extends AsyncTask<String, Void, String> {
int responseCode;
#Override
protected String doInBackground(String... params) {
try {
OkHttpClient client = new OkHttpClient();
RequestBody postData = new FormBody.Builder()
.add("name", name.getText().toString())
.add("email", email.getText().toString())
.add("password", password.getText().toString())
.build();
Request request = new Request.Builder()
.url(params[0])
.post(postData)
.build();
Response response = client.newCall(request).execute();
responseCode = response.code();
String result = response.body().string();
return result;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
/*Toast.makeText(getActivity(), ""+s.toString(), Toast.LENGTH_SHORT).show();*/
if (responseCode == 200) {
AuthTask authTask = new AuthTask();
authTask.execute(ROOT_TOKEN);
Intent intent = new Intent(getActivity(), BottomNavigationActivity.class);
startActivity(intent);
} else if (s.toString().equals("{\"error\":\"Email id already taken\"}")) {
Toast.makeText(getActivity(), "Email-id already exist", Toast.LENGTH_LONG).show();
}
}
}
public class AuthTask extends AsyncTask<String, Void, String> {
int responseCode1;
#Override
protected String doInBackground(String... params1) {
try {
OkHttpClient client = new OkHttpClient();
RequestBody postData = new FormBody.Builder()
.add("client_id", "2")
.add("client_secret", "oreOeeeN7ZYpCGNFMmW2W1OowPQVaJ92jadcl8B2")
.add("grant_type", "password")
.add("scope", "*")
.add("username", email.getText().toString())
.add("password", password.getText().toString())
.build();
Request request = new Request.Builder()
.url(params1[0])
.post(postData)
.build();
Response response = client.newCall(request).execute();
responseCode1 = response.code();
String result = response.body().string();
return result;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
Toast.makeText(getActivity(), "" + s.toString(), Toast.LENGTH_LONG).show();
}
}
public class GoogleRegisterTask extends AsyncTask<String, Void, String> {
int responseCode;
#Override
protected String doInBackground(String... params) {
try {
OkHttpClient client = new OkHttpClient();
RequestBody postData = new FormBody.Builder()
.add("name", googleName)
.add("email", googleEmail)
.add("access_token", googleUserAccessToken)
.add("social_id", googleUserSocialId)
.add("social", "google_id")
.build();
Request request = new Request.Builder()
.url(params[0])
.post(postData)
.build();
Response response = client.newCall(request).execute();
responseCode = response.code();
String result = response.body().string();
return result;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
if (responseCode == 200) {
GoogleAuthTask googleAuthTask = new GoogleAuthTask();
googleAuthTask.execute(ROOT_TOKEN);
Intent intent = new Intent(getActivity(), BottomNavigationActivity.class);
startActivity(intent);
}
}
}
public class GoogleAuthTask extends AsyncTask<String, Void, String> {
int responseCode1;
#Override
protected String doInBackground(String... params1) {
try {
OkHttpClient client = new OkHttpClient();
RequestBody postData = new FormBody.Builder()
.add("grant_type", "social")
.add("client_id", "2")
.add("client_secret", "oreOeeeN7ZYpCGNFMmW2W1OowPQVaJ92jadcl8B2")
.add("access_token", googleUserAccessToken)
.add("network", "google_id")
.build();
Request request = new Request.Builder()
.url(params1[0])
.post(postData)
.build();
Response response = client.newCall(request).execute();
responseCode1 = response.code();
String result = response.body().string();
return result;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
Toast.makeText(getActivity(), "" + s.toString(), Toast.LENGTH_LONG).show();
}
}
public class FacebookRegisterTask extends AsyncTask<String, Void, String> {
int responseCode;
#Override
protected String doInBackground(String... params) {
try {
OkHttpClient client = new OkHttpClient();
RequestBody postData = new FormBody.Builder()
.add("name", facebookName)
.add("email", facebookEmail)
.add("access_token", facebookToken)
.add("social_id", facebookId)
.add("social", "facebook_id")
.build();
Request request = new Request.Builder()
.url(params[0])
.post(postData)
.build();
Response response = client.newCall(request).execute();
responseCode = response.code();
String result = response.body().string();
return result;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
FacebookAuthTask facebookAuthTask = new FacebookAuthTask();
facebookAuthTask.execute(ROOT_TOKEN);
Intent intent = new Intent(getActivity(), BottomNavigationActivity.class);
startActivity(intent);
Toast.makeText(getActivity(), "" + responseCode, Toast.LENGTH_LONG).show();
}
}
public class FacebookAuthTask extends AsyncTask<String, Void, String> {
int responseCode1;
#Override
protected String doInBackground(String... params1) {
try {
OkHttpClient client = new OkHttpClient();
RequestBody postData = new FormBody.Builder()
.add("grant_type", "social")
.add("client_id", "2")
.add("client_secret", "oreOeeeN7ZYpCGNFMmW2W1OowPQVaJ92jadcl8B2")
.add("access_token", facebookToken)
.add("network", "facebook_id")
.build();
Request request = new Request.Builder()
.url(params1[0])
.post(postData)
.build();
Response response = client.newCall(request).execute();
responseCode1 = response.code();
String result = response.body().string();
return result;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
Toast.makeText(getActivity(), "" + s.toString(), Toast.LENGTH_LONG).show();
}
}
} }
}
}
fragment_sign_up.xml:`
<FrameLayout
android:id="#+id/FrameLayout3"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginLeft="25dp"
android:layout_marginTop="30dp"
android:layout_weight="1">
<com.twitter.sdk.android.core.identity.TwitterLoginButton
android:id="#+id/twitter1"
android:layout_width="40dp"
android:layout_height="40dp"
android:visibility="gone"/>
<ImageButton
android:id="#+id/twitter_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/twitter_icon" />
</FrameLayout>`
After clicking on the button, it is redirecting to the twitter login page and after clicking on "connect" button, it simply returns to the fragment and doesn't show the Toast message. When I Click the button for the second time, it shows toast from failure method.
just add in your activity
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
yourcurrentfragment.onActivityResult(requestCode, resultCode, data);
}
I am displaying a list of messages in my chat room and I'm using RecycleView to display. I want the view to be set to the recent message(last message, last item in the list) instead of the first item. I used smoothScrollToPosition but I don't want the list to be scrolled from first to last to view the recent message. I want it to be like whatsapp which when clicked on a chat would show the view of the last message. How can I achieve this?
package com.webapp.chat.activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.android.volley.DefaultRetryPolicy;
import com.android.volley.NetworkResponse;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.RetryPolicy;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import com.webapp.chat.R;
import com.webapp.chat.adapter.ChatRoomThreadAdapter;
import com.webapp.chat.app.Config;
import com.webapp.chat.app.EndPoints;
import com.webapp.chat.app.MyApplication;
import com.webapp.chat.gcm.NotificationUtils;
import com.webapp.chat.model.Message;
import com.webapp.chat.model.User;
public class ChatRoomActivity extends AppCompatActivity {
private String TAG = ChatRoomActivity.class.getSimpleName();
private String userChatRoomId;
private RecyclerView recyclerView;
private ChatRoomThreadAdapter mAdapter;
private ArrayList<Message> messageArrayList;
private BroadcastReceiver mRegistrationBroadcastReceiver;
private EditText inputMessage;
private Button btnSend;
private String selfUserId;
private String selfUserName;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat_room);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
inputMessage = (EditText) findViewById(R.id.message);
btnSend = (Button) findViewById(R.id.btn_send);
Intent intent = getIntent();
userChatRoomId = intent.getStringExtra("user_id");
String title = intent.getStringExtra("name");
getSupportActionBar().setTitle(title);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
if (userChatRoomId == null) {
Toast.makeText(getApplicationContext(), "User Chat room not found!", Toast.LENGTH_SHORT).show();
finish();
}
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
messageArrayList = new ArrayList<>();
// self user id is to identify the message owner
selfUserId = MyApplication.getInstance().getPrefManager().getUser().getId();
selfUserName = MyApplication.getInstance().getPrefManager().getUser().getName();
mAdapter = new ChatRoomThreadAdapter(this, messageArrayList, selfUserId);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(mAdapter);
mRegistrationBroadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Config.PUSH_NOTIFICATION)) {
// new push message is received
handlePushNotification(intent);
}
}
};
btnSend.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
sendMessage();
}
});
fetchChatThread();
}
#Override
protected void onResume() {
super.onResume();
// registering the receiver for new notification
LocalBroadcastManager.getInstance(this).registerReceiver(mRegistrationBroadcastReceiver,
new IntentFilter(Config.PUSH_NOTIFICATION));
NotificationUtils.clearNotifications();
}
#Override
protected void onPause() {
LocalBroadcastManager.getInstance(this).unregisterReceiver(mRegistrationBroadcastReceiver);
super.onPause();
}
/**
* Handling new push message, will add the message to
* recycler view and scroll it to bottom
* */
private void handlePushNotification(Intent intent) {
Message message = (Message) intent.getSerializableExtra("message");
String userChatRoomId = intent.getStringExtra("user_id");
if (message != null && userChatRoomId != null) {
messageArrayList.add(message);
mAdapter.notifyDataSetChanged();
if (mAdapter.getItemCount() > 1) {
recyclerView.getLayoutManager().smoothScrollToPosition(recyclerView, null, mAdapter.getItemCount() - 1);
}
}
}
/**
* Posting a new message in chat room
* will make an http call to our server. Our server again sends the message
* to all the devices as push notification
* */
private void sendMessage() {
final String message = this.inputMessage.getText().toString().trim();
if (TextUtils.isEmpty(message)) {
Toast.makeText(getApplicationContext(), "Enter a message", Toast.LENGTH_SHORT).show();
return;
}
/** Create chatroom with the other user after sending the message**/
String endPointInsert = EndPoints.CHAT_ROOM.replace("_ID_", selfUserId) + "/" + userChatRoomId;
Log.e(TAG, "endpointInsert: " + endPointInsert);
StringRequest strReque = new StringRequest(Request.Method.GET,
endPointInsert, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.e(TAG, "response: " + response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
NetworkResponse networkResponse = error.networkResponse;
Log.e(TAG, "Volley error: " + error.getMessage() + ", code: " + networkResponse);
Toast.makeText(getApplicationContext(), "Volley error: " + error.getMessage(), Toast.LENGTH_SHORT).show();
}
});
Date date = new Date();
String createdAt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
Log.e(TAG, "TIMESTAMP:" + createdAt);
User user = new User(selfUserId, selfUserName);
final Message msg = new Message();
msg.setId("");
msg.setMessage(message);
msg.setCreatedAt(createdAt);
msg.setUser(user);
messageArrayList.add(msg);
mAdapter.notifyDataSetChanged();
if (mAdapter.getItemCount() > 1) {
// scrolling to bottom of the recycler view
recyclerView.getLayoutManager().smoothScrollToPosition(recyclerView, null, mAdapter.getItemCount() - 1);
}
//Log.e(TAG,msg.getId());
String endPoint = EndPoints.USER_MESSAGE.replace("_ID_", userChatRoomId);
Log.e(TAG, "endpoint: " + endPoint);
this.inputMessage.setText("");
StringRequest strReq = new StringRequest(Request.Method.POST,
endPoint, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.e(TAG, "response: " + response);
try {
JSONObject obj = new JSONObject(response);
// check for error
if (obj.getBoolean("error") == false) {
JSONObject commentObj = obj.getJSONObject("message");
String commentId = commentObj.getString("message_id");
String commentText = commentObj.getString("message");
String createdAt = commentObj.getString("created_at");
JSONObject userObj = obj.getJSONObject("user");
String userId = commentObj.getString("from_user_id");
String userName = userObj.getString("name");
User user = new User(userId, userName);
Log.e(TAG, commentId);
msg.setId(commentId);
/*Message message = new Message();
message.setId(commentId);
message.setMessage(commentText);
message.setCreatedAt(createdAt);
message.setUser(user);*/
/*messageArrayList.add(msg);
mAdapter.notifyDataSetChanged();
if (mAdapter.getItemCount() > 1) {
// scrolling to bottom of the recycler view
recyclerView.getLayoutManager().smoothScrollToPosition(recyclerView, null, mAdapter.getItemCount() - 1);
}*/
} else {
Toast.makeText(getApplicationContext(), "" + obj.getString("message"), Toast.LENGTH_LONG).show();
}
} catch (JSONException e) {
Log.e(TAG, "json parsing error: " + e.getMessage());
Toast.makeText(getApplicationContext(), "json parse error: " + e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
NetworkResponse networkResponse = error.networkResponse;
Log.e(TAG, "Volley error: " + error.getMessage() + ", code: " + networkResponse);
Toast.makeText(getApplicationContext(), "Volley error: " + error.getMessage(), Toast.LENGTH_SHORT).show();
inputMessage.setText(message);
}
}) {
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put("user_id", MyApplication.getInstance().getPrefManager().getUser().getId());
params.put("message", message);
Log.e(TAG, "Params: " + params.toString());
return params;
};
};
// disabling retry policy so that it won't make
// multiple http calls
int socketTimeout = 0;
RetryPolicy policy = new DefaultRetryPolicy(socketTimeout,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
strReq.setRetryPolicy(policy);
//Adding request to request queue
MyApplication.getInstance().addToRequestQueue(strReque);
MyApplication.getInstance().addToRequestQueue(strReq);
Log.i(TAG,msg.getId());
}
/**
* Fetching all the messages of a single chat room
* */
private void fetchChatThread() {
String endPointi = EndPoints.CHAT_USER_THREAD.replace("_ID_", userChatRoomId);
String endPoint = endPointi + "/" + selfUserId;
Log.e(TAG, "endPoint: " + endPoint);
StringRequest strReq = new StringRequest(Request.Method.GET,
endPoint, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.e(TAG, "response: " + response);
try {
JSONObject obj = new JSONObject(response);
// check for error
if (obj.getBoolean("error") == false) {
JSONArray commentsObj = obj.getJSONArray("messages");
for (int i = 0; i < commentsObj.length(); i++) {
JSONObject commentObj = (JSONObject) commentsObj.get(i);
String commentId = commentObj.getString("message_id");
String commentText = commentObj.getString("message");
String createdAt = commentObj.getString("created_at");
JSONObject userObj = commentObj.getJSONObject("user");
String userId = userObj.getString("user_id");
String userName = userObj.getString("username");
User user = new User(userId, userName);
Message message = new Message();
message.setId(commentId);
message.setMessage(commentText);
message.setCreatedAt(createdAt);
message.setUser(user);
messageArrayList.add(message);
}
mAdapter.notifyDataSetChanged();
if (mAdapter.getItemCount() > 1) {
recyclerView.getLayoutManager().smoothScrollToPosition(recyclerView, null, 1);
}
} else {
Toast.makeText(getApplicationContext(), "" + obj.getJSONObject("error").getString("message"), Toast.LENGTH_LONG).show();
}
} catch (JSONException e) {
Log.e(TAG, "json parsing error: " + e.getMessage());
Toast.makeText(getApplicationContext(), "json parse error: " + e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
NetworkResponse networkResponse = error.networkResponse;
Log.e(TAG, "Volley error: " + error.getMessage() + ", code: " + networkResponse);
Toast.makeText(getApplicationContext(), "Volley error: " + error.getMessage(), Toast.LENGTH_SHORT).show();
}
});
//Adding request to request queue
MyApplication.getInstance().addToRequestQueue(strReq);
}
}
package com.webapp.chat.adapter;
/**
* Created by COMP on 17-06-2016.
*/
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import com.webapp.chat.R;
import com.webapp.chat.model.Message;
public class ChatRoomThreadAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static String TAG = ChatRoomThreadAdapter.class.getSimpleName();
private String userId;
private int SELF = 100;
private static String today;
private Context mContext;
private ArrayList<Message> messageArrayList;
public class ViewHolder extends RecyclerView.ViewHolder {
TextView message, timestamp;
public ViewHolder(View view) {
super(view);
message = (TextView) itemView.findViewById(R.id.message);
timestamp = (TextView) itemView.findViewById(R.id.timestamp);
}
}
public ChatRoomThreadAdapter(Context mContext, ArrayList<Message> messageArrayList, String userId) {
this.mContext = mContext;
this.messageArrayList = messageArrayList;
this.userId = userId;
Calendar calendar = Calendar.getInstance();
today = String.valueOf(calendar.get(Calendar.DAY_OF_MONTH));
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView;
// view type is to identify where to render the chat message
// left or right
if (viewType == SELF) {
// self message
itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.chat_item_self, parent, false);
} else {
// others message
itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.chat_item_other, parent, false);
}
return new ViewHolder(itemView);
}
#Override
public int getItemViewType(int position) {
Message message = messageArrayList.get(position);
if (message.getUser().getId().equals(userId)) {
return SELF;
}
return position;
}
#Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {
Message message = messageArrayList.get(position);
((ViewHolder) holder).message.setText(message.getMessage());
String timestamp = getTimeStamp(message.getCreatedAt());
if (message.getUser().getName() != null)
timestamp = message.getUser().getName() + ", " + timestamp;
((ViewHolder) holder).timestamp.setText(timestamp);
}
#Override
public int getItemCount() {
return messageArrayList.size();
}
public static String getTimeStamp(String dateStr) {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String timestamp = "";
today = today.length() < 2 ? "0" + today : today;
try {
Date date = format.parse(dateStr);
SimpleDateFormat todayFormat = new SimpleDateFormat("dd");
String dateToday = todayFormat.format(date);
format = dateToday.equals(today) ? new SimpleDateFormat("hh:mm a") : new SimpleDateFormat("dd LLL, hh:mm a");
String date1 = format.format(date);
timestamp = date1.toString();
} catch (ParseException e) {
e.printStackTrace();
}
return timestamp;
}
}
Set setReverseLayout=true so that LayoutManager will layout items from end.
Something like this:
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.setReverseLayout(true);
recyclerView.setLayoutManager(layoutManager);
EDIT: This will reverse the data order but not scroll the RecyclerView to the last item. For keeping data order same and simply scrolling the RecyclerView to the last item set setStackFromEnd=true
Sample:
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.setStackFromEnd(true);
recyclerView.setLayoutManager(layoutManager);
Use RecyclerView LayoutManager to scroll item at position
recyclerView.getLayoutManager().scrollToPosition(messageList.size()-1);
And u are good to go
LinearLayoutManager manager = new LinearLayoutManager(ActivityMessage.this);
manager.setStackFromEnd(true);
manager.setReverseLayout(false);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(manager);
I'm trying to get all the user chats (created in my database) using an ArrayList and Recyclerview.Adapter but only first item from my ArrayList is being shown on my emulator screen.
Here's the corresponding code:
MainActivity:
package com.wipro.chat.activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;
import com.android.volley.NetworkResponse;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import com.wipro.chat.R;
import com.wipro.chat.adapter.ChatRoomsAdapter;
import com.wipro.chat.app.Config;
import com.wipro.chat.app.EndPoints;
import com.wipro.chat.app.MyApplication;
import com.wipro.chat.gcm.GcmIntentService;
import com.wipro.chat.gcm.NotificationUtils;
import com.wipro.chat.helper.SimpleDividerItemDecoration;
import com.wipro.chat.model.ChatRoom;
import com.wipro.chat.model.Message;
public class MainActivity extends AppCompatActivity {
private String TAG = MainActivity.class.getSimpleName();
private static final int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;
private BroadcastReceiver mRegistrationBroadcastReceiver;
private ArrayList<ChatRoom> chatRoomArrayList;
private ChatRoomsAdapter mAdapter;
private RecyclerView recyclerView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/**
* Check for login session. If not logged in launch
* login activity
* */
if (MyApplication.getInstance().getPrefManager().getUser() == null) {
launchLoginActivity();
}
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
/**
* Broadcast receiver calls in two scenarios
* 1. gcm registration is completed
* 2. when new push notification is received
* */
mRegistrationBroadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// checking for type intent filter
if (intent.getAction().equals(Config.REGISTRATION_COMPLETE)) {
// gcm successfully registered
// now subscribe to `global` topic to receive app wide notifications
subscribeToGlobalTopic();
} else if (intent.getAction().equals(Config.SENT_TOKEN_TO_SERVER)) {
// gcm registration id is stored in our server's MySQL
Log.e(TAG, "GCM registration id is sent to our server");
} else if (intent.getAction().equals(Config.PUSH_NOTIFICATION)) {
// new push notification is received
handlePushNotification(intent);
}
}
};
chatRoomArrayList = new ArrayList<>();
mAdapter = new ChatRoomsAdapter(this, chatRoomArrayList);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
recyclerView.addItemDecoration(new SimpleDividerItemDecoration(
getApplicationContext()
));
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(mAdapter);
recyclerView.addOnItemTouchListener(new ChatRoomsAdapter.RecyclerTouchListener(getApplicationContext(), recyclerView, new ChatRoomsAdapter.ClickListener() {
#Override
public void onClick(View view, int position) {
// when chat is clicked, launch full chat thread activity
ChatRoom userChatRoom = chatRoomArrayList.get(position);
Intent intent = new Intent(MainActivity.this, ChatRoomActivity.class);
intent.putExtra("user_id", userChatRoom.getId());
intent.putExtra("name", userChatRoom.getName());
startActivity(intent);
}
#Override
public void onLongClick(View view, int position) {
}
}));
/**
* Always check for google play services availability before
* proceeding further with GCM
* */
if (checkPlayServices()) {
registerGCM();
fetchChatRooms();
}
}
/**
* Handles new push notification
*/
private void handlePushNotification(Intent intent) {
/*int type = intent.getIntExtra("type", -1);
// if the push is of chat room message
// simply update the UI unread messages count
if (type == Config.PUSH_TYPE_CHATROOM) {
Message message = (Message) intent.getSerializableExtra("message");
String chatRoomId = intent.getStringExtra("chat_room_id");
if (message != null && chatRoomId != null) {
updateRow(chatRoomId, message);
}
} else if (type == Config.PUSH_TYPE_USER) {
// push belongs to user alone
// just showing the message in a toast
Message message = (Message) intent.getSerializableExtra("message");
Toast.makeText(getApplicationContext(), "New push: " + message.getMessage(), Toast.LENGTH_LONG).show();
}*/
Message message = (Message) intent.getSerializableExtra("message");
String userChatRoomId = intent.getStringExtra("user_id");
if (message != null && userChatRoomId != null) {
updateRow(userChatRoomId, message);
}
}
/**
* Updates the chat list unread count and the last message
*/
private void updateRow(String chatRoomId, Message message) {
for (ChatRoom cr : chatRoomArrayList) {
if (cr.getId().equals(chatRoomId)) {
int index = chatRoomArrayList.indexOf(cr);
cr.setLastMessage(message.getMessage());
cr.setUnreadCount(cr.getUnreadCount() + 1);
chatRoomArrayList.remove(index);
chatRoomArrayList.add(index, cr);
break;
}
}
mAdapter.notifyDataSetChanged();
}
/**
* fetching the chat rooms by making http call
*/
private void fetchChatRooms() {
StringRequest strReq = new StringRequest(Request.Method.GET,
EndPoints.CHAT_ROOMS, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.e(TAG, "response: " + response);
try {
JSONObject obj = new JSONObject(response);
// check for error flag
if (obj.getBoolean("error") == false) {
JSONArray chatRoomsArray = obj.getJSONArray("chat_rooms");
for (int i = 0; i < chatRoomsArray.length(); i++) {
JSONObject chatRoomsObj = (JSONObject) chatRoomsArray.get(i);
ChatRoom cr = new ChatRoom();
cr.setId(chatRoomsObj.getString("user_id"));
cr.setName(chatRoomsObj.getString("name"));
cr.setLastMessage("");
cr.setUnreadCount(0);
cr.setTimestamp(chatRoomsObj.getString("created_at"));
chatRoomArrayList.add(cr);
}
} else {
// error in fetching chat rooms
Toast.makeText(getApplicationContext(), "" + obj.getJSONObject("error").getString("message"), Toast.LENGTH_LONG).show();
}
} catch (JSONException e) {
Log.e(TAG, "json parsing error: " + e.getMessage());
Toast.makeText(getApplicationContext(), "Json parse error: " + e.getMessage(), Toast.LENGTH_LONG).show();
}
mAdapter.notifyDataSetChanged();
// subscribing to all chat room topics
//subscribeToAllTopics();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
NetworkResponse networkResponse = error.networkResponse;
Log.e(TAG, "Volley error: " + error.getMessage() + ", code: " + networkResponse);
Toast.makeText(getApplicationContext(), "Volley error: " + error.getMessage(), Toast.LENGTH_SHORT).show();
}
});
//Adding request to request queue
MyApplication.getInstance().addToRequestQueue(strReq);
}
// subscribing to global topic
private void subscribeToGlobalTopic() {
Intent intent = new Intent(this, GcmIntentService.class);
intent.putExtra(GcmIntentService.KEY, GcmIntentService.SUBSCRIBE);
intent.putExtra(GcmIntentService.TOPIC, Config.TOPIC_GLOBAL);
startService(intent);
}
// Subscribing to all chat room topics
// each topic name starts with `topic_` followed by the ID of the chat room
// Ex: topic_1, topic_2
/*private void subscribeToAllTopics() {
for (ChatRoom cr : chatRoomArrayList) {
Intent intent = new Intent(this, GcmIntentService.class);
intent.putExtra(GcmIntentService.KEY, GcmIntentService.SUBSCRIBE);
intent.putExtra(GcmIntentService.TOPIC, "topic_" + cr.getId());
startService(intent);
}
}*/
private void launchLoginActivity() {
Intent intent = new Intent(MainActivity.this, LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
finish();
}
#Override
protected void onResume() {
super.onResume();
// register GCM registration complete receiver
LocalBroadcastManager.getInstance(this).registerReceiver(mRegistrationBroadcastReceiver,
new IntentFilter(Config.REGISTRATION_COMPLETE));
// register new push message receiver
// by doing this, the activity will be notified each time a new message arrives
LocalBroadcastManager.getInstance(this).registerReceiver(mRegistrationBroadcastReceiver,
new IntentFilter(Config.PUSH_NOTIFICATION));
// clearing the notification tray
NotificationUtils.clearNotifications();
}
#Override
protected void onPause() {
LocalBroadcastManager.getInstance(this).unregisterReceiver(mRegistrationBroadcastReceiver);
super.onPause();
}
// starting the service to register with GCM
private void registerGCM() {
Intent intent = new Intent(this, GcmIntentService.class);
intent.putExtra("key", "register");
startService(intent);
}
private boolean checkPlayServices() {
GoogleApiAvailability apiAvailability = GoogleApiAvailability.getInstance();
int resultCode = apiAvailability.isGooglePlayServicesAvailable(this);
if (resultCode != ConnectionResult.SUCCESS) {
if (apiAvailability.isUserResolvableError(resultCode)) {
apiAvailability.getErrorDialog(this, resultCode, PLAY_SERVICES_RESOLUTION_REQUEST)
.show();
} else {
Log.i(TAG, "This device is not supported. Google Play Services not installed!");
Toast.makeText(getApplicationContext(), "This device is not supported. Google Play Services not installed!", Toast.LENGTH_LONG).show();
finish();
}
return false;
}
return true;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_main, menu);
return true;
}
public boolean onOptionsItemSelected(MenuItem menuItem) {
switch (menuItem.getItemId()) {
case R.id.action_logout:
MyApplication.getInstance().logout();
break;
}
return super.onOptionsItemSelected(menuItem);
}
}
ChatRoomsAdapter:
package com.wipro.chat.adapter;
/**
* Created by COMP on 16-06-2016.
*/
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.GestureDetector;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import com.wipro.chat.R;
import com.wipro.chat.model.ChatRoom;
public class ChatRoomsAdapter extends RecyclerView.Adapter<ChatRoomsAdapter.ViewHolder> {
private Context mContext;
private ArrayList<ChatRoom> chatRoomArrayList;
private static String today;
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView name, message, timestamp, count;
public ViewHolder(View view) {
super(view);
name = (TextView) view.findViewById(R.id.name);
message = (TextView) view.findViewById(R.id.message);
timestamp = (TextView) view.findViewById(R.id.timestamp);
count = (TextView) view.findViewById(R.id.count);
}
}
public ChatRoomsAdapter(Context mContext, ArrayList<ChatRoom> chatRoomArrayList) {
this.mContext = mContext;
this.chatRoomArrayList = chatRoomArrayList;
Calendar calendar = Calendar.getInstance();
today = String.valueOf(calendar.get(Calendar.DAY_OF_MONTH));
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.chat_rooms_list_row, parent, false);
return new ViewHolder(itemView);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
ChatRoom chatRoom = chatRoomArrayList.get(position);
holder.name.setText(chatRoom.getName());
holder.message.setText(chatRoom.getLastMessage());
if (chatRoom.getUnreadCount() > 0) {
holder.count.setText(String.valueOf(chatRoom.getUnreadCount()));
holder.count.setVisibility(View.VISIBLE);
} else {
holder.count.setVisibility(View.GONE);
}
holder.timestamp.setText(getTimeStamp(chatRoom.getTimestamp()));
}
#Override
public int getItemCount() {
return chatRoomArrayList.size();
}
public static String getTimeStamp(String dateStr) {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String timestamp = "";
today = today.length() < 2 ? "0" + today : today;
try {
Date date = format.parse(dateStr);
SimpleDateFormat todayFormat = new SimpleDateFormat("dd");
String dateToday = todayFormat.format(date);
format = dateToday.equals(today) ? new SimpleDateFormat("hh:mm a") : new SimpleDateFormat("dd LLL, hh:mm a");
String date1 = format.format(date);
timestamp = date1.toString();
} catch (ParseException e) {
e.printStackTrace();
}
return timestamp;
}
public interface ClickListener {
void onClick(View view, int position);
void onLongClick(View view, int position);
}
public static class RecyclerTouchListener implements RecyclerView.OnItemTouchListener {
private GestureDetector gestureDetector;
private ChatRoomsAdapter.ClickListener clickListener;
public RecyclerTouchListener(Context context, final RecyclerView recyclerView, final ChatRoomsAdapter.ClickListener clickListener) {
this.clickListener = clickListener;
gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
#Override
public boolean onSingleTapUp(MotionEvent e) {
return true;
}
#Override
public void onLongPress(MotionEvent e) {
View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
if (child != null && clickListener != null) {
clickListener.onLongClick(child, recyclerView.getChildLayoutPosition(child));
}
}
});
}
#Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
View child = rv.findChildViewUnder(e.getX(), e.getY());
if (child != null && clickListener != null && gestureDetector.onTouchEvent(e)) {
clickListener.onClick(child, rv.getChildLayoutPosition(child));
}
return false;
}
#Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) {
}
#Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
}
}
PHP code which is retrieving the chatroom is like:
/* * *
* fetching all chat rooms
*/
$app->get('/chat_rooms', function() {
$response = array();
$db = new DbHandler();
// fetching all user tasks
$result = $db->getAllChats();
$response["error"] = false;
$response["chat_rooms"] = array();
// pushing single chat room into array
while ($chat_room = $result->fetch_assoc()) {
$tmp = array();
$tmp["user_id"] = $chat_room["user_id"];
$tmp["name"] = $chat_room["name"];
$tmp["created_at"] = $chat_room["created_at"];
array_push($response["chat_rooms"], $tmp);
}
echoRespnse(200, $response);
});
public function getAllChats() {
$stmt = $this->conn->prepare("SELECT user_id, name, created_at FROM users");
$stmt->execute();
$tasks = $stmt->get_result();
$stmt->close();
return $tasks;
}
There are two user chats in my database, namely Messaging, Chat and I'm getting the both from database into ArrayList but it is only showing Messaging.
Adapter display:
Response from database:
Check recycler_view in your main layout. The height should be set to "wrap_content".
My sinch client sends duplicate messages to my parse database in an incremental way. That is for the first message it posts once in the database. Twice for the second message. Thrice for the third in that order.
This is my ChatActivity
package com.app.knowtes;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;
import com.parse.FindCallback;
import com.parse.ParseObject;
import com.parse.ParseQuery;
import com.parse.ParseUser;
import com.sinch.android.rtc.PushPair;
import com.sinch.android.rtc.messaging.Message;
import com.sinch.android.rtc.messaging.MessageClient;
import com.sinch.android.rtc.messaging.MessageClientListener;
import com.sinch.android.rtc.messaging.MessageDeliveryInfo;
import com.sinch.android.rtc.messaging.MessageFailureInfo;
import com.sinch.android.rtc.messaging.WritableMessage;
import java.util.Arrays;
import java.util.List;
/**
* Created by RR on 12/6/2015.
*/
public class ChatActivity extends ActionBarActivity {
private String recipientId;
private EditText messageBodyField;
private String messageBody;
private MessageService.MessageServiceInterface messageService;
private String currentUserId;
private ServiceConnection serviceConnection = new MyServiceConnection();
ListView messagesList;
MessageAdapter messageAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.chatactivity);
bindService(new Intent(this, MessageService.class), serviceConnection, BIND_AUTO_CREATE);
//get recipientId from the intent
Intent intent = getIntent();
recipientId = intent.getStringExtra("RECIPIENT_ID");
currentUserId = ParseUser.getCurrentUser().getObjectId();
messageBodyField = (EditText) findViewById(R.id.messageBodyField);
messagesList = (ListView) findViewById(R.id.listMessages);
messageAdapter = new MessageAdapter(this);
messagesList.setAdapter(messageAdapter);
String[] cuserIds = {currentUserId, recipientId};
String[] ruserIds = {recipientId,currentUserId};
ParseQuery<ParseObject> query = ParseQuery.getQuery("ParseMessage");
query.whereContainedIn("senderId", Arrays.asList(cuserIds));
query.whereContainedIn("recipientId", Arrays.asList(ruserIds));
query.orderByAscending("createdAt");
query.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> messageList, com.parse.ParseException e) {
if (e == null) {
for (int i = 0; i < messageList.size(); i++) {
WritableMessage message = new WritableMessage(messageList.get(i).get("recipientId").toString(), messageList.get(i).get("messageText").toString());
if (messageList.get(i).get("senderId").toString().equals(currentUserId)) {
messageAdapter.addMessage(message, MessageAdapter.DIRECTION_OUTGOING);
} else {
messageAdapter.addMessage(message, MessageAdapter.DIRECTION_INCOMING);
}
}
}
}
});
//listen for a click on the send button
findViewById(R.id.sendButton).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//send the message!
messageBody = messageBodyField.getText().toString();
if (messageBody.equals("")) {
Toast.makeText(getApplicationContext(), "Please enter a message", Toast.LENGTH_SHORT).show();
return;
}else {
messageService.sendMessage(recipientId, messageBody);
messageBodyField.setText("");
}
}
});
}
//unbind the service when the activity is destroyed
#Override
public void onDestroy() {
unbindService(serviceConnection);
messageService.removeMessageClientListener(new MyMessageClientListener());
super.onDestroy();
}
private class MyServiceConnection implements ServiceConnection {
#Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
messageService = (MessageService.MessageServiceInterface) iBinder;
messageService.addMessageClientListener(new MyMessageClientListener());
}
#Override
public void onServiceDisconnected(ComponentName componentName) {
messageService = null;
}
}
private class MyMessageClientListener implements MessageClientListener {
//Notify the user if their message failed to send
#Override
public void onMessageFailed(MessageClient client, Message message,
MessageFailureInfo failureInfo) {
Toast.makeText(getApplicationContext(), "Message failed to send." + failureInfo.getSinchError().getMessage(), Toast.LENGTH_SHORT).show();
}
#Override
public void onIncomingMessage(MessageClient client, Message message) {
//Display an incoming message
if (message.getSenderId().equals(recipientId)) {
WritableMessage writableMessage = new WritableMessage(message.getRecipientIds().get(0), message.getTextBody());
messageAdapter.addMessage(writableMessage, MessageAdapter.DIRECTION_INCOMING);
}
}
#Override
public void onMessageSent(MessageClient client, Message message, final String recipientId) {
//Display the message that was just sent
//Later, I'll show you how to store the
//message in Parse, so you can retrieve and
//display them every time the conversation is opened
//WritableMessage writableMessage = new WritableMessage(message.getRecipientIds().get(0), message.getTextBody());
//messageAdapter.addMessage(writableMessage, MessageAdapter.DIRECTION_OUTGOING);
Toast.makeText(getApplicationContext(), "Message successfully senT.", Toast.LENGTH_SHORT).show();
final WritableMessage writableMessage = new WritableMessage(message.getRecipientIds().get(0), message.getTextBody());
messageAdapter.addMessage(writableMessage, MessageAdapter.DIRECTION_OUTGOING);
//only add message to parse database if it doesn't already exist there
ParseQuery<ParseObject> query = ParseQuery.getQuery("ParseMessage");
query.whereEqualTo("sinchId", message.getMessageId());
query.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> messageList, com.parse.ParseException e) {
if (e == null) {
if (messageList.size() == 0) {
ParseObject parseMessage = new ParseObject("ParseMessage");
parseMessage.put("senderId", currentUserId);
parseMessage.put("recipientId", recipientId);
parseMessage.put("messageText", writableMessage.getTextBody());
parseMessage.put("sinchId", writableMessage.getMessageId());
parseMessage.saveInBackground();
messageAdapter.addMessage(writableMessage, MessageAdapter.DIRECTION_OUTGOING);
}
}
}
});
}
//Do you want to notify your user when the message is delivered?
#Override
public void onMessageDelivered(MessageClient client, MessageDeliveryInfo deliveryInfo) {}
//Don't worry about this right now
#Override
public void onShouldSendPushData(MessageClient client, Message message, List<PushPair> pushPairs) {}
}
}
And this is my MessageService.java
package com.app.knowtes;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.support.v4.content.LocalBroadcastManager;
import com.parse.ParseUser;
import com.sinch.android.rtc.ClientRegistration;
import com.sinch.android.rtc.Sinch;
import com.sinch.android.rtc.SinchClient;
import com.sinch.android.rtc.SinchClientListener;
import com.sinch.android.rtc.SinchError;
import com.sinch.android.rtc.messaging.MessageClient;
import com.sinch.android.rtc.messaging.MessageClientListener;
import com.sinch.android.rtc.messaging.WritableMessage;
/**
* Created by RR on 12/4/2015.
*/
public class MessageService extends Service implements SinchClientListener {
private static final String APP_KEY = "XXXXXXXXXXXXXXXXXXX";
private static final String APP_SECRET = "XXXXXXXXXXXXXXXX";
private static final String ENVIRONMENT = "sandbox.sinch.com";
private final MessageServiceInterface serviceInterface = new MessageServiceInterface();
private SinchClient sinchClient = null;
private MessageClient messageClient = null;
private String currentUserId;
private Intent broadcastIntent = new Intent("com.app.knowtes.ChatListActivity");
private LocalBroadcastManager broadcaster;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
//get the current user id from Parse
currentUserId = ParseUser.getCurrentUser().getObjectId();
if (currentUserId != null && !isSinchClientStarted()) {
startSinchClient(currentUserId);
}
broadcaster = LocalBroadcastManager.getInstance(this);
return super.onStartCommand(intent, flags, startId);
}
public void startSinchClient(String username) {
sinchClient = Sinch.getSinchClientBuilder()
.context(this)
.userId(username)
.applicationKey(APP_KEY)
.applicationSecret(APP_SECRET)
.environmentHost(ENVIRONMENT)
.build();
//this client listener requires that you define
//a few methods below
sinchClient.addSinchClientListener(this);
//messaging is "turned-on", but calling is not
sinchClient.setSupportMessaging(true);
sinchClient.setSupportActiveConnectionInBackground(true);
sinchClient.checkManifest();
sinchClient.start();
}
private boolean isSinchClientStarted() {
return sinchClient != null && sinchClient.isStarted();
}
//The next 5 methods are for the sinch client listener
#Override
public void onClientFailed(SinchClient client, SinchError error) {
sinchClient = null;
broadcastIntent.putExtra("success", false);
broadcaster.sendBroadcast(broadcastIntent);
}
#Override
public void onClientStarted(SinchClient client) {
client.startListeningOnActiveConnection();
messageClient = client.getMessageClient();
broadcastIntent.putExtra("success", true);
broadcaster.sendBroadcast(broadcastIntent);
}
#Override
public void onClientStopped(SinchClient client) {
sinchClient = null;
}
#Override
public void onRegistrationCredentialsRequired(SinchClient client, ClientRegistration clientRegistration) {}
#Override
public void onLogMessage(int level, String area, String message) {}
#Override
public IBinder onBind(Intent intent) {
return serviceInterface;
}
public void sendMessage(String recipientUserId, String textBody) {
if (messageClient != null) {
WritableMessage message = new WritableMessage(recipientUserId, textBody);
messageClient.send(message);
}
}
public void addMessageClientListener(MessageClientListener listener) {
if (messageClient != null) {
messageClient.addMessageClientListener(listener);
}
}
public void removeMessageClientListener(MessageClientListener listener) {
if (messageClient != null) {
messageClient.removeMessageClientListener(listener);
}
}
#Override
public void onDestroy() {
sinchClient.stopListeningOnActiveConnection();
//sinchClient.stop();
sinchClient.terminate();
}
//public interface for ListUsersActivity & MessagingActivity
public class MessageServiceInterface extends Binder {
public void sendMessage(String recipientUserId, String textBody) {
MessageService.this.sendMessage(recipientUserId, textBody);
}
public void addMessageClientListener(MessageClientListener listener) {
MessageService.this.addMessageClientListener(listener);
}
public void removeMessageClientListener(MessageClientListener listener) {
MessageService.this.removeMessageClientListener(listener);
}
public boolean isSinchClientStarted() {
return MessageService.this.isSinchClientStarted();
}
public void terminateSinchClient(){
}
}
}
enter code here
When you log out, our servers dont know that the messages have been delivered to that device. We keep messages for delivery for 30 days. AS a developer you will experience this more since you are wiping the install when you deploy.
If you just kill the app and launch it again you will see that its not delivered again.
There is a couple of ways of avoiding this,
1. Dont log out
2. If you want logout functionality, dont toast as old messages arrive look at time stamp.
or keep track of messages id in your own database