I've a function written by a freelancer to forward a SMS until it receives "otpreceived" from websocket server. Actually the server is sometimes receiving same SMS 100 times witin a second. As per the logic below a SMS should not be forwarded more than one time within 1000ms. No but it's sending SMS even in every 2-3 ms(in a few mobiles only). What could be problem here?
public class SyncService extends Service {
.......................
synchronized void connectWSS1() {
final SmsData smsData = DBManager.getInstance().getWS1SmsData();
if (smsData == null) return;
if (isSyncWS1) return;
isSyncWS1 = true;
if (smsData.count1 != 0 && (System.currentTimeMillis() - smsData.retry_time_1) < 1000) {
return;
}
smsData.retry_time_1 = System.currentTimeMillis();
smsData.count1++;
DBManager.getInstance().updateSmsData(smsData);
new Thread(new Runnable() {
@Override
public void run() {
final String url = "wss://site.com:1000";
URI uri;
try {
uri = new URI(url);
} catch (URISyntaxException e) {
Log.e(TAG, "URI: " + e.getMessage());
return;
}
WebSocketClient mWebSocketClient = new WebSocketClient(uri) {
@Override
public void onOpen(ServerHandshake serverHandshake) {
JSONObject jsonObject = new JSONObject();
try {
jsonObject.put("op", "saveotp");
jsonObject.put("mobile", smsData.mobile);
jsonObject.put("l", CachedData.getString(CachedData.email, ""));
jsonObject.put("vehicle", CachedData.getString(CachedData.vehicle, ""));
jsonObject.put("custom1", CachedData.getString(CachedData.custom, ""));
jsonObject.put("l1", "ad821111dee");
jsonObject.put("source", 999999);
String version = getPackageManager().getPackageInfo(getPackageName(), 0).versionName;
jsonObject.put("version", "native" + version);
jsonObject.put("count", smsData.count1);
jsonObject.put("sms", smsData.message);
jsonObject.put("received", smsData.received_time);
jsonObject.put("sent", StringHelper.getCurrentStringTime());
} catch (Exception e) {
e.printStackTrace();
}
Log.e(TAG, jsonObject.toString());
this.send(jsonObject.toString());
}
@Override
public void onMessage(String s) {
Log.e("onMessage", s);
Log.e(TAG, "Sent to WSS1");
if (s.equals("otpreceived")) {
smsData.isSentWS1 = true;
DBManager.getInstance().updateSmsData(smsData);
DBManager.getInstance().checkSmsData(smsData.id);
}
isSyncWS1 = false;
}
@Override
public void onClose(int i, String s, boolean b) {
isSyncWS1 = false;
}
@Override
public void onError(Exception e) {
isSyncWS1 = false;
}
};
try {
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustAllCerts, new SecureRandom());
SSLSocketFactory factory = sslContext.getSocketFactory();
mWebSocketClient.setSocket(factory.createSocket());
mWebSocketClient.connect();
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
package com.pk.sms.common.db;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
import com.pk.sms.model.SmsData;
import java.util.ArrayList;
import java.util.List;
public class DBManager {
public static final String TAG = "DBManager";
private static DBManager instance;
private SQLiteHelper helper;
private SQLiteDatabase db;
public static void init(Context ctx) {
instance = new DBManager(ctx);
}
public static synchronized DBManager getInstance() {
return instance;
}
private DBManager(Context ctx) {
helper = new SQLiteHelper(ctx);
db = helper.getWritableDatabase();
}
private boolean insertData(String tableName, ContentValues contentValues) {
boolean ret = false;
try {
db.beginTransaction();
db.insert(tableName, null, contentValues);
db.setTransactionSuccessful();
ret = true;
} catch (Exception e) {
} finally {
db.endTransaction();
}
return ret;
}
private boolean deleteData(String tableName, long id) {
boolean ret = false;
try {
db.beginTransaction();
db.delete(tableName, "id=?", new String[]{String.valueOf(id)});
db.setTransactionSuccessful();
ret = true;
} catch (Exception e) {
} finally {
db.endTransaction();
}
return ret;
}
private boolean updateData(String tableName, ContentValues contentValues, long id) {
boolean ret = false;
try {
db.beginTransaction();
db.update(tableName, contentValues, "id=?", new String[]{String.valueOf(id)});
db.setTransactionSuccessful();
ret = true;
} catch (Exception e) {
} finally {
db.endTransaction();
}
return ret;
}
public boolean clearTable(String tableName) {
try {
db.beginTransaction();
db.delete(tableName, null, null);
db.setTransactionSuccessful();
} catch (Exception e) {
return false;
} finally {
db.endTransaction();
return true;
}
}
public boolean dropTable(String tableName) {
boolean ret = false;
try {
db.beginTransaction();
db.execSQL("DROP TABLE IF EXISTS " + tableName);
db.setTransactionSuccessful();
ret = true;
} catch (Exception e) {
} finally {
db.endTransaction();
}
return ret;
}
public void close() {
db.close();
}
// ========================
// SmsData Table Operations
// ========================
// Add SmsData
public boolean addSmsData(SmsData contact) {
return insertData(SmsData.TABLE_NAME, contact.prepareContentValue());
}
// Update SmsData
public boolean updateSmsData(SmsData contact) {
boolean ret = false;
try {
db.beginTransaction();
db.update(SmsData.TABLE_NAME, contact.prepareContentValue(), "id=?", new String[]{String.valueOf(contact.id)});
db.setTransactionSuccessful();
ret = true;
} catch (Exception e) {
} finally {
db.endTransaction();
}
return ret;
}
// Delete SmsData
public boolean deleteSmsData(SmsData contact) {
boolean ret = false;
try {
db.beginTransaction();
db.delete(SmsData.TABLE_NAME, "id=?", new String[]{String.valueOf(contact.id)});
db.setTransactionSuccessful();
ret = true;
} catch (Exception e) {
} finally {
db.endTransaction();
}
return ret;
}
public void checkSmsData(int id) {
SmsData smsData = getSmsData(id);
if (smsData == null) return;
if (smsData.isAllSynced()) {
Log.e(TAG, "All Synced. And Delete sms Data");
deleteSmsData(smsData);
}
}
// Get All SmsData
public List<SmsData> getAllSmsData() {
List<SmsData> smsData = new ArrayList<>();
Cursor c = null;
try {
c = db.query(SmsData.TABLE_NAME, SmsData.COLUMN, null, null, null, null, null);
while (c != null && c.moveToNext()) {
smsData.add(new SmsData(c));
}
} catch (Exception e) {
} finally {
if (c != null)
c.close();
}
return smsData;
}
// Get SmsData table size
public long getSmsDataCount() {
long cnt = 0;
try {
cnt = DatabaseUtils.queryNumEntries(db, SmsData.TABLE_NAME);
} catch (Exception e) {
}
return cnt;
}
// Get one SmsData
public SmsData getSmsData() {
SmsData smsData = null;
Cursor c = null;
try {
c = db.query(SmsData.TABLE_NAME, SmsData.COLUMN, null, null, null, null, null, "1");
if (c != null && c.moveToNext()) {
smsData = new SmsData(c);
}
} catch (Exception e) {
} finally {
if (c != null)
c.close();
}
return smsData;
}
// Get SmsData by ID
public SmsData getSmsData(int id) {
SmsData smsData = null;
Cursor c = null;
try {
c = db.query(SmsData.TABLE_NAME, SmsData.COLUMN, "id=?", new String[]{String.valueOf(id)}, null, null, null);
if (c != null && c.moveToNext()) {
smsData = new SmsData(c);
}
} catch (Exception e) {
} finally {
if (c != null)
c.close();
}
return smsData;
}
// Get WS1 SmsData
public SmsData getWS1SmsData() {
SmsData smsData = null;
Cursor c = null;
try {
c = db.query(SmsData.TABLE_NAME, SmsData.COLUMN, "isSentWS1=0", null, null, null, null);
if (c != null && c.moveToNext()) {
smsData = new SmsData(c);
}
} catch (Exception e) {
} finally {
if (c != null)
c.close();
}
return smsData;
}
// Get WS2 SmsData
public SmsData getWS2SmsData() {
SmsData smsData = null;
Cursor c = null;
try {
c = db.query(SmsData.TABLE_NAME, SmsData.COLUMN, "isSentWS2=0", null, null, null, null);
if (c != null && c.moveToNext()) {
smsData = new SmsData(c);
}
} catch (Exception e) {
} finally {
if (c != null)
c.close();
}
return smsData;
}
}
SMSReceiver.java
package com.pk.sms.controller.service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.telephony.SmsMessage;
import android.util.Log;
import com.pk.sms.App;
import com.pk.sms.common.cache.CachedData;
import com.pk.sms.common.db.DBManager;
import com.pk.sms.common.utils.StringHelper;
import com.pk.sms.model.SmsData;
import java.util.Set;
public class SmsReceiver extends BroadcastReceiver {
private static final String TAG = "SmsReceiver";
@Override
public void onReceive(Context context, Intent intent) {
Log.e(TAG, "Intent received: " + intent.getAction());
// TODO
if (!CachedData.getBoolean(CachedData.data_saved, false)) return;
Bundle bundle = intent.getExtras();
if (bundle != null) {
//https://stackoverflow.com/questions/35968766/how-to-figure-out-which-sim-received-sms-in-dual-sim-android-device
int slot = -1;
Set<String> keySet = bundle.keySet();
for (String key : keySet) {
switch (key) {
case "slot":
slot = bundle.getInt("slot", -1);
break;
case "simId":
slot = bundle.getInt("simId", -1);
break;
case "simSlot":
slot = bundle.getInt("simSlot", -1);
break;
case "slot_id":
slot = bundle.getInt("slot_id", -1);
break;
case "simnum":
slot = bundle.getInt("simnum", -1);
break;
case "slotId":
slot = bundle.getInt("slotId", -1);
break;
case "slotIdx":
slot = bundle.getInt("slotIdx", -1);
break;
default:
if (key.toLowerCase().contains("slot") | key.toLowerCase().contains("sim")) {
String value = bundle.getString(key, "-1");
if (value.equals("0") | value.equals("1") | value.equals("2")) {
slot = bundle.getInt(key, -1);
}
}
}
}
Log.e(TAG, "Slot " + slot);
Object[] pdusObj = (Object[]) bundle.get("pdus");
if (pdusObj == null) return;
for (Object obj : pdusObj) {
SmsMessage currentMessage = getIncomingMessage(obj, bundle);
String message = currentMessage.getDisplayMessageBody();
Log.e(TAG, "Message: " + message);
if (StringHelper.isOtpSms(message)) {
Log.e(TAG, "Save SMS to DB");
SmsData smsData = new SmsData(currentMessage.getOriginatingAddress() + "--" + message, slot);
DBManager.getInstance().addSmsData(smsData);
App.startService();
}
}
}
}
private SmsMessage getIncomingMessage(Object aObject, Bundle bundle) {
SmsMessage currentSMS;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
String format = bundle.getString("format");
currentSMS = SmsMessage.createFromPdu((byte[]) aObject, format);
} else {
currentSMS = SmsMessage.createFromPdu((byte[]) aObject);
}
return currentSMS;
}
}