Browse Source
Merge pull request #96 from vernu/improve-call-reliability
Merge pull request #96 from vernu/improve-call-reliability
Improve received sms and status tracking reliability using work managerpull/98/head
committed by
GitHub
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 248 additions and 58 deletions
-
6android/app/build.gradle
-
8android/app/src/main/AndroidManifest.xml
-
20android/app/src/main/java/com/vernu/sms/SMSGatewayApplication.java
-
33android/app/src/main/java/com/vernu/sms/receivers/SMSBroadcastReceiver.java
-
26android/app/src/main/java/com/vernu/sms/receivers/SMSStatusReceiver.java
-
106android/app/src/main/java/com/vernu/sms/workers/SMSReceivedWorker.java
-
105android/app/src/main/java/com/vernu/sms/workers/SMSStatusUpdateWorker.java
@ -0,0 +1,20 @@ |
|||
package com.vernu.sms; |
|||
|
|||
import android.app.Application; |
|||
|
|||
import androidx.work.Configuration; |
|||
import androidx.work.WorkManager; |
|||
|
|||
public class SMSGatewayApplication extends Application implements Configuration.Provider { |
|||
@Override |
|||
public void onCreate() { |
|||
super.onCreate(); |
|||
} |
|||
|
|||
@Override |
|||
public Configuration getWorkManagerConfiguration() { |
|||
return new Configuration.Builder() |
|||
.setMinimumLoggingLevel(android.util.Log.INFO) |
|||
.build(); |
|||
} |
|||
} |
|||
@ -0,0 +1,106 @@ |
|||
package com.vernu.sms.workers; |
|||
|
|||
import android.content.Context; |
|||
import android.util.Log; |
|||
|
|||
import androidx.annotation.NonNull; |
|||
import androidx.work.Data; |
|||
import androidx.work.Worker; |
|||
import androidx.work.WorkerParameters; |
|||
import androidx.work.BackoffPolicy; |
|||
import androidx.work.Constraints; |
|||
import androidx.work.NetworkType; |
|||
import androidx.work.OneTimeWorkRequest; |
|||
import androidx.work.WorkManager; |
|||
|
|||
import com.google.gson.Gson; |
|||
import com.vernu.sms.ApiManager; |
|||
import com.vernu.sms.dtos.SMSDTO; |
|||
import com.vernu.sms.dtos.SMSForwardResponseDTO; |
|||
|
|||
import java.io.IOException; |
|||
import java.util.concurrent.TimeUnit; |
|||
|
|||
import retrofit2.Call; |
|||
import retrofit2.Response; |
|||
|
|||
public class SMSReceivedWorker extends Worker { |
|||
private static final String TAG = "SMSReceivedWorker"; |
|||
private static final int MAX_RETRIES = 5; |
|||
|
|||
public static final String KEY_DEVICE_ID = "device_id"; |
|||
public static final String KEY_API_KEY = "api_key"; |
|||
public static final String KEY_SMS_DTO = "sms_dto"; |
|||
public static final String KEY_RETRY_COUNT = "retry_count"; |
|||
|
|||
public SMSReceivedWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) { |
|||
super(context, workerParams); |
|||
} |
|||
|
|||
@NonNull |
|||
@Override |
|||
public Result doWork() { |
|||
String deviceId = getInputData().getString(KEY_DEVICE_ID); |
|||
String apiKey = getInputData().getString(KEY_API_KEY); |
|||
String smsDtoJson = getInputData().getString(KEY_SMS_DTO); |
|||
int retryCount = getInputData().getInt(KEY_RETRY_COUNT, 0); |
|||
|
|||
if (deviceId == null || apiKey == null || smsDtoJson == null) { |
|||
Log.e(TAG, "Missing required parameters"); |
|||
return Result.failure(); |
|||
} |
|||
|
|||
// Check if we've exceeded the maximum retry count |
|||
if (retryCount >= MAX_RETRIES) { |
|||
Log.e(TAG, "Maximum retry count reached for received SMS"); |
|||
return Result.failure(); |
|||
} |
|||
|
|||
SMSDTO smsDTO = new Gson().fromJson(smsDtoJson, SMSDTO.class); |
|||
|
|||
try { |
|||
Call<SMSForwardResponseDTO> call = ApiManager.getApiService().sendReceivedSMS(deviceId, apiKey, smsDTO); |
|||
Response<SMSForwardResponseDTO> response = call.execute(); |
|||
|
|||
if (response.isSuccessful()) { |
|||
Log.d(TAG, "Received SMS sent to server successfully"); |
|||
return Result.success(); |
|||
} else { |
|||
Log.e(TAG, "Failed to send received SMS to server. Response code: " + response.code()); |
|||
return Result.retry(); |
|||
} |
|||
} catch (IOException e) { |
|||
Log.e(TAG, "API call failed: " + e.getMessage()); |
|||
return Result.retry(); |
|||
} |
|||
} |
|||
|
|||
public static void enqueueWork(Context context, String deviceId, String apiKey, SMSDTO smsDTO) { |
|||
Data inputData = new Data.Builder() |
|||
.putString(KEY_DEVICE_ID, deviceId) |
|||
.putString(KEY_API_KEY, apiKey) |
|||
.putString(KEY_SMS_DTO, new Gson().toJson(smsDTO)) |
|||
.putInt(KEY_RETRY_COUNT, 0) |
|||
.build(); |
|||
|
|||
Constraints constraints = new Constraints.Builder() |
|||
.setRequiredNetworkType(NetworkType.CONNECTED) |
|||
.build(); |
|||
|
|||
OneTimeWorkRequest workRequest = new OneTimeWorkRequest.Builder(SMSReceivedWorker.class) |
|||
.setConstraints(constraints) |
|||
.setBackoffCriteria(BackoffPolicy.EXPONENTIAL, 10, TimeUnit.SECONDS) |
|||
.setInputData(inputData) |
|||
.addTag("sms_received") |
|||
.build(); |
|||
|
|||
String uniqueWorkName = "sms_received_" + System.currentTimeMillis(); |
|||
WorkManager.getInstance(context) |
|||
.beginUniqueWork(uniqueWorkName, |
|||
androidx.work.ExistingWorkPolicy.APPEND_OR_REPLACE, |
|||
workRequest) |
|||
.enqueue(); |
|||
|
|||
Log.d(TAG, "Work enqueued for received SMS from: " + smsDTO.getSender()); |
|||
} |
|||
} |
|||
@ -0,0 +1,105 @@ |
|||
package com.vernu.sms.workers; |
|||
|
|||
import android.content.Context; |
|||
import android.util.Log; |
|||
|
|||
import androidx.annotation.NonNull; |
|||
import androidx.work.Data; |
|||
import androidx.work.Worker; |
|||
import androidx.work.WorkerParameters; |
|||
import androidx.work.BackoffPolicy; |
|||
import androidx.work.Constraints; |
|||
import androidx.work.NetworkType; |
|||
import androidx.work.OneTimeWorkRequest; |
|||
import androidx.work.WorkManager; |
|||
|
|||
import com.google.gson.Gson; |
|||
import com.vernu.sms.ApiManager; |
|||
import com.vernu.sms.dtos.SMSDTO; |
|||
import com.vernu.sms.dtos.SMSForwardResponseDTO; |
|||
|
|||
import java.io.IOException; |
|||
import java.util.concurrent.TimeUnit; |
|||
|
|||
import retrofit2.Call; |
|||
import retrofit2.Response; |
|||
|
|||
public class SMSStatusUpdateWorker extends Worker { |
|||
private static final String TAG = "SMSStatusUpdateWorker"; |
|||
private static final int MAX_RETRIES = 5; |
|||
|
|||
public static final String KEY_DEVICE_ID = "device_id"; |
|||
public static final String KEY_API_KEY = "api_key"; |
|||
public static final String KEY_SMS_DTO = "sms_dto"; |
|||
public static final String KEY_RETRY_COUNT = "retry_count"; |
|||
|
|||
public SMSStatusUpdateWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) { |
|||
super(context, workerParams); |
|||
} |
|||
|
|||
@NonNull |
|||
@Override |
|||
public Result doWork() { |
|||
String deviceId = getInputData().getString(KEY_DEVICE_ID); |
|||
String apiKey = getInputData().getString(KEY_API_KEY); |
|||
String smsDtoJson = getInputData().getString(KEY_SMS_DTO); |
|||
int retryCount = getInputData().getInt(KEY_RETRY_COUNT, 0); |
|||
|
|||
if (deviceId == null || apiKey == null || smsDtoJson == null) { |
|||
Log.e(TAG, "Missing required parameters"); |
|||
return Result.failure(); |
|||
} |
|||
|
|||
// Check if we've exceeded the maximum retry count |
|||
if (retryCount >= MAX_RETRIES) { |
|||
Log.e(TAG, "Maximum retry count reached for SMS status update"); |
|||
return Result.failure(); |
|||
} |
|||
|
|||
SMSDTO smsDTO = new Gson().fromJson(smsDtoJson, SMSDTO.class); |
|||
|
|||
try { |
|||
Call<SMSForwardResponseDTO> call = ApiManager.getApiService().updateSMSStatus(deviceId, apiKey, smsDTO); |
|||
Response<SMSForwardResponseDTO> response = call.execute(); |
|||
|
|||
if (response.isSuccessful()) { |
|||
Log.d(TAG, "SMS status updated successfully - ID: " + smsDTO.getSmsId() + ", Status: " + smsDTO.getStatus()); |
|||
return Result.success(); |
|||
} else { |
|||
Log.e(TAG, "Failed to update SMS status. Response code: " + response.code()); |
|||
return Result.retry(); |
|||
} |
|||
} catch (IOException e) { |
|||
Log.e(TAG, "API call failed: " + e.getMessage()); |
|||
return Result.retry(); |
|||
} |
|||
} |
|||
|
|||
public static void enqueueWork(Context context, String deviceId, String apiKey, SMSDTO smsDTO) { |
|||
Data inputData = new Data.Builder() |
|||
.putString(KEY_DEVICE_ID, deviceId) |
|||
.putString(KEY_API_KEY, apiKey) |
|||
.putString(KEY_SMS_DTO, new Gson().toJson(smsDTO)) |
|||
.putInt(KEY_RETRY_COUNT, 0) |
|||
.build(); |
|||
|
|||
Constraints constraints = new Constraints.Builder() |
|||
.setRequiredNetworkType(NetworkType.CONNECTED) |
|||
.build(); |
|||
|
|||
OneTimeWorkRequest workRequest = new OneTimeWorkRequest.Builder(SMSStatusUpdateWorker.class) |
|||
.setConstraints(constraints) |
|||
.setBackoffCriteria(BackoffPolicy.EXPONENTIAL, 10, TimeUnit.SECONDS) |
|||
.setInputData(inputData) |
|||
.build(); |
|||
|
|||
String uniqueWorkName = "sms_status_" + smsDTO.getStatus() + "_" + System.currentTimeMillis(); |
|||
WorkManager.getInstance(context) |
|||
.beginUniqueWork(uniqueWorkName, |
|||
androidx.work.ExistingWorkPolicy.REPLACE, |
|||
workRequest) |
|||
.enqueue(); |
|||
|
|||
Log.d(TAG, "Work enqueued for SMS status update - ID: " + smsDTO.getSmsId()); |
|||
} |
|||
} |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue