Browse Source

chore(android): refactor MainActivity

pull/8/head
isra el 2 years ago
parent
commit
31735b8d14
  1. 246
      android/app/src/main/java/com/vernu/sms/activities/MainActivity.java
  2. 9
      android/app/src/main/java/com/vernu/sms/dtos/SMSForwardResponseDTO.java

246
android/app/src/main/java/com/vernu/sms/activities/MainActivity.java

@ -3,18 +3,12 @@ package com.vernu.sms.activities;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.util.Log;
import android.view.View;
import android.widget.Button;
@ -25,61 +19,48 @@ import android.widget.RadioGroup;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.material.snackbar.Snackbar;
import com.google.firebase.messaging.FirebaseMessaging;
import com.google.zxing.integration.android.IntentIntegrator;
import com.google.zxing.integration.android.IntentResult;
import com.vernu.sms.services.GatewayApiService;
import com.vernu.sms.ApiManager;
import com.vernu.sms.AppConstants;
import com.vernu.sms.BuildConfig;
import com.vernu.sms.TextBeeUtils;
import com.vernu.sms.database.local.AppDatabase;
import com.vernu.sms.database.local.SMS;
import com.vernu.sms.R;
import com.vernu.sms.dtos.RegisterDeviceInputDTO;
import com.vernu.sms.dtos.RegisterDeviceResponseDTO;
import com.vernu.sms.helpers.SharedPreferenceHelper;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.Executors;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class MainActivity extends AppCompatActivity {
private Context mContext;
private Retrofit retrofit;
private GatewayApiService gatewayApiService;
private Switch gatewaySwitch;
private EditText apiKeyEditText, fcmTokenEditText;
private Button registerDeviceBtn, grantSMSPermissionBtn, scanQRBtn;
private ImageButton copyDeviceIdImgBtn;
private TextView deviceBrandAndModelTxt, deviceIdTxt;
private RadioGroup defaultSimSlotRadioGroup;
private static final int SEND_SMS_PERMISSION_REQUEST_CODE = 0;
private static final int SCAN_QR_REQUEST_CODE = 49374;
private static final String API_BASE_URL = "https://api.textbee.dev/api/v1/";
private static final int PERMISSION_REQUEST_CODE = 0;
private String deviceId = null;
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext = getApplicationContext();
retrofit = new Retrofit.Builder()
.baseUrl(API_BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
gatewayApiService = retrofit.create(GatewayApiService.class);
deviceId = SharedPreferenceHelper.getSharedPreferenceString(mContext, "DEVICE_ID", "");
deviceId = SharedPreferenceHelper.getSharedPreferenceString(mContext, AppConstants.SHARED_PREFS_DEVICE_ID_KEY, "");
setContentView(R.layout.activity_main);
gatewaySwitch = findViewById(R.id.gatewaySwitch);
apiKeyEditText = findViewById(R.id.apiKeyEditText);
@ -87,33 +68,11 @@ public class MainActivity extends AppCompatActivity {
registerDeviceBtn = findViewById(R.id.registerDeviceBtn);
grantSMSPermissionBtn = findViewById(R.id.grantSMSPermissionBtn);
scanQRBtn = findViewById(R.id.scanQRButton);
deviceBrandAndModelTxt = findViewById(R.id.deviceBrandAndModelTxt);
deviceIdTxt = findViewById(R.id.deviceIdTxt);
copyDeviceIdImgBtn = findViewById(R.id.copyDeviceIdImgBtn);
defaultSimSlotRadioGroup = findViewById(R.id.defaultSimSlotRadioGroup);
try {
getAvailableSimSlots().forEach(subscriptionInfo -> {
RadioButton radioButton = new RadioButton(mContext);
radioButton.setText(subscriptionInfo.getDisplayName().toString());
radioButton.setId(subscriptionInfo.getSubscriptionId());
radioButton.setOnClickListener(view -> {
SharedPreferenceHelper.setSharedPreferenceInt(mContext, "PREFERED_SIM", subscriptionInfo.getSubscriptionId());
});
radioButton.setChecked(subscriptionInfo.getSubscriptionId() == SharedPreferenceHelper.getSharedPreferenceInt(mContext, "PREFERED_SIM", 0));
defaultSimSlotRadioGroup.addView(radioButton);
});
} catch (Exception e) {
Snackbar.make(defaultSimSlotRadioGroup.getRootView(), "Error: " + e.getMessage(), Snackbar.LENGTH_LONG).show();
Log.e("SIM_SLOT_ERROR", e.getMessage());
}
deviceIdTxt.setText(deviceId);
deviceBrandAndModelTxt.setText(Build.BRAND + " " + Build.MODEL);
@ -123,14 +82,19 @@ public class MainActivity extends AppCompatActivity {
registerDeviceBtn.setText("Update");
}
if (isSMSPermissionGranted(mContext) && isReadPhoneStatePermissionGranted(mContext)) {
String[] missingPermissions = Arrays.stream(AppConstants.requiredPermissions).filter(permission -> !TextBeeUtils.isPermissionGranted(mContext, permission)).toArray(String[]::new);
if (missingPermissions.length == 0) {
grantSMSPermissionBtn.setEnabled(false);
grantSMSPermissionBtn.setText("SMS Permission Granted");
renderAvailableSimOptions();
} else {
Snackbar.make(grantSMSPermissionBtn, "Please Grant Required Permissions to continue: " + Arrays.toString(missingPermissions), Snackbar.LENGTH_SHORT).show();
grantSMSPermissionBtn.setEnabled(true);
grantSMSPermissionBtn.setOnClickListener(view -> handleSMSRequestPermission(view));
grantSMSPermissionBtn.setOnClickListener(this::handleRequestPermissions);
}
TextBeeUtils.startStickyNotificationService(mContext);
copyDeviceIdImgBtn.setOnClickListener(view -> {
ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("Device ID", deviceId);
@ -138,70 +102,111 @@ public class MainActivity extends AppCompatActivity {
Snackbar.make(view, "Copied", Snackbar.LENGTH_LONG).show();
});
apiKeyEditText.setText(SharedPreferenceHelper.getSharedPreferenceString(mContext, "API_KEY", ""));
gatewaySwitch.setChecked(SharedPreferenceHelper.getSharedPreferenceBoolean(mContext, "GATEWAY_ENABLED", false));
apiKeyEditText.setText(SharedPreferenceHelper.getSharedPreferenceString(mContext, AppConstants.SHARED_PREFS_API_KEY_KEY, ""));
gatewaySwitch.setChecked(SharedPreferenceHelper.getSharedPreferenceBoolean(mContext, AppConstants.SHARED_PREFS_GATEWAY_ENABLED_KEY, false));
gatewaySwitch.setOnCheckedChangeListener((compoundButton, isCheked) -> {
View view = compoundButton.getRootView();
compoundButton.setEnabled(false);
String key = apiKeyEditText.getText().toString();
RegisterDeviceInputDTO registerDeviceInput = new RegisterDeviceInputDTO();
registerDeviceInput.setEnabled(isCheked);
registerDeviceInput.setAppVersionCode(BuildConfig.VERSION_CODE);
registerDeviceInput.setAppVersionName(BuildConfig.VERSION_NAME);
Call<RegisterDeviceResponseDTO> apiCall = gatewayApiService.updateDevice(deviceId, key, registerDeviceInput);
Call<RegisterDeviceResponseDTO> apiCall = ApiManager.getApiService().updateDevice(deviceId, key, registerDeviceInput);
apiCall.enqueue(new Callback<RegisterDeviceResponseDTO>() {
@Override
public void onResponse(Call<RegisterDeviceResponseDTO> call, Response<RegisterDeviceResponseDTO> response) {
if (response.isSuccessful()) {
Snackbar.make(view, "Gateway " + (isCheked ? "enabled" : "disabled"), Snackbar.LENGTH_LONG).show();
SharedPreferenceHelper.setSharedPreferenceBoolean(mContext, "GATEWAY_ENABLED", isCheked);
compoundButton.setChecked(Boolean.TRUE.equals(response.body().data.get("enabled")));
} else {
Log.d(TAG, response.toString());
if (!response.isSuccessful()) {
Snackbar.make(view, response.message(), Snackbar.LENGTH_LONG).show();
compoundButton.setEnabled(true);
return;
}
Snackbar.make(view, "Gateway " + (isCheked ? "enabled" : "disabled"), Snackbar.LENGTH_LONG).show();
SharedPreferenceHelper.setSharedPreferenceBoolean(mContext, AppConstants.SHARED_PREFS_GATEWAY_ENABLED_KEY, isCheked);
boolean enabled = Boolean.TRUE.equals(Objects.requireNonNull(response.body()).data.get("enabled"));
compoundButton.setChecked(enabled);
if (enabled) {
TextBeeUtils.startStickyNotificationService(mContext);
} else {
TextBeeUtils.stopStickyNotificationService(mContext);
}
compoundButton.setEnabled(true);
}
@Override
public void onFailure(Call<RegisterDeviceResponseDTO> call, Throwable t) {
Snackbar.make(view, "An error occured :(", Snackbar.LENGTH_LONG).show();
compoundButton.setEnabled(true);
}
});
});
// TODO: check gateway status/api key/device validity and update UI accordingly
registerDeviceBtn.setOnClickListener(view -> handleRegisterDevice());
scanQRBtn.setOnClickListener(view -> {
IntentIntegrator intentIntegrator = new IntentIntegrator(MainActivity.this);
intentIntegrator.setPrompt("Go to textbee.dev/dashboard and click Register Device to generate QR Code");
intentIntegrator.setRequestCode(SCAN_QR_REQUEST_CODE);
intentIntegrator.initiateScan();
});
}
private void renderAvailableSimOptions() {
try {
defaultSimSlotRadioGroup.removeAllViews();
RadioButton defaultSimSlotRadioBtn = new RadioButton(mContext);
defaultSimSlotRadioBtn.setText("Device Default");
defaultSimSlotRadioBtn.setId((int)123456);
defaultSimSlotRadioGroup.addView(defaultSimSlotRadioBtn);
TextBeeUtils.getAvailableSimSlots(mContext).forEach(subscriptionInfo -> {
String simInfo = "SIM " + (subscriptionInfo.getSimSlotIndex() + 1) + " (" + subscriptionInfo.getDisplayName() + ")";
RadioButton radioButton = new RadioButton(mContext);
radioButton.setText(simInfo);
radioButton.setId(subscriptionInfo.getSubscriptionId());
defaultSimSlotRadioGroup.addView(radioButton);
});
int preferredSim = SharedPreferenceHelper.getSharedPreferenceInt(mContext, AppConstants.SHARED_PREFS_PREFERRED_SIM_KEY, -1);
if (preferredSim == -1) {
defaultSimSlotRadioGroup.check(defaultSimSlotRadioBtn.getId());
} else {
defaultSimSlotRadioGroup.check(preferredSim);
}
defaultSimSlotRadioGroup.setOnCheckedChangeListener((radioGroup, i) -> {
RadioButton radioButton = findViewById(i);
if (radioButton == null) {
return;
}
radioButton.setChecked(true);
if("Device Default".equals(radioButton.getText().toString())) {
SharedPreferenceHelper.clearSharedPreference(mContext, AppConstants.SHARED_PREFS_PREFERRED_SIM_KEY);
} else {
SharedPreferenceHelper.setSharedPreferenceInt(mContext, AppConstants.SHARED_PREFS_PREFERRED_SIM_KEY, radioButton.getId());
}
});
} catch (Exception e) {
Snackbar.make(defaultSimSlotRadioGroup.getRootView(), "Error: " + e.getMessage(), Snackbar.LENGTH_LONG).show();
Log.e(TAG, "SIM_SLOT_ERROR "+ e.getMessage());
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case SEND_SMS_PERMISSION_REQUEST_CODE: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(mContext, "Yay! Permission Granted.", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(mContext, "Permission Denied :(", Toast.LENGTH_LONG).show();
return;
}
}
}
if (requestCode != PERMISSION_REQUEST_CODE) {
return;
}
boolean allPermissionsGranted = Arrays.stream(permissions).allMatch(permission -> TextBeeUtils.isPermissionGranted(mContext, permission));
if (allPermissionsGranted) {
Snackbar.make(findViewById(R.id.grantSMSPermissionBtn), "All Permissions Granted", Snackbar.LENGTH_SHORT).show();
grantSMSPermissionBtn.setEnabled(false);
grantSMSPermissionBtn.setText("Permission Granted");
renderAvailableSimOptions();
} else {
Snackbar.make(findViewById(R.id.grantSMSPermissionBtn), "Please Grant Required Permissions to continue", Snackbar.LENGTH_SHORT).show();
}
}
private void handleRegisterDevice() {
@ -230,86 +235,63 @@ public class MainActivity extends AppCompatActivity {
registerDeviceInput.setModel(Build.MODEL);
registerDeviceInput.setBuildId(Build.ID);
registerDeviceInput.setOs(Build.VERSION.BASE_OS);
registerDeviceInput.setAppVersionCode(BuildConfig.VERSION_CODE);
registerDeviceInput.setAppVersionName(BuildConfig.VERSION_NAME);
Call<RegisterDeviceResponseDTO> apiCall = gatewayApiService.registerDevice(newKey, registerDeviceInput);
Call<RegisterDeviceResponseDTO> apiCall = ApiManager.getApiService().registerDevice(newKey, registerDeviceInput);
apiCall.enqueue(new Callback<RegisterDeviceResponseDTO>() {
@Override
public void onResponse(Call<RegisterDeviceResponseDTO> call, Response<RegisterDeviceResponseDTO> response) {
if (response.isSuccessful()) {
SharedPreferenceHelper.setSharedPreferenceString(mContext, "API_KEY", newKey);
Log.e("API_RESP", response.toString());
Snackbar.make(view, "Device Registration Successful :)", Snackbar.LENGTH_LONG).show();
deviceId = response.body().data.get("_id").toString();
deviceIdTxt.setText(deviceId);
SharedPreferenceHelper.setSharedPreferenceString(mContext, "DEVICE_ID", deviceId);
} else {
Log.d(TAG, response.toString());
if (!response.isSuccessful()) {
Snackbar.make(view, response.message(), Snackbar.LENGTH_LONG).show();
registerDeviceBtn.setEnabled(true);
registerDeviceBtn.setText("Update");
return;
}
SharedPreferenceHelper.setSharedPreferenceString(mContext, AppConstants.SHARED_PREFS_API_KEY_KEY, newKey);
Snackbar.make(view, "Device Registration Successful :)", Snackbar.LENGTH_LONG).show();
deviceId = response.body().data.get("_id").toString();
deviceIdTxt.setText(deviceId);
SharedPreferenceHelper.setSharedPreferenceString(mContext, AppConstants.SHARED_PREFS_DEVICE_ID_KEY, deviceId);
registerDeviceBtn.setEnabled(true);
registerDeviceBtn.setText("Update");
}
}
@Override
public void onFailure(Call<RegisterDeviceResponseDTO> call, Throwable t) {
Snackbar.make(view, "An error occured :(", Snackbar.LENGTH_LONG).show();
registerDeviceBtn.setEnabled(true);
registerDeviceBtn.setText("Update");
}
});
});
}
private void handleSMSRequestPermission(View view) {
if (isSMSPermissionGranted(mContext) && isReadPhoneStatePermissionGranted(mContext)) {
private void handleRequestPermissions(View view) {
boolean allPermissionsGranted = Arrays.stream(AppConstants.requiredPermissions).allMatch(permission -> TextBeeUtils.isPermissionGranted(mContext, permission));
if (allPermissionsGranted) {
Snackbar.make(view, "Already got permissions", Snackbar.LENGTH_SHORT).show();
} else {
Snackbar.make(view, "Grant SMS Permissions to continue", Snackbar.LENGTH_SHORT).show();
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.SEND_SMS, Manifest.permission.READ_PHONE_STATE
}, SEND_SMS_PERMISSION_REQUEST_CODE);
return;
}
String[] permissionsToRequest = Arrays.stream(AppConstants.requiredPermissions).filter(permission -> !TextBeeUtils.isPermissionGranted(mContext, permission)).toArray(String[]::new);
Snackbar.make(view, "Please Grant Required Permissions to continue", Snackbar.LENGTH_SHORT).show();
ActivityCompat.requestPermissions(this, permissionsToRequest, PERMISSION_REQUEST_CODE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == SCAN_QR_REQUEST_CODE) {
IntentResult intentResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
if (intentResult != null) {
if (intentResult.getContents() == null) {
Toast.makeText(getBaseContext(), "Canceled", Toast.LENGTH_SHORT).show();
} else {
String scannedQR = intentResult.getContents();
apiKeyEditText.setText(scannedQR);
handleRegisterDevice();
}
if (intentResult == null || intentResult.getContents() == null) {
Toast.makeText(getBaseContext(), "Canceled", Toast.LENGTH_SHORT).show();
return;
}
String scannedQR = intentResult.getContents();
apiKeyEditText.setText(scannedQR);
handleRegisterDevice();
}
}
private boolean isSMSPermissionGranted(Context context) {
return ContextCompat.checkSelfPermission(context, Manifest.permission.SEND_SMS) == PackageManager.PERMISSION_GRANTED;
}
private boolean isReadPhoneStatePermissionGranted(Context context) {
return ContextCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED;
}
private List<SubscriptionInfo> getAvailableSimSlots() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
return new ArrayList<>();
}
SubscriptionManager subscriptionManager = SubscriptionManager.from(mContext);
return subscriptionManager.getActiveSubscriptionInfoList();
}
}

9
android/app/src/main/java/com/vernu/sms/dtos/SMSForwardResponseDTO.java

@ -0,0 +1,9 @@
package com.vernu.sms.dtos;
public class SMSForwardResponseDTO {
public SMSForwardResponseDTO() {
}
}
Loading…
Cancel
Save