diff --git a/.idea/misc.xml b/.idea/misc.xml
index 6992e56..42d4ab2 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -3,7 +3,7 @@
diff --git a/app/build.gradle b/app/build.gradle
index 2ba692a..e219cf5 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -8,7 +8,7 @@ android {
defaultConfig {
applicationId "com.vernu.sms"
- minSdk 21
+ minSdk 24
targetSdk 32
versionCode 1
versionName "1.0"
@@ -45,4 +45,5 @@ dependencies {
implementation 'com.google.code.gson:gson:2.9.0'
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
+ implementation 'com.journeyapps:zxing-android-embedded:4.1.0'
}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 8d1fcf8..c9cfaa5 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,5 +1,6 @@
@@ -9,7 +10,8 @@
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
- android:theme="@style/Theme.SMSGateway">
+ android:theme="@style/Theme.SMSGateway"
+ android:usesCleartextTraffic="true" >
+
\ No newline at end of file
diff --git a/app/src/main/java/com/vernu/sms/GatewayApiService.java b/app/src/main/java/com/vernu/sms/GatewayApiService.java
deleted file mode 100644
index 8d6be14..0000000
--- a/app/src/main/java/com/vernu/sms/GatewayApiService.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package com.vernu.sms;
-
-import com.vernu.sms.dtos.UpdateDeviceInputDTO;
-import com.vernu.sms.dtos.UpdateDeviceResponseDTO;
-
-import retrofit2.Call;
-import retrofit2.http.Body;
-import retrofit2.http.PATCH;
-import retrofit2.http.Path;
-
-public interface GatewayApiService {
- @PATCH("gateway/devices/{deviceId}")
- Call updateDevice(@Path("deviceId") String deviceId, @Body() UpdateDeviceInputDTO body);
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/vernu/sms/activities/MainActivity.java b/app/src/main/java/com/vernu/sms/activities/MainActivity.java
index 4189d57..124638e 100644
--- a/app/src/main/java/com/vernu/sms/activities/MainActivity.java
+++ b/app/src/main/java/com/vernu/sms/activities/MainActivity.java
@@ -1,12 +1,14 @@
package com.vernu.sms.activities;
import androidx.annotation.NonNull;
+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.Context;
+import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
@@ -22,10 +24,12 @@ import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.android.material.snackbar.Snackbar;
import com.google.firebase.messaging.FirebaseMessaging;
-import com.vernu.sms.GatewayApiService;
+import com.google.zxing.integration.android.IntentIntegrator;
+import com.google.zxing.integration.android.IntentResult;
+import com.vernu.sms.services.GatewayApiService;
import com.vernu.sms.R;
-import com.vernu.sms.dtos.UpdateDeviceInputDTO;
-import com.vernu.sms.dtos.UpdateDeviceResponseDTO;
+import com.vernu.sms.dtos.RegisterDeviceInputDTO;
+import com.vernu.sms.dtos.RegisterDeviceResponseDTO;
import com.vernu.sms.helpers.SharedPreferenceHelper;
import retrofit2.Call;
@@ -41,28 +45,38 @@ public class MainActivity extends AppCompatActivity {
private GatewayApiService gatewayApiService;
private Switch gatewaySwitch;
- private EditText gatewayKeyEditText, fcmTokenEditText;
- private Button updateKeyButton, grantSMSPermissionBtn;
+ private EditText apiKeyEditText, fcmTokenEditText;
+ private Button registerDeviceBtn, grantSMSPermissionBtn, scanQRBtn;
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://vernu-sms.herokuapp.com/api/v1/";
+
+ private String deviceId = null;
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext = getApplicationContext();
+
retrofit = new Retrofit.Builder()
- .baseUrl("https://vernu-sms.herokuapp.com/api/v1/")
+ .baseUrl(API_BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
gatewayApiService = retrofit.create(GatewayApiService.class);
+ deviceId = SharedPreferenceHelper.getSharedPreferenceString(mContext, "DEVICE_ID", "");
+
setContentView(R.layout.activity_main);
gatewaySwitch = findViewById(R.id.gatewaySwitch);
- gatewayKeyEditText = findViewById(R.id.gatewayKeyEditText);
+ apiKeyEditText = findViewById(R.id.apiKeyEditText);
fcmTokenEditText = findViewById(R.id.fcmTokenEditText);
- updateKeyButton = findViewById(R.id.updateKeyButton);
+ registerDeviceBtn = findViewById(R.id.registerDeviceBtn);
grantSMSPermissionBtn = findViewById(R.id.grantSMSPermissionBtn);
+ scanQRBtn = findViewById(R.id.scanQRButton);
if (isSMSPermissionGranted(mContext)) {
grantSMSPermissionBtn.setEnabled(false);
@@ -77,7 +91,7 @@ public class MainActivity extends AppCompatActivity {
}
- gatewayKeyEditText.setText(SharedPreferenceHelper.getSharedPreferenceString(mContext, "GATEWAY_KEY", ""));
+ apiKeyEditText.setText(SharedPreferenceHelper.getSharedPreferenceString(mContext, "API_KEY", ""));
gatewaySwitch.setChecked(SharedPreferenceHelper.getSharedPreferenceBoolean(mContext, "GATEWAY_ENABLED", false));
gatewaySwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@@ -85,16 +99,16 @@ public class MainActivity extends AppCompatActivity {
public void onCheckedChanged(CompoundButton compoundButton, boolean isCheked) {
View view = compoundButton.getRootView();
compoundButton.setEnabled(false);
- String key = gatewayKeyEditText.getText().toString();
+ String key = apiKeyEditText.getText().toString();
- UpdateDeviceInputDTO updateDeviceInput = new UpdateDeviceInputDTO();
- updateDeviceInput.setEnabled(isCheked);
+ RegisterDeviceInputDTO registerDeviceInput = new RegisterDeviceInputDTO();
+ registerDeviceInput.setEnabled(isCheked);
- Call apiCall = gatewayApiService.updateDevice(key, updateDeviceInput);
- apiCall.enqueue(new Callback() {
+ Call apiCall = gatewayApiService.updateDevice(deviceId, key, registerDeviceInput);
+ apiCall.enqueue(new Callback() {
@Override
- public void onResponse(Call call, Response response) {
+ public void onResponse(Call call, Response response) {
if (response.isSuccessful()) {
SharedPreferenceHelper.setSharedPreferenceBoolean(mContext, "GATEWAY_ENABLED", isCheked);
@@ -108,7 +122,7 @@ public class MainActivity extends AppCompatActivity {
}
@Override
- public void onFailure(Call call, Throwable t) {
+ public void onFailure(Call call, Throwable t) {
Snackbar.make(view, "An error occured :(", Snackbar.LENGTH_LONG).show();
compoundButton.setEnabled(true);
@@ -119,65 +133,21 @@ public class MainActivity extends AppCompatActivity {
}
});
- updateKeyButton.setOnClickListener(new View.OnClickListener() {
+ registerDeviceBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
- String newKey = gatewayKeyEditText.getText().toString();
- updateKeyButton.setEnabled(false);
- updateKeyButton.setText("Loading...");
-
- FirebaseMessaging.getInstance().getToken()
- .addOnCompleteListener(new OnCompleteListener() {
- @Override
- public void onComplete(@NonNull Task task) {
- if (!task.isSuccessful()) {
- Snackbar.make(view, "Failed to obtain FCM Token :(", Snackbar.LENGTH_LONG).show();
- updateKeyButton.setEnabled(true);
- updateKeyButton.setText("Update");
- return;
- }
- String token = task.getResult();
- fcmTokenEditText.setText(token);
-
- UpdateDeviceInputDTO updateDeviceInput = new UpdateDeviceInputDTO();
- updateDeviceInput.setEnabled(true);
- updateDeviceInput.setFcmToken(token);
- updateDeviceInput.setBrand(Build.BRAND);
- updateDeviceInput.setManufacturer(Build.MANUFACTURER);
- updateDeviceInput.setModel(Build.MODEL);
- updateDeviceInput.setBuildId(Build.ID);
- updateDeviceInput.setOs(Build.VERSION.BASE_OS);
-
-
- Call apiCall = gatewayApiService.updateDevice(newKey, updateDeviceInput);
- apiCall.enqueue(new Callback() {
- @Override
- public void onResponse(Call call, Response response) {
-
- if (response.isSuccessful()) {
- SharedPreferenceHelper.setSharedPreferenceString(mContext, "GATEWAY_KEY", newKey);
- Log.e("API_RESP", response.toString());
- Snackbar.make(view, "DONE :)", Snackbar.LENGTH_LONG).show();
-
- } else {
- Snackbar.make(view, response.message(), Snackbar.LENGTH_LONG).show();
- }
- updateKeyButton.setEnabled(true);
- updateKeyButton.setText("Update");
- }
-
- @Override
- public void onFailure(Call call, Throwable t) {
- Snackbar.make(view, "An error occured :(", Snackbar.LENGTH_LONG).show();
- updateKeyButton.setEnabled(true);
- updateKeyButton.setText("Update");
-
- }
- });
- }
- });
+ handleRegisterDevice();
+ }
+ });
+ scanQRBtn.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ IntentIntegrator intentIntegrator = new IntentIntegrator(MainActivity.this);
+ intentIntegrator.setPrompt("Go to vernu-sms.vercel.app/dashboard and click Register Device to generate QR Code");
+ intentIntegrator.setRequestCode(SCAN_QR_REQUEST_CODE);
+ intentIntegrator.initiateScan();
}
});
@@ -200,6 +170,66 @@ public class MainActivity extends AppCompatActivity {
}
+ private void handleRegisterDevice() {
+
+ String newKey = apiKeyEditText.getText().toString();
+ registerDeviceBtn.setEnabled(false);
+ registerDeviceBtn.setText("Loading...");
+ View view = findViewById(R.id.registerDeviceBtn);
+
+ FirebaseMessaging.getInstance().getToken()
+ .addOnCompleteListener(new OnCompleteListener() {
+ @Override
+ public void onComplete(@NonNull Task task) {
+ if (!task.isSuccessful()) {
+ Snackbar.make(view, "Failed to obtain FCM Token :(", Snackbar.LENGTH_LONG).show();
+ registerDeviceBtn.setEnabled(true);
+ registerDeviceBtn.setText("Update");
+ return;
+ }
+ String token = task.getResult();
+ fcmTokenEditText.setText(token);
+
+ RegisterDeviceInputDTO registerDeviceInput = new RegisterDeviceInputDTO();
+ registerDeviceInput.setEnabled(true);
+ registerDeviceInput.setFcmToken(token);
+ registerDeviceInput.setBrand(Build.BRAND);
+ registerDeviceInput.setManufacturer(Build.MANUFACTURER);
+ registerDeviceInput.setModel(Build.MODEL);
+ registerDeviceInput.setBuildId(Build.ID);
+ registerDeviceInput.setOs(Build.VERSION.BASE_OS);
+
+
+ Call apiCall = gatewayApiService.registerDevice(newKey, registerDeviceInput);
+ apiCall.enqueue(new Callback() {
+ @Override
+ public void onResponse(Call call, Response 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();
+ SharedPreferenceHelper.setSharedPreferenceString(mContext, "DEVICE_ID", response.body().data.get("_id").toString());
+
+ } else {
+ Snackbar.make(view, response.message(), Snackbar.LENGTH_LONG).show();
+ }
+ registerDeviceBtn.setEnabled(true);
+ registerDeviceBtn.setText("Update");
+ }
+
+ @Override
+ public void onFailure(Call 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)) {
Snackbar.make(view, "Already got permissions", Snackbar.LENGTH_SHORT).show();
@@ -215,6 +245,25 @@ public class MainActivity extends AppCompatActivity {
}
}
+ @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();
+ }
+ }
+ }
+ }
+
private boolean isSMSPermissionGranted(Context context) {
return ContextCompat.checkSelfPermission(context, Manifest.permission.SEND_SMS) == PackageManager.PERMISSION_GRANTED;
}
diff --git a/app/src/main/java/com/vernu/sms/dtos/UpdateDeviceInputDTO.java b/app/src/main/java/com/vernu/sms/dtos/RegisterDeviceInputDTO.java
similarity index 94%
rename from app/src/main/java/com/vernu/sms/dtos/UpdateDeviceInputDTO.java
rename to app/src/main/java/com/vernu/sms/dtos/RegisterDeviceInputDTO.java
index dc763fb..f803814 100644
--- a/app/src/main/java/com/vernu/sms/dtos/UpdateDeviceInputDTO.java
+++ b/app/src/main/java/com/vernu/sms/dtos/RegisterDeviceInputDTO.java
@@ -1,6 +1,6 @@
package com.vernu.sms.dtos;
-public class UpdateDeviceInputDTO {
+public class RegisterDeviceInputDTO {
private String fcmToken;
private boolean enabled;
private String brand;
@@ -13,10 +13,10 @@ public class UpdateDeviceInputDTO {
private String appVersionName;
private String appVersionCode;
- public UpdateDeviceInputDTO() {
+ public RegisterDeviceInputDTO() {
}
- public UpdateDeviceInputDTO(String fcmToken) {
+ public RegisterDeviceInputDTO(String fcmToken) {
this.fcmToken = fcmToken;
}
diff --git a/app/src/main/java/com/vernu/sms/dtos/RegisterDeviceResponseDTO.java b/app/src/main/java/com/vernu/sms/dtos/RegisterDeviceResponseDTO.java
new file mode 100644
index 0000000..64ed318
--- /dev/null
+++ b/app/src/main/java/com/vernu/sms/dtos/RegisterDeviceResponseDTO.java
@@ -0,0 +1,9 @@
+package com.vernu.sms.dtos;
+
+import java.util.Map;
+
+public class RegisterDeviceResponseDTO {
+ public boolean success;
+ public Map data;
+ public String error;
+}
diff --git a/app/src/main/java/com/vernu/sms/dtos/UpdateDeviceResponseDTO.java b/app/src/main/java/com/vernu/sms/dtos/UpdateDeviceResponseDTO.java
deleted file mode 100644
index 64ad23a..0000000
--- a/app/src/main/java/com/vernu/sms/dtos/UpdateDeviceResponseDTO.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package com.vernu.sms.dtos;
-
-public class UpdateDeviceResponseDTO {
- public boolean success;
- public Object data;
- public String error;
-}
diff --git a/app/src/main/java/com/vernu/sms/services/GatewayApiService.java b/app/src/main/java/com/vernu/sms/services/GatewayApiService.java
new file mode 100644
index 0000000..73e546e
--- /dev/null
+++ b/app/src/main/java/com/vernu/sms/services/GatewayApiService.java
@@ -0,0 +1,19 @@
+package com.vernu.sms.services;
+
+import com.vernu.sms.dtos.RegisterDeviceInputDTO;
+import com.vernu.sms.dtos.RegisterDeviceResponseDTO;
+
+import retrofit2.Call;
+import retrofit2.http.Body;
+import retrofit2.http.PATCH;
+import retrofit2.http.POST;
+import retrofit2.http.Path;
+import retrofit2.http.Query;
+
+public interface GatewayApiService {
+ @POST("gateway/devices")
+ Call registerDevice(@Query("apiKey") String apiKey, @Body() RegisterDeviceInputDTO body);
+
+ @PATCH("gateway/devices/{deviceId}")
+ Call updateDevice(@Path("deviceId") String deviceId, @Query("apiKey") String apiKey, @Body() RegisterDeviceInputDTO body);
+}
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index 5f5017a..2b76b7e 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -10,30 +10,32 @@
android:id="@+id/gatewaySwitch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:minHeight="32dp"
android:text="Status"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
+ app:layout_constraintEnd_toEndOf="@+id/apiKeyEditText"
+ app:layout_constraintStart_toStartOf="@+id/apiKeyEditText"
+ app:layout_constraintTop_toBottomOf="@+id/apiKeyEditText" />
+
+
+ app:layout_constraintTop_toBottomOf="@+id/scanQRButton"
+ app:layout_constraintVertical_bias="0.0">
+ android:orientation="vertical">
+
+