diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..aa724b7
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,15 @@
+*.iml
+.gradle
+/local.properties
+/.idea/caches
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+/.idea/navEditor.xml
+/.idea/assetWizardSettings.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild
+.cxx
+local.properties
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..26d3352
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
new file mode 100644
index 0000000..4e3844e
--- /dev/null
+++ b/.idea/gradle.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml
new file mode 100644
index 0000000..cfc391f
--- /dev/null
+++ b/.idea/jarRepositories.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..62269df
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/.gitignore b/app/.gitignore
new file mode 100644
index 0000000..42afabf
--- /dev/null
+++ b/app/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
new file mode 100644
index 0000000..b68c72d
--- /dev/null
+++ b/app/build.gradle
@@ -0,0 +1,82 @@
+plugins {
+ id 'com.android.application'
+}
+
+android {
+ compileSdkVersion 28
+
+ defaultConfig {
+ applicationId "com.cst.im30"
+ minSdkVersion 22
+ //noinspection ExpiredTargetSdkVersion
+ targetSdkVersion 28
+ versionCode 1
+ versionName "1.0.0"
+
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ }
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ implementation files('libs/NeptuneLiteApi_V3.00.00_20180717.jar')
+
+ //noinspection GradleDependency
+ implementation 'androidx.appcompat:appcompat:1.3.1'
+ //noinspection GradleDependency
+ implementation 'com.google.android.material:material:1.4.0'
+ //noinspection GradleDependency
+ implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
+
+ //noinspection GradleDynamicVersion
+ testImplementation 'junit:junit:4.+'
+ androidTestImplementation 'androidx.test.ext:junit:1.1.3'
+ androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
+
+ // For Laravel Echo
+ implementation 'com.github.MrBin99:LaravelEchoAndroid:1.03'
+
+ //noinspection AnnotationProcessorOnCompilePath
+ implementation 'org.projectlombok:lombok:1.18.22'
+ annotationProcessor "org.projectlombok:lombok:1.18.22"
+
+ implementation 'com.squareup.retrofit2:retrofit:2.9.0'
+ implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
+ implementation 'com.squareup.retrofit2:converter-scalars:2.9.0'
+
+ //noinspection GradleDependency
+ implementation "androidx.room:room-runtime:2.3.0"
+ //noinspection GradleDependency
+ annotationProcessor "androidx.room:room-compiler:2.3.0"
+
+ implementation 'com.github.bumptech.glide:glide:4.9.0'
+ annotationProcessor 'com.github.bumptech.glide:compiler:4.9.0'
+
+ //for slider
+ implementation 'com.daimajia.slider:library:1.1.5@aar'
+ implementation 'com.nineoldandroids:library:2.4.0'
+ implementation 'com.squareup.picasso:picasso:2.5.2'
+
+ implementation 'com.loopj.android:android-async-http:1.4.9'
+ implementation 'com.nex3z:flow-layout:1.2.4'
+ //noinspection GradleDynamicVersion
+ implementation 'com.android.support:recyclerview-v7:+'
+ //noinspection GradleDependency
+ implementation 'com.google.code.gson:gson:2.8.5'
+ //noinspection GradleDynamicVersion
+ implementation 'me.grantland:autofittextview:0.2.+'
+
+ debugImplementation 'com.github.amitshekhariitbhu.Android-Debug-Database:debug-db:v1.0.6'
+
+}
\ No newline at end of file
diff --git a/app/libs/CL_common_V1.00.00_20170616.jar b/app/libs/CL_common_V1.00.00_20170616.jar
new file mode 100644
index 0000000..72d8968
Binary files /dev/null and b/app/libs/CL_common_V1.00.00_20170616.jar differ
diff --git a/app/libs/NeptuneLiteApi_V3.00.00_20180717.jar b/app/libs/NeptuneLiteApi_V3.00.00_20180717.jar
new file mode 100644
index 0000000..108e698
Binary files /dev/null and b/app/libs/NeptuneLiteApi_V3.00.00_20180717.jar differ
diff --git a/app/libs/PURE_v100.jar b/app/libs/PURE_v100.jar
new file mode 100644
index 0000000..398500e
Binary files /dev/null and b/app/libs/PURE_v100.jar differ
diff --git a/app/libs/libAmex_V1.00.00_20170614.jar b/app/libs/libAmex_V1.00.00_20170614.jar
new file mode 100644
index 0000000..db67bb3
Binary files /dev/null and b/app/libs/libAmex_V1.00.00_20170614.jar differ
diff --git a/app/libs/libDPAS_V1.00.00_20170809.jar b/app/libs/libDPAS_V1.00.00_20170809.jar
new file mode 100644
index 0000000..a59b598
Binary files /dev/null and b/app/libs/libDPAS_V1.00.00_20170809.jar differ
diff --git a/app/libs/libDevice_V1.00.00_20170616.jar b/app/libs/libDevice_V1.00.00_20170616.jar
new file mode 100644
index 0000000..e606100
Binary files /dev/null and b/app/libs/libDevice_V1.00.00_20170616.jar differ
diff --git a/app/libs/libEMV_V1.00.00_20170616.jar b/app/libs/libEMV_V1.00.00_20170616.jar
new file mode 100644
index 0000000..d987681
Binary files /dev/null and b/app/libs/libEMV_V1.00.00_20170616.jar differ
diff --git a/app/libs/libEntry_V1.00.00_20170616.jar b/app/libs/libEntry_V1.00.00_20170616.jar
new file mode 100644
index 0000000..249a2c8
Binary files /dev/null and b/app/libs/libEntry_V1.00.00_20170616.jar differ
diff --git a/app/libs/libMC_V1.00.00_20170616.jar b/app/libs/libMC_V1.00.00_20170616.jar
new file mode 100644
index 0000000..edb7e12
Binary files /dev/null and b/app/libs/libMC_V1.00.00_20170616.jar differ
diff --git a/app/libs/libQPBOC_V1.00.00_20170705.jar b/app/libs/libQPBOC_V1.00.00_20170705.jar
new file mode 100644
index 0000000..b647990
Binary files /dev/null and b/app/libs/libQPBOC_V1.00.00_20170705.jar differ
diff --git a/app/libs/libWave_V1.00.00_20170616.jar b/app/libs/libWave_V1.00.00_20170616.jar
new file mode 100644
index 0000000..c1843fd
Binary files /dev/null and b/app/libs/libWave_V1.00.00_20170616.jar differ
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
new file mode 100644
index 0000000..481bb43
--- /dev/null
+++ b/app/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
\ No newline at end of file
diff --git a/app/src/androidTest/java/com/cst/im30/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/cst/im30/ExampleInstrumentedTest.java
new file mode 100644
index 0000000..c77d82d
--- /dev/null
+++ b/app/src/androidTest/java/com/cst/im30/ExampleInstrumentedTest.java
@@ -0,0 +1,26 @@
+package com.cst.im30;
+
+import static org.junit.Assert.assertEquals;
+
+import android.content.Context;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * @see Testing documentation
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest {
+ @Test
+ public void useAppContext() {
+ // Context of the app under test.
+ Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
+ assertEquals("com.cst.udc_payment_terminal_im30", appContext.getPackageName());
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..8bbf71d
--- /dev/null
+++ b/app/src/main/AndroidManifest.xml
@@ -0,0 +1,70 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/ic_udc_launcher-playstore.png b/app/src/main/ic_udc_launcher-playstore.png
new file mode 100644
index 0000000..be8f86d
Binary files /dev/null and b/app/src/main/ic_udc_launcher-playstore.png differ
diff --git a/app/src/main/java/com/cst/im30/EchoClient.java b/app/src/main/java/com/cst/im30/EchoClient.java
new file mode 100644
index 0000000..50156ad
--- /dev/null
+++ b/app/src/main/java/com/cst/im30/EchoClient.java
@@ -0,0 +1,55 @@
+package com.cst.im30;
+
+import com.cst.im30.activity.MainActivity;
+
+import net.mrbin99.laravelechoandroid.Echo;
+import net.mrbin99.laravelechoandroid.EchoCallback;
+import net.mrbin99.laravelechoandroid.EchoOptions;
+import net.mrbin99.laravelechoandroid.channel.SocketIOChannel;
+
+public class EchoClient {
+
+ private Echo echo;
+ private EchoOptions options;
+
+ private String host;
+
+ private MainActivity context;
+
+ public EchoClient(MainActivity context, String host) {
+ this.context = context;
+ this.host = host;
+
+ this.options = new EchoOptions();
+ this.options.host = host;
+
+ /*
+ * Add headers for authorizing your users (private and presence channels).
+ * This line can change matching how you have configured
+ * your guards on your Laravel application
+ */
+ //options.headers.put("Authorization", "Bearer {token}");
+
+ init();
+ }
+
+ public void init() {
+ this.echo = new Echo(options);
+ }
+
+ public void connect(EchoCallback successCallback, EchoCallback failureCallback) {
+ echo.connect(successCallback, failureCallback);
+ }
+
+ public SocketIOChannel channel(String channelName) {
+ return echo.channel(channelName);
+ }
+
+ public void disconnect() {
+ echo.disconnect();
+ }
+
+ public boolean isConnected() {
+ return echo.isConnected();
+ }
+}
diff --git a/app/src/main/java/com/cst/im30/EchoClientSetting.java b/app/src/main/java/com/cst/im30/EchoClientSetting.java
new file mode 100644
index 0000000..c1883c6
--- /dev/null
+++ b/app/src/main/java/com/cst/im30/EchoClientSetting.java
@@ -0,0 +1,56 @@
+package com.cst.im30;
+
+import com.cst.im30.activity.SettingActivity;
+
+import net.mrbin99.laravelechoandroid.Echo;
+import net.mrbin99.laravelechoandroid.EchoCallback;
+import net.mrbin99.laravelechoandroid.EchoOptions;
+import net.mrbin99.laravelechoandroid.channel.SocketIOChannel;
+
+public class EchoClientSetting {
+
+ private Echo echo;
+ private EchoOptions options;
+
+ private String host;
+
+ private SettingActivity context;
+
+ public EchoClientSetting(SettingActivity context, String host) {
+ this.context = context;
+ this.host = host;
+
+ this.options = new EchoOptions();
+ this.options.host = host;
+
+ /*
+ * Add headers for authorizing your users (private and presence channels).
+ * This line can change matching how you have configured
+ * your guards on your Laravel application
+ */
+ //options.headers.put("Authorization", "Bearer {token}");
+
+ init();
+ }
+
+ public void init() {
+ this.echo = new Echo(options);
+ }
+
+ public void connect(EchoCallback successCallback, EchoCallback failureCallback) {
+ echo.connect(successCallback, failureCallback);
+ }
+
+ public SocketIOChannel channel(String channelName) {
+ return echo.channel(channelName);
+ }
+
+ public void disconnect() {
+ echo.disconnect();
+ }
+
+ public boolean isConnected() {
+ return echo.isConnected();
+ }
+
+}
diff --git a/app/src/main/java/com/cst/im30/ICEchoClient.java b/app/src/main/java/com/cst/im30/ICEchoClient.java
new file mode 100644
index 0000000..004f84a
--- /dev/null
+++ b/app/src/main/java/com/cst/im30/ICEchoClient.java
@@ -0,0 +1,12 @@
+package com.cst.im30;
+
+import com.cst.im30.activity.MainActivity;
+
+public class ICEchoClient extends EchoClient {
+
+ public ICEchoClient(MainActivity context, String host) {
+ super(context, host);
+ }
+
+
+}
diff --git a/app/src/main/java/com/cst/im30/MainApplication.java b/app/src/main/java/com/cst/im30/MainApplication.java
new file mode 100644
index 0000000..9dad69b
--- /dev/null
+++ b/app/src/main/java/com/cst/im30/MainApplication.java
@@ -0,0 +1,25 @@
+package com.cst.im30;
+
+import android.app.Application;
+import android.util.Log;
+
+public class MainApplication extends Application {
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+
+ initializeCrashHandler();
+ }
+
+ private void initializeCrashHandler() {
+ Thread.setDefaultUncaughtExceptionHandler(this::handleUncaughtException);
+ }
+
+ public void handleUncaughtException(Thread thread, Throwable e) {
+ if (e instanceof Exception) {
+ Log.e("CST-DBG", "Exception: " + Log.getStackTraceString(e));
+ System.out.println();
+ }
+ }
+}
diff --git a/app/src/main/java/com/cst/im30/activity/ICCActivity.java b/app/src/main/java/com/cst/im30/activity/ICCActivity.java
new file mode 100644
index 0000000..09a69f2
--- /dev/null
+++ b/app/src/main/java/com/cst/im30/activity/ICCActivity.java
@@ -0,0 +1,548 @@
+package com.cst.im30.activity;
+
+import android.annotation.SuppressLint;
+import android.app.Activity;
+import android.app.ProgressDialog;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Environment;
+import android.os.Handler;
+import android.os.Message;
+import android.os.SystemClock;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.TextView;
+
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.AlertDialog;
+import androidx.appcompat.app.AppCompatActivity;
+
+import com.cst.im30.R;
+import com.cst.im30.utility.IccTester;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+
+public class ICCActivity extends AppCompatActivity {
+
+ private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ private static final int RETURN_REQUEST = 0;
+ public static IccDetectedThread iccDetectedThread;
+ public static CardDetectedThread cardDetectedThread;
+ public static CardInsertedThread cardInsertedThread;
+ public static boolean isIcDetected;
+ public static boolean stopChecking;
+ private ProgressDialog pd;
+ private String name;
+ private String cardNo;
+ private AlertDialog alertDialogPromptCard;
+ @SuppressLint("HandlerLeak")
+ private Handler handler = new Handler() {
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case 0: //got card
+ iccDetectedThread.interrupt();
+ ArrayList info = (ArrayList) msg.obj;
+ if (info.get(0).trim().equals("")) {
+ pd.dismiss();
+ AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(ICCActivity.this);
+ LayoutInflater inflater = (LayoutInflater) ICCActivity.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ View dialogView = inflater.inflate(R.layout.confirm, null);
+
+ TextView textMessage = dialogView.findViewById(R.id.text_message_confirm);
+ TextView textTitle = dialogView.findViewById(R.id.text_title_confirm);
+
+ textTitle.setText("Error");
+ textMessage.setText("Invalid card.");
+
+ dialogBuilder.setPositiveButton("OK", (dialog, which) -> {
+ stopChecking = false;
+ insertCard();
+ });
+ dialogBuilder.setCancelable(false);
+ dialogBuilder.setView(dialogView);
+
+ AlertDialog alertDialog = dialogBuilder.create();
+ alertDialog.show();
+ } else {
+ name = info.get(1).trim();
+ cardNo = info.get(0).trim();
+
+ AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(ICCActivity.this);
+ LayoutInflater inflater = (LayoutInflater) ICCActivity.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ View dialogView = inflater.inflate(R.layout.confirm, null);
+
+ TextView textMessage = dialogView.findViewById(R.id.text_message_confirm);
+ TextView textTitle = dialogView.findViewById(R.id.text_title_confirm);
+
+ textTitle.setText("Read Success");
+ textMessage.setText("Please remove card.");
+
+ dialogBuilder.setCancelable(false);
+ dialogBuilder.setView(dialogView);
+
+ alertDialogPromptCard = dialogBuilder.create();
+ alertDialogPromptCard.show();
+
+ checkCard();
+ }
+ break;
+ case 1: //no card
+ iccDetectedThread.interrupt();
+ pd.dismiss();
+
+ AlertDialog.Builder dialogBuilder1 = new AlertDialog.Builder(ICCActivity.this);
+ LayoutInflater inflater1 = (LayoutInflater) ICCActivity.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ View dialogView1 = inflater1.inflate(R.layout.confirm, null);
+
+ TextView textMessage1 = dialogView1.findViewById(R.id.text_message_confirm);
+ TextView textTitle1 = dialogView1.findViewById(R.id.text_title_confirm);
+
+ textTitle1.setText("Error");
+ textMessage1.setText("No card detected. Please insert card to read.");
+
+ dialogBuilder1.setPositiveButton("OK", (dialog, which) -> {
+ stopChecking = false;
+ insertCard();
+ });
+ dialogBuilder1.setCancelable(false);
+ dialogBuilder1.setView(dialogView1);
+
+ AlertDialog alertDialog1 = dialogBuilder1.create();
+ alertDialog1.show();
+
+ break;
+
+ case 2: //invalid card
+ iccDetectedThread.interrupt();
+ pd.dismiss();
+
+ AlertDialog.Builder dialogBuilder2 = new AlertDialog.Builder(ICCActivity.this);
+ LayoutInflater inflater2 = (LayoutInflater) ICCActivity.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ View dialogView2 = inflater2.inflate(R.layout.confirm, null);
+
+ TextView textMessage2 = dialogView2.findViewById(R.id.text_message_confirm);
+ TextView textTitle2 = dialogView2.findViewById(R.id.text_title_confirm);
+
+ textTitle2.setText("Error");
+ textMessage2.setText(msg.obj.toString());
+
+ dialogBuilder2.setPositiveButton("OK", (dialog, which) -> {
+ stopChecking = false;
+ insertCard();
+ });
+ dialogBuilder2.setCancelable(false);
+ dialogBuilder2.setView(dialogView2);
+
+ AlertDialog alertDialog2 = dialogBuilder2.create();
+ alertDialog2.show();
+
+ break;
+
+ default:
+ break;
+ }
+ }
+ };
+ @SuppressLint("HandlerLeak")
+ private Handler handlerCard = new Handler() {
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case 0:
+ cardDetectedThread.interrupt();
+ SystemClock.sleep(1000);
+ checkCard();
+ break;
+ case 1:
+ cardDetectedThread.interrupt();
+ if (alertDialogPromptCard.isShowing()) {
+ alertDialogPromptCard.dismiss();
+ }
+ pd.dismiss();
+
+ Intent outgoingIntent = new Intent();
+ outgoingIntent.putExtra("name", name);
+ outgoingIntent.putExtra("cardNo", cardNo);
+
+ Log.d(MainActivity.TAG, name + ":" + cardNo);
+
+ setResult(RESULT_OK, outgoingIntent);
+ finish();
+
+ //reset();
+ break;
+ default:
+ break;
+ }
+ }
+ };
+ @SuppressLint("HandlerLeak")
+ private Handler handlerInsertCard = new Handler() {
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case 0: //got card
+ stopChecking = true;
+ cardInsertedThread.interrupt();
+ pd = ICCActivity.getLoadingBar(ICCActivity.this);
+ appIsReady();
+
+ break;
+
+ case 1: //no card
+ cardInsertedThread.interrupt();
+ SystemClock.sleep(1000);
+
+ if (!stopChecking) {
+ insertCard();
+ }
+
+ break;
+
+ default:
+ break;
+ }
+ }
+ };
+
+ public static ProgressDialog getLoadingBar(Context context) {
+ ProgressDialog progressDialogWait;
+ progressDialogWait = new ProgressDialog(context);
+ progressDialogWait.setCancelable(false);
+ progressDialogWait.setMessage("Please wait...");
+ progressDialogWait.show();
+
+ return progressDialogWait;
+ }
+
+ public static void appendLog(Exception e) {
+ String callerTime = dateFormat.format(new Date());
+ String callerClass = e.getStackTrace()[0].getClassName();
+ String callerMethod = e.getStackTrace()[0].getMethodName();
+ String callerLine = String.valueOf(e.getStackTrace()[0].getLineNumber());
+ String text = "Timestamp: " + callerTime + "\nClass: " + callerClass + "\nMethod: " + callerMethod + "\nLine: " + callerLine + "\n" + e.getMessage() + "\n";
+
+ File logFile = getLogPath("error");
+
+ try {
+ //BufferedWriter for performance, true to set append to file flag
+ BufferedWriter buf = new BufferedWriter(new FileWriter(logFile, true));
+ buf.append(text);
+ buf.newLine();
+ buf.close();
+ } catch (Exception ignored) {
+ }
+ }
+
+ public static File getLogPath(String name) {
+ File sdcard = Environment.getExternalStorageDirectory();
+ String logFile = sdcard.getAbsolutePath() + File.separator + "subsidy" + File.separator + name;
+
+ if (!logFile.endsWith(".log")) {
+ logFile += ".log";
+ }
+
+ File result = new File(logFile);
+
+ if (!result.getParentFile().exists()) {
+ result.getParentFile().mkdirs();
+ }
+
+ return result;
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_icc);
+ setTitle("Read Card");
+
+ name = "";
+ cardNo = "";
+
+ isIcDetected = false;
+ stopChecking = false;
+ insertCard();
+ }
+
+ @Override
+ public void finish() {
+ stopChecking = true;
+ if (cardInsertedThread != null) {
+ cardInsertedThread.interrupt();
+ }
+ if (cardDetectedThread != null) {
+ cardDetectedThread.interrupt();
+ }
+ if (iccDetectedThread != null) {
+ iccDetectedThread.interrupt();
+ }
+ if (pd != null) {
+ pd.dismiss();
+ }
+ super.finish();
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
+ if (resultCode == Activity.RESULT_OK) {
+ if (requestCode == RETURN_REQUEST) {
+ finish();
+ }
+ } else {
+ stopChecking = false;
+ insertCard();
+ }
+ if (pd != null) {
+ pd.dismiss();
+ }
+ }
+
+ private void reset() {
+ name = "";
+ cardNo = "";
+
+ isIcDetected = false;
+ stopChecking = false;
+ insertCard();
+ }
+
+ private void appIsReady() {
+ if (iccDetectedThread == null) {
+ iccDetectedThread = new IccDetectedThread();
+ iccDetectedThread.start();
+ } else {
+ iccDetectedThread = new IccDetectedThread();
+ iccDetectedThread.start();
+ }
+ }
+
+ private void checkCard() {
+ if (cardDetectedThread == null) {
+ cardDetectedThread = new CardDetectedThread();
+ cardDetectedThread.start();
+ } else {
+ cardDetectedThread = new CardDetectedThread();
+ cardDetectedThread.start();
+ }
+ }
+
+ private void insertCard() {
+ cardInsertedThread = new CardInsertedThread();
+ cardInsertedThread.start();
+ }
+
+ public String getHexValue(byte[] source) {
+ StringBuilder sb = new StringBuilder();
+ for (byte b : source) {
+ sb.append(String.format("%02X ", b));
+ }
+ return sb.toString();
+ }
+
+ public class IccDetectedThread extends Thread {
+ @Override
+ public void run() {
+ super.run();
+
+ String nric = "";
+ String name = "";
+ String cardVer = "";
+ IccTester.getInstance(ICCActivity.this).light(true);
+
+ while (!Thread.interrupted()) {
+ isIcDetected = IccTester.getInstance(ICCActivity.this).detect((byte) 0);
+
+ if (isIcDetected) {
+ byte[] res = IccTester.getInstance(getApplicationContext()).init((byte) 0);
+
+ if (res == null) {
+ //Log.i("Test", "init ic card,but no response");
+ Message message = Message.obtain();
+ message.what = 2;
+ message.obj = "Invalid card.";
+ handler.sendMessage(message);
+ return;
+ }
+
+ IccTester.getInstance(getApplicationContext()).autoResp((byte) 0, true);// 设置iccIsoCommand函数是否自动发送GET RESPONSE指令。
+
+ byte[] selectJpn = new byte[]{(byte) 0x00, (byte) 0xA4, (byte) 0x04, (byte) 0x00, (byte) 0x0A, (byte) 0xA0, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x74, (byte) 0x4A, (byte) 0x50, (byte) 0x4E, (byte) 0x00, (byte) 0x10};
+ byte[] readIc = new byte[]{(byte) 0xC8, (byte) 0x32, (byte) 0x00, (byte) 0x00, (byte) 0x05, (byte) 0x08, (byte) 0x00, (byte) 0x00, (byte) 0x0D, (byte) 0x00};
+ byte[] readIc1 = new byte[]{(byte) 0xCC, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x08, (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x11, (byte) 0x01, (byte) 0x0D, (byte) 0x00};
+ byte[] readIc2 = new byte[]{(byte) 0xCC, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x0D};
+
+ byte[] readName = new byte[]{(byte) 0xC8, (byte) 0x32, (byte) 0x00, (byte) 0x00, (byte) 0x05, (byte) 0x08, (byte) 0x00, (byte) 0x00, (byte) 0x28, (byte) 0x00};
+ byte[] readName1 = new byte[]{(byte) 0xCC, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x08, (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0xE9, (byte) 0x00, (byte) 0x28, (byte) 0x00};
+ byte[] readName2 = new byte[]{(byte) 0xCC, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x28};
+
+ byte[] readCard = new byte[]{(byte) 0xC8, (byte) 0x32, (byte) 0x00, (byte) 0x00, (byte) 0x05, (byte) 0x08, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00};
+ byte[] readCard1 = new byte[]{(byte) 0xCC, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x08, (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x8F, (byte) 0x01, (byte) 0x01, (byte) 0x00};
+ byte[] readCard2 = new byte[]{(byte) 0xCC, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x01};
+
+ byte[] isoRes = IccTester.getInstance(getApplicationContext()).isoCommand((byte) 0, selectJpn);
+
+ if (isoRes != null) {
+
+ String isoStr = null;
+
+ try {
+ byte[] isoResx = IccTester.getInstance(getApplicationContext()).isoCommand((byte) 0, readIc);
+
+ byte[] isoRes1 = IccTester.getInstance(getApplicationContext()).isoCommand((byte) 0, readIc1);
+ Log.d("ZZZ1", getHexValue(isoRes1));
+
+ byte[] isoRes2 = IccTester.getInstance(getApplicationContext()).isoCommand((byte) 0, readIc2);
+ Log.d("ZZZ2", getHexValue(isoRes2));
+
+ byte[] icBytes = Arrays.copyOfRange(isoRes2, 0, isoRes2.length - 3);
+ Log.d("ZZZ3", new String(icBytes));
+
+ nric = new String(icBytes);
+
+ byte[] isoResN = IccTester.getInstance(getApplicationContext()).isoCommand((byte) 0, readName);
+ Log.d("ZZZ4", getHexValue(isoResN));
+
+ byte[] isoResN1 = IccTester.getInstance(getApplicationContext()).isoCommand((byte) 0, readName1);
+ Log.d("ZZZ5", getHexValue(isoResN1));
+
+ byte[] isoResN2 = IccTester.getInstance(getApplicationContext()).isoCommand((byte) 0, readName2);
+ Log.d("ZZZ6", getHexValue(isoResN2));
+
+ byte[] nameBytes = Arrays.copyOfRange(isoResN2, 0, isoResN2.length - 2);
+ Log.d("ZZZ7", new String(nameBytes));
+
+ name = new String(nameBytes);
+
+ byte[] isoResC = IccTester.getInstance(getApplicationContext()).isoCommand((byte) 0, readCard);
+ Log.d("ZZZ8", getHexValue(isoResC));
+
+ byte[] isoResC1 = IccTester.getInstance(getApplicationContext()).isoCommand((byte) 0, readCard1);
+ Log.d("ZZZ9", getHexValue(isoResC1));
+
+ byte[] isoResC2 = IccTester.getInstance(getApplicationContext()).isoCommand((byte) 0, readCard2);
+ Log.d("ZZZ10", getHexValue(isoResC2));
+
+ byte[] cardBytes = Arrays.copyOfRange(isoResC2, 0, isoResC2.length - 2);
+ Log.d("ZZZ11", getHexValue(cardBytes));
+ Log.d("ZZZ11", new String(cardBytes));
+
+ cardVer = new String(cardBytes);
+
+ nric += getHexValue(cardBytes);
+ //readData();
+
+ } catch (Exception e) {
+ ICCActivity.appendLog(e);
+ }
+
+ IccTester.getInstance(getApplicationContext()).close((byte) 0);
+ IccTester.getInstance(getApplicationContext()).light(false);
+
+ ArrayList info = new ArrayList<>();
+ info.add(nric);
+ info.add(name);
+ info.add(cardVer);
+
+ Message message = Message.obtain();
+ message.what = 0;
+ message.obj = info;
+ handler.sendMessage(message);
+ } else {
+ Message message = Message.obtain();
+ message.what = 1;
+ message.obj = "No card.";
+ handler.sendMessage(message);
+ }
+
+ SystemClock.sleep(500);
+ break;
+ } else {
+ //resString = getResources().getString(R.string.icc_detect_nocard);
+ Message message = Message.obtain();
+ message.what = 1;
+ message.obj = "No card.";
+ handler.sendMessage(message);
+
+ SystemClock.sleep(500);
+ break;
+ }
+ }
+ IccTester.getInstance(ICCActivity.this).light(false);
+ }
+ }
+
+ public class CardDetectedThread extends Thread {
+ @Override
+ public void run() {
+ super.run();
+
+ IccTester.getInstance(ICCActivity.this).light(true);
+
+ while (!Thread.interrupted()) {
+ boolean detect = IccTester.getInstance(ICCActivity.this).detect((byte) 0);
+
+ if (detect) {
+ Message message = Message.obtain();
+ message.what = 0;
+ message.obj = "Remove card";
+ handlerCard.sendMessage(message);
+
+ SystemClock.sleep(500);
+ break;
+ } else {
+ Message message = Message.obtain();
+ message.what = 1;
+ message.obj = "No card";
+ handlerCard.sendMessage(message);
+
+ SystemClock.sleep(500);
+ break;
+ }
+ }
+
+ IccTester.getInstance(ICCActivity.this).light(false);
+ }
+ }
+
+ public class CardInsertedThread extends Thread {
+ @Override
+ public void run() {
+ super.run();
+
+ IccTester.getInstance(ICCActivity.this).light(true);
+
+ while (!Thread.interrupted()) {
+ boolean detect = IccTester.getInstance(ICCActivity.this).detect((byte) 0);
+
+ if (detect) {
+ Message message = Message.obtain();
+ message.what = 0;
+ message.obj = "Detect card";
+ handlerInsertCard.sendMessage(message);
+
+ SystemClock.sleep(500);
+ break;
+ } else {
+ Message message = Message.obtain();
+ message.what = 1;
+ message.obj = "No card";
+ handlerInsertCard.sendMessage(message);
+
+ SystemClock.sleep(500);
+ break;
+ }
+ }
+
+ IccTester.getInstance(ICCActivity.this).light(false);
+ }
+ }
+
+}
diff --git a/app/src/main/java/com/cst/im30/activity/MainActivity.java b/app/src/main/java/com/cst/im30/activity/MainActivity.java
new file mode 100644
index 0000000..86985dc
--- /dev/null
+++ b/app/src/main/java/com/cst/im30/activity/MainActivity.java
@@ -0,0 +1,408 @@
+package com.cst.im30.activity;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.graphics.drawable.AnimationDrawable;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.util.Log;
+import android.view.View;
+import android.widget.ImageView;
+
+import androidx.activity.result.ActivityResultLauncher;
+import androidx.activity.result.contract.ActivityResultContracts;
+import androidx.appcompat.app.AppCompatActivity;
+
+import com.cst.im30.EchoClient;
+import com.cst.im30.R;
+import com.cst.im30.common.CallableInterface;
+import com.cst.im30.common.Constants;
+import com.cst.im30.model.EventLogDetailed;
+import com.cst.im30.service.IDVerificationService;
+import com.daimajia.slider.library.SliderLayout;
+import com.daimajia.slider.library.SliderTypes.BaseSliderView;
+import com.daimajia.slider.library.SliderTypes.TextSliderView;
+
+import net.mrbin99.laravelechoandroid.EchoCallback;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+public class MainActivity extends AppCompatActivity implements CallableInterface {
+ public static final String TAG = "CST-DBG";
+ //Set value to get temp value-RefNum
+ private static String value;
+ //Set value to get temp value-Amount
+ private static String values;
+ ImageView load;
+ AnimationDrawable animationDrawable;
+ private EchoClient paymentClient;
+ private EchoClient icClient;
+ private boolean paymentIsConnected = false;
+ private boolean icIsConnected = false;
+ private String code;
+ private EventLogDetailed eventLogDetailed;
+ private String status;
+
+ //private Toolbar toolbar;
+ private SliderLayout sliderLayout;
+ ActivityResultLauncher icVerificationLauncher = registerForActivityResult(
+ new ActivityResultContracts.StartActivityForResult(),
+ result -> {
+ if (result.getResultCode() == Activity.RESULT_OK) {
+ Intent incomingData = result.getData();
+ if (incomingData != null) {
+ String name = incomingData.getStringExtra("name");
+ String cardNo = incomingData.getStringExtra("cardNo");
+
+ if (verifyIC(name, cardNo)) {
+ Log.d(TAG, "Match");
+ } else {
+ Log.d(TAG, "Fail");
+ resetView();
+ }
+ }
+ } else if (result.getResultCode() == Activity.RESULT_CANCELED) { // Retry Payment
+
+ } else {
+
+ }
+ });
+
+ public static String getValue() {
+ return value;
+ }
+
+ public static String getValues() {
+ return values;
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ sliderLayout = findViewById(R.id.slider_layout_ma);
+ load = findViewById(R.id.loading_image_mt);
+ setupTextSlider();
+
+ initEchoClient();
+ connectEchoClient();
+
+ checkPaymentResult();
+ }
+
+ private void setupTextSlider() {
+ TextSliderView textSliderView = new TextSliderView(this);
+ //textSliderView.description("Welcome to UDC.");
+ textSliderView.image(R.drawable.img_front_1);
+ textSliderView.setScaleType(BaseSliderView.ScaleType.CenterInside);
+ textSliderView.setOnSliderClickListener(slider -> {
+ });
+ textSliderView.bundle(new Bundle());
+ //textSliderView.getBundle().putString("extra", "Welcome to UDC.");
+ sliderLayout.addSlider(textSliderView);
+
+
+
+ /*sliderLayout.setPresetTransformer(SliderLayout.Transformer.Accordion);
+ sliderLayout.setPresetIndicator(SliderLayout.PresetIndicators.Center_Bottom);
+ sliderLayout.setCustomAnimation(new DescriptionAnimation());
+ sliderLayout.setDuration(10000);
+ sliderLayout.addOnPageChangeListener(new ViewPagerEx.OnPageChangeListener() {
+ @Override
+ public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
+ }
+
+ @Override
+ public void onPageSelected(int position) {
+ }
+
+ @Override
+ public void onPageScrollStateChanged(int state) {
+ }
+ });*/
+ }
+
+ private void initViews() {
+ runOnUiThread(() -> {
+ sliderLayout.setVisibility(View.GONE);
+ animationDrawable = (AnimationDrawable) load.getDrawable();
+ animationDrawable.start();
+ load.setVisibility(View.VISIBLE);
+ });
+ }
+
+ private void resetView() {
+ this.code = null;
+ this.eventLogDetailed = null;
+
+ runOnUiThread(() -> {
+ sliderLayout.setVisibility(View.VISIBLE);
+ load.setVisibility(View.GONE);
+ });
+ }
+
+ private void paymentProcess(String payment) {
+
+ //Get the amount from JSON Object
+ String payAmount = "";
+ try {
+ JSONObject jsonObject = new JSONObject(payment).getJSONObject("code");
+ payAmount = jsonObject.getString("payable_amount");
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+
+ //Convert double value of amount from UDC kiosk app to integer 1st
+ double doubleValue = Double.parseDouble(payAmount);
+ int correctAmount = (int) Math.round(doubleValue * 100);
+
+ String pay_amount = "";
+
+ Bundle extra = new Bundle();
+ String pay_function = "01"; //Sale Payment Function
+ pay_amount = String.valueOf(correctAmount);
+ String pay_type = "01"; // Card Payment
+ String pay_camera_mode = "01"; // Internal Device Back/bottom Camera
+ String pay_print_receipt_id = "N"; //Set Requirement
+ String pay_resp_code = "";
+
+ //Pack Request Message
+ extra.putString("pay_function", pay_function);
+ extra.putString("pay_amount", pay_amount);
+ extra.putString("pay_type", pay_type);
+ extra.putString("pay_camera_mode", pay_camera_mode);
+ extra.putString("pay_print_receipt_id", pay_print_receipt_id);
+ extra.putString("pay_resp_code", pay_resp_code);
+
+ //API to call Payment App
+ Intent intent = new Intent("com.revenue.edc.hlb.pro.app2app");
+ intent.putExtras(extra);
+
+ startActivity(intent);
+ }
+
+ private void checkPaymentResult() {
+ //Get status from Status Screen
+ Intent intent = getIntent();
+ Bundle retryInfoGet = intent.getExtras();
+
+ if (retryInfoGet != null) {
+ String referenceSet = (String) retryInfoGet.get("referenceCurrent");
+
+ String statusSet = (String) retryInfoGet.get("statusCurrent");
+ //set status null
+ if (statusSet != null) {
+ status = statusSet;
+ } else {
+ status = "start";
+ }
+
+ String amountSet = (String) retryInfoGet.get("amountCurrent");
+
+ //if payment success
+ if (status.toLowerCase().trim().equals("success")) {
+
+
+ } else if (status.toLowerCase().trim().equals("pending")) {
+
+ initViews();
+
+ //if payment fail
+ /*Button buttonRetryPayment = (Button) findViewById(R.id.button_retry_payment);
+ buttonRetryPayment.getBackground().setColorFilter(Color.CYAN, PorterDuff.Mode.MULTIPLY);
+ buttonRetryPayment.setEnabled(true);
+
+ //Get data from StatusActivty - refNum & amount only
+ //String referenceNumber = StatusActivity.getRefNum();
+ //get and set again
+ *//*textViewViewRespTranslateRefNum = findViewById(R.id.textview_response_translate_refNum);
+ textViewViewRespTranslateStatus = findViewById(R.id.textview_response_translate_status);
+ textViewViewRespTranslateAmount = findViewById(R.id.textview_response_translate_amount);*//*
+
+
+ //String statusTemp = StatusActivity.getStatus();
+ //runOnUiThread(() -> textViewViewRespTranslateStatus.setText(statusSet));
+ //String amount = StatusActivity.getAmount();
+ //runOnUiThread(() -> textViewViewRespTranslateAmount.setText("RM " + amountSet));
+
+ //for checking
+ if (buttonRetryPayment.isEnabled()) {*/
+ //show payment info
+
+ //if user click retry ->disable coz show retry on status activity
+ //buttonRetryPayment.setOnClickListener(v -> retryPayment());
+ //}
+
+ } else {
+ //if return fail
+ //runOnUiThread(() -> textViewViewRespTranslateRefNum.setText("Reference Number..."));
+ //runOnUiThread(() -> textViewViewRespTranslateStatus.setText("Status..."));
+ //runOnUiThread(() -> textViewViewRespTranslateAmount.setText("Amount..."));
+ }
+ }
+ //refreshUI();
+ //if null
+ /*runOnUiThread(() -> textViewViewRespTranslateRefNum.setText("Reference Number..."));
+ runOnUiThread(() -> textViewViewRespTranslateStatus.setText("Status..."));
+ runOnUiThread(() -> textViewViewRespTranslateAmount.setText("Amount..."));*/
+ }
+
+ private void receiveMessage(Object... args) {
+ Log.d(TAG, "receiveMessage");
+
+ //debug error
+ try {
+ //start main activity screen
+ initViews();
+ } catch (Exception ex) {
+ Log.e("Error on contact", ex.getMessage());
+ }
+
+ JSONObject jsonObject = (JSONObject) args[1];
+ String data = null;
+ try {
+ data = jsonObject.getString("data");
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ if (data != null) {
+ //hold the info from UDC kiosk donation received for 5 second then proceed to HLB app
+ final Handler handler = new Handler(Looper.getMainLooper());
+ String finalData = data;
+ handler.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ //Do something after 5000ms = 5 seconds
+ paymentProcess(finalData);
+
+ //clearInfo();
+ }
+ }, 5000);
+
+ }
+
+ }
+
+ private void receiveMessageIC(Object... args) {
+ Log.d(TAG, "receiveMessage");
+
+ //debug error
+ try {
+ //start main activity screen
+ initViews();
+ } catch (Exception ex) {
+ Log.e("Error on contact", ex.getMessage());
+ }
+
+ JSONObject jsonObject = (JSONObject) args[1];
+ String data = null;
+ try {
+ data = jsonObject.getJSONObject("data").getString("code");
+ this.code = data;
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ if (data != null) {
+ IDVerificationService service = new IDVerificationService(this, this);
+ service.getEventLog(code);
+ }
+ }
+
+ //region Echo Client Stuff
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ disconnectEchoClient();
+ }
+
+ private void initEchoClient() {
+ paymentClient = new EchoClient(this, Constants.ECHO_SERVER_URL + ":" + Constants.ECHO_SERVER_PORT);
+ icClient = new EchoClient(this, Constants.ECHO_SERVER_URL + ":" + Constants.ECHO_SERVER_PORT);
+ }
+
+ private void connectEchoClient() {
+ paymentClient.connect(this::onConnectSuccessPayment, this::onConnectFailurePayment);
+ icClient.connect(this::onConnectSuccessIC, this::onConnectFailureIC);
+ }
+
+ private void disconnectEchoClient() {
+ paymentClient.disconnect();
+ paymentIsConnected = false;
+ icClient.disconnect();
+ icIsConnected = false;
+ }
+
+ private void onConnectSuccessPayment(Object[] args) {
+ paymentIsConnected = true;
+ try {
+ String channelID = Constants.SOCKET_PREFIX + Constants.PAYMENT_CHANNEL_ID + Constants.KIOSK_CODE;
+ String eventType = Constants.PAYMENT_EVENT_TYPE;
+ EchoCallback echoCallback = this::receiveMessage;
+ paymentClient.channel(channelID).listen(eventType, echoCallback);
+ } catch (Exception ex) {
+ Log.e("Error on contact", ex.getMessage());
+ }
+ }
+
+ private void onConnectFailurePayment(Object[] args) {
+ paymentIsConnected = false;
+ }
+
+ private void onConnectSuccessIC(Object[] args) {
+ icIsConnected = true;
+ try {
+ String channelID = Constants.SOCKET_PREFIX + Constants.IC_CHANNEL_ID + Constants.KIOSK_CODE;
+ String eventType = Constants.IC_EVENT_TYPE;
+ EchoCallback echoCallback = this::receiveMessageIC;
+ icClient.channel(channelID).listen(eventType, echoCallback);
+ } catch (Exception ex) {
+ Log.e("Error on contact", ex.getMessage());
+ }
+
+ }
+
+ private void onConnectFailureIC(Object[] args) {
+ icIsConnected = false;
+ }
+ //endregion Echo Client Stuff
+
+ @Override
+ public void callBack(String source) {
+
+ }
+
+ @Override
+ public void callBack(String source, Object object) {
+ if (source.equalsIgnoreCase(IDVerificationService.CALLBACK_SUCCESS_GET_EVENT_LOG)) {
+ this.eventLogDetailed = (EventLogDetailed) object;
+ Intent i = new Intent(MainActivity.this, ICCActivity.class);
+ icVerificationLauncher.launch(i);
+ }
+ }
+
+ private boolean verifyIC(String name, String cardNo) {
+ boolean match = true;
+
+ // Verify Card No.
+ String savedNo = this.eventLogDetailed.getDocumentNumber().trim();
+ if (!savedNo.equalsIgnoreCase(cardNo.trim())) {
+ match = false;
+ }
+
+ // Verify Name...
+ String firstName = this.eventLogDetailed.getFirstName().trim().toUpperCase();
+ String lastName = this.eventLogDetailed.getLastName().trim().toUpperCase();
+
+ if (!name.contains(firstName)) {
+ match = false;
+ }
+ if (!name.contains(lastName)) {
+ match = false;
+ }
+
+ return match;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/cst/im30/activity/ResponseActivity.java b/app/src/main/java/com/cst/im30/activity/ResponseActivity.java
new file mode 100644
index 0000000..8e3e329
--- /dev/null
+++ b/app/src/main/java/com/cst/im30/activity/ResponseActivity.java
@@ -0,0 +1,269 @@
+package com.cst.im30.activity;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.Button;
+import android.widget.TextView;
+
+import androidx.appcompat.app.AppCompatActivity;
+
+import com.cst.im30.R;
+import com.cst.im30.common.Parcel;
+import com.cst.im30.entity.Transaction;
+
+public class ResponseActivity extends AppCompatActivity {
+
+ //Set value to get temp value-RefNum
+ private static String vRefNum;
+ //Set value to get temp value-Status
+ private static String vStatus;
+ //Set value to get temp value-Amount
+ private static String vAmount;
+ private TextView txtResponseCode, txtRefNum, txtStatus, txtErrorDesc, txtAmount;
+ private Button buttonOk;
+ private Transaction transaction;
+
+ public static String getRefNum() {
+ return vRefNum;
+ }
+
+ public static String getStatus() {
+ return vStatus;
+ }
+
+ public static String getAmount() {
+ return vAmount;
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_response);
+
+ setTitle("UDC DONATION KIOSK PAYMENT");
+
+ txtResponseCode = findViewById(R.id.title_responses);
+ txtRefNum = findViewById(R.id.title_reference_number);
+ txtStatus = findViewById(R.id.title_status);
+ txtErrorDesc = findViewById(R.id.title_error);
+ txtAmount = findViewById(R.id.title_amount);
+ buttonOk = findViewById(R.id.button_ok_ra);
+
+ //Get data from StatusActivty - refNum & amount only
+ String referenceNumber = MainActivity.getValue();
+ //get and set again
+ vRefNum = referenceNumber;
+ //String referenceNumber = getIntent().getStringExtra("keyrefnumber");
+ //String status = getIntent().getStringExtra("keystatus");
+ //String amount = getIntent().getStringExtra("keyamountpayment");
+ String amount = MainActivity.getValues();
+ vAmount = amount;
+
+ /*//Convert back amount into correct decimal/value
+ int correctAmount = Integer.parseInt(amount) /100;
+
+ String convertedAmount = "";
+ convertedAmount.valueOf(correctAmount);*/
+
+ buttonOk.setVisibility(View.GONE);
+
+ txtRefNum.setText(referenceNumber);
+ //txtStatus.setText(status);
+ txtAmount.setText(amount);
+
+ Intent intent = getIntent();
+ Bundle extra = intent.getExtras();
+
+
+ Parcel parcel = new Parcel(extra.toString());
+ Bundle args = new Bundle();
+ args.putSerializable("events", parcel);
+
+
+ String payRespCode = extra.getString("pay_resp_code");
+
+ String payRespErrorDesc = extra.getString("pay_resp_error_desc");
+
+ String payRespIssuerId = extra.getString("pay_resp_issuer_id");
+ String payFunction = extra.getString("pay_function");
+ String payRespQrTxnId = extra.getString("pay_resp_qr_txn_id");
+ String payRespInvoiceNo = extra.getString("pay_resp_invoice_no");
+ String payRespScheme = extra.getString("pay_resp_scheme");
+ String payRespBatchNo = extra.getString("pay_resp_batch_no");
+ String payRespTxnDate = extra.getString("pay_resp_txn_date");
+ String payRespTxnTime = extra.getString("pay_resp_txn_time");
+ String payPrintReceiptId = extra.getString("pay_print_receipt_id");
+ String payRespQrWalletId = extra.getString("pay_resp_qr_wallet_id");
+ String payRespCardAppCryptogram = extra.getString("pay_resp_card_app_cryptogram");
+ String payRespAppLabel = extra.getString("pay_resp_app_label");
+ String payRespCardRefNum = extra.getString("pay_resp_card_ref_num");
+ String payCameraMode = extra.getString("pay_camera_mode");
+ String payRespCardAuthCode = extra.getString("pay_resp_card_auth_code");
+ String payRespCardAid = extra.getString("pay_resp_card_aid");
+ String payRespHashPan = extra.getString("pay_resp_hash_pan");
+ String payRespMerchInfo = extra.getString("pay_resp_merch_info");
+ String payRespMid = extra.getString("pay_resp_mid");
+ String payRespTid = extra.getString("pay_resp_tid");
+ String payRespTvr = extra.getString("pay_resp_tvr");
+ String payRespCustomerId = extra.getString("pay_resp_customer_id");
+ String payType = extra.getString("pay_type");
+ String payRespTraceNo = extra.getString("pay_resp_trace_no");
+ String payRespCvmDesc = extra.getString("pay_resp_cvm_desc");
+ String payAddAmount = extra.getString("pay_add_amount");
+ String payRespCardNo = extra.getString("pay_resp_card_no");
+ String payAmount = extra.getString("pay_amount");
+
+ //get all HLB response & convert it to string for inserting API column(params_response)
+ //String allHLBresponse = {"id":13,"merchant_code":"MER0001","terminal_code":"TER001","reference_number":"PAY0021","response_code":"00","payment_type":"01","amount":"1.00","payment_function":"01","payment_camera_mode":null,"status":"success","created_at":"2021-08-23T03:19:30.000000Z","updated_at":"2021-08-23T06:29:40.000000Z"};
+ String allHLBresponse =
+ "{pay_resp_issuer_id=" + payRespIssuerId + "," +
+ "pay_resp_error_desc=" + payRespErrorDesc + "," +
+ "pay_function=" + payFunction + "," +
+ "pay_resp_qr_txn_id=" + payRespQrTxnId + "," +
+ "pay_resp_invoice_no=" + payRespInvoiceNo + "," +
+ "pay_resp_scheme=" + payRespScheme + "," +
+ "pay_resp_batch_no=" + payRespBatchNo + "," +
+ "pay_resp_txn_date=" + payRespTxnDate + "," +
+ "pay_resp_txn_time=" + payRespTxnTime + "," +
+ "pay_print_receipt_id=" + payPrintReceiptId + "," +
+ "pay_resp_qr_wallet_id=" + payRespQrWalletId + "," +
+ "pay_resp_code=" + payRespCode + "," +
+ "pay_resp_card_app_cryptogram=" + payRespCardAppCryptogram + "," +
+ "pay_resp_app_label=" + payRespAppLabel + "," +
+ "pay_resp_card_ref_num=" + payRespCardRefNum + "," +
+ "pay_camera_mode=" + payCameraMode + "," +
+ "pay_resp_card_auth_code=" + payRespCardAuthCode + "," +
+ "pay_resp_card_aid=" + payRespCardAid + "," +
+ "pay_resp_hash_pan=" + payRespHashPan + "," +
+ "pay_resp_merch_info=" + payRespMerchInfo + "," +
+ "pay_resp_mid=" + payRespMid + "," +
+ "pay_resp_tid=" + payRespTid + "," +
+ "pay_resp_tvr=" + payRespTvr + "," +
+ "pay_resp_customer_id=" + payRespCustomerId + "," +
+ "pay_type=" + payType + "," +
+ "pay_resp_trace_no=" + payRespTraceNo + "," +
+ "pay_resp_cvm_desc=" + payRespCvmDesc + "," +
+ "pay_add_amount=" + payAddAmount + "," +
+ "pay_resp_card_no=" + payRespCardNo + "," +
+ "pay_amount=" + payAmount + "}";
+
+ //Log.d("TAG", payRespCode);
+ txtResponseCode.setText(payRespCode);
+ txtErrorDesc.setText(payRespErrorDesc);
+
+ //set status from response to human readable language/meaning
+ String resultPayRespCode = "";
+ String resultPayRespCodeStatus = "";
+ if (payRespCode.equals("00") && payRespErrorDesc.toLowerCase().trim().equals("approved")) {
+ resultPayRespCode = "Transaction Approved";
+ resultPayRespCodeStatus = "success";
+
+ } else if (payRespCode.equals("00") && payRespErrorDesc.toLowerCase().trim().equals("declined")) {
+ resultPayRespCode = "Transaction Approved but Declined #ErrorDesc";
+ resultPayRespCodeStatus = "fail"; //or declined
+
+ } else if (payRespCode.equals("ND")) {
+ resultPayRespCode = "User cancel/No Host Response";
+ resultPayRespCodeStatus = "fail";
+
+ } else {
+ resultPayRespCode = "Transaction Decline";
+ resultPayRespCodeStatus = "fail";
+
+ }
+
+ txtStatus.setText(resultPayRespCode);
+
+ String finalResultPayRespCode = resultPayRespCode;
+ String finalResultPayRespCodeStatus = resultPayRespCodeStatus;
+ vStatus = finalResultPayRespCodeStatus;
+
+ //TODO: Send all response to Status Activity, then update/send all the info to API to be inserted in UDC KIOSK
+
+
+ String refNum = referenceNumber;
+ String finalAmount = amount;
+
+ //directly to status screen
+ //get infos from HLB and send to status activity
+ showStatusScreen(refNum, finalResultPayRespCodeStatus, finalAmount, payRespCode, payRespErrorDesc, payRespIssuerId,
+ payFunction, payRespQrTxnId, payRespInvoiceNo, payRespScheme, payRespBatchNo, payRespTxnDate, payRespTxnTime,
+ payPrintReceiptId, payRespQrWalletId, payRespCardAppCryptogram, payRespAppLabel, payRespCardRefNum,
+ payCameraMode, payRespCardAuthCode, payRespCardAid, payRespHashPan, payRespMerchInfo, payRespMid, payRespTid,
+ payRespTvr, payRespCustomerId, payType, payRespTraceNo, payRespCvmDesc, payAddAmount, payRespCardNo, payAmount, allHLBresponse);
+
+ //get infos from HLB and send to status activity
+ /*sendHLBPaymentResponse(payRespCode, payRespErrorDesc, payRespIssuerId, payFunction, payRespQrTxnId, payRespInvoiceNo,
+ payRespScheme, payRespBatchNo, payRespTxnDate, payRespTxnTime, payPrintReceiptId, payRespQrWalletId,
+ payRespCardAppCryptogram, payRespAppLabel, payRespCardRefNum, payCameraMode, payRespCardAuthCode, payRespCardAid,
+ payRespHashPan, payRespMerchInfo, payRespMid, payRespTid, payRespTvr, payRespCustomerId, payType, payRespTraceNo,
+ payRespCvmDesc, payAddAmount, payRespCardNo, payAmount);*/
+
+
+ }
+
+
+ private void showStatusScreen(String refNumTransaction, String statusTransaction, String amountTransaction,
+ String payRespCodeTransaction, String payRespErrorDescTransaction,
+ String payRespIssuerIdTransaction, String payFunctionTransaction,
+ String payRespQrTxnIdTransaction, String payRespInvoiceNoTransaction,
+ String payRespSchemeTransaction, String payRespBatchNoTransaction,
+ String payRespTxnDateTransaction, String payRespTxnTimeTransaction,
+ String payPrintReceiptIdTransaction, String payRespQrWalletIdTransaction,
+ String payRespCardAppCryptogramTransaction, String payRespAppLabelTransaction,
+ String payRespCardRefNumTransaction, String payCameraModeTransaction,
+ String payRespCardAuthCodeTransaction, String payRespCardAidTransaction,
+ String payRespHashPanTransaction, String payRespMerchInfoTransaction,
+ String payRespMidTransaction, String payRespTidTransaction, String payRespTvrTransaction,
+ String payRespCustomerIdTransaction, String payTypeTransaction,
+ String payRespTraceNoTransaction, String payRespCvmDescTransaction,
+ String payAddAmountTransaction, String payRespCardNoTransaction, String payAmountTransaction,
+ String allHLBresponse) {
+
+ Intent intent = new Intent(ResponseActivity.this, StatusActivity.class);
+ //intent.putExtra("transaction", transaction);
+ intent.putExtra("referenceNumTransaction", refNumTransaction);
+ intent.putExtra("statusTransaction", statusTransaction);
+ intent.putExtra("amountTransaction", amountTransaction); //only this info right now that is important to show (value) at status screen
+ //response from APP2APP HLB
+ intent.putExtra("hlbResponse", allHLBresponse);
+ intent.putExtra("payRespCodeTransaction", payRespCodeTransaction);
+ intent.putExtra("payRespErrorDescTransaction", payRespErrorDescTransaction);
+ intent.putExtra("payRespIssuerIdTransaction", payRespIssuerIdTransaction);
+ intent.putExtra("payFunctionTransaction", payFunctionTransaction);
+ intent.putExtra("payRespQrTxnIdTransaction", payRespQrTxnIdTransaction);
+ intent.putExtra("payRespInvoiceNoTransaction", payRespInvoiceNoTransaction);
+ intent.putExtra("payRespSchemeTransaction", payRespSchemeTransaction);
+ intent.putExtra("payRespBatchNoTransaction", payRespBatchNoTransaction);
+ intent.putExtra("payRespTxnDateTransaction", payRespTxnDateTransaction);
+ intent.putExtra("payRespTxnTimeTransaction", payRespTxnTimeTransaction);
+ intent.putExtra("payPrintReceiptIdTransaction", payPrintReceiptIdTransaction);
+ intent.putExtra("payRespQrWalletIdTransaction", payRespQrWalletIdTransaction);
+ intent.putExtra("payRespCardAppCryptogramTransaction", payRespCardAppCryptogramTransaction);
+ intent.putExtra("payRespAppLabelTransaction", payRespAppLabelTransaction);
+ intent.putExtra("payRespCardRefNumTransaction", payRespCardRefNumTransaction);
+ intent.putExtra("payCameraModeTransaction", payCameraModeTransaction);
+ intent.putExtra("payRespCardAuthCodeTransaction", payRespCardAuthCodeTransaction);
+ intent.putExtra("payRespCardAidTransaction", payRespCardAidTransaction);
+ intent.putExtra("payRespHashPanTransaction", payRespHashPanTransaction);
+ intent.putExtra("payRespMerchInfoTransaction", payRespMerchInfoTransaction);
+ intent.putExtra("payRespMidTransaction", payRespMidTransaction);
+ intent.putExtra("payRespTidTransaction", payRespTidTransaction);
+ intent.putExtra("payRespTvrTransaction", payRespTvrTransaction);
+ intent.putExtra("payRespCustomerIdTransaction", payRespCustomerIdTransaction);
+ intent.putExtra("payTypeTransaction", payTypeTransaction);
+ intent.putExtra("payRespTraceNoTransaction", payRespTraceNoTransaction);
+ intent.putExtra("payRespCvmDescTransaction", payRespCvmDescTransaction);
+ intent.putExtra("payAddAmountTransaction", payAddAmountTransaction);
+ intent.putExtra("payRespCardNoTransaction", payRespCardNoTransaction);
+ intent.putExtra("payAmountTransaction", payAmountTransaction);
+
+ startActivity(intent);
+ setResult(RESULT_OK);
+ finish();
+
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/cst/im30/activity/SettingActivity.java b/app/src/main/java/com/cst/im30/activity/SettingActivity.java
new file mode 100644
index 0000000..10cba80
--- /dev/null
+++ b/app/src/main/java/com/cst/im30/activity/SettingActivity.java
@@ -0,0 +1,228 @@
+package com.cst.im30.activity;
+
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.text.method.ScrollingMovementMethod;
+import android.util.Log;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.appcompat.widget.Toolbar;
+import androidx.core.content.ContextCompat;
+
+import com.cst.im30.EchoClientSetting;
+import com.cst.im30.R;
+import com.cst.im30.common.Constants;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+public class SettingActivity extends AppCompatActivity {
+
+ public static final String TAG = "SettingActivity";
+
+ private EchoClientSetting echoClient;
+
+ private TextView textViewResponse,
+ textViewConnectionStatus;
+
+ private Button buttonConnect,
+ buttonCheckConnectionStatus;
+
+ private boolean isConnected;
+
+ private Toolbar toolbar;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ Log.d(TAG, "onCreate");
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_setting);
+
+ toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
+
+ TextView titleMain = findViewById(R.id.title_main_st);
+ ImageView returnIcon = findViewById(R.id.return_icon_st);
+
+ titleMain.setText("Setting");
+
+ returnIcon.setOnClickListener(v -> onBackPressed());
+
+ initVariables();
+ initViews();
+
+ initEchoClient();
+ connectEchoClient();
+
+ }
+
+ private void initVariables() {
+ isConnected = false;
+ }
+
+ private void initViews() {
+ textViewConnectionStatus = findViewById(R.id.textview_connection_status_st);
+
+ textViewResponse = findViewById(R.id.textview_response_st);
+ textViewResponse.setMovementMethod(new ScrollingMovementMethod());
+
+ buttonConnect = findViewById(R.id.button_connect_st);
+
+ buttonCheckConnectionStatus = findViewById(R.id.button_check_connection_status_st);
+ buttonCheckConnectionStatus.setOnClickListener(v -> buttonCheckConnectionStatusClicked());
+
+ //buttonTriggerCheckPreviousPayment = findViewById(R.id.button_previous_payment);
+ //buttonTriggerCheckPreviousPayment.setOnClickListener(v -> receivedPaymentResult());
+ //buttonTriggerLaunch.setOnClickListener(v -> buttonTriggerPaymentClicked("payment"));
+
+ }
+
+ private void initEchoClient() {
+ Log.d(TAG, "initEchoClient");
+
+ // Create the client
+ echoClient = new EchoClientSetting(
+ this,
+ Constants.ECHO_SERVER_URL + ":" + Constants.ECHO_SERVER_PORT
+ );
+ }
+
+ private void connectEchoClient() {
+ Log.d(TAG, "connectEchoClient");
+
+ // Connect and supply callbacks
+ echoClient.connect(
+ this::onConnectSuccess,
+ this::onConnectFailure
+ );
+ }
+
+ private void disconnectEchoClient() {
+ Log.d(TAG, "disconnectEchoClient");
+
+ echoClient.disconnect();
+
+ isConnected = false;
+
+ runOnUiThread(() -> Toast.makeText(SettingActivity.this, "Disconnected!", Toast.LENGTH_SHORT).show());
+
+ refreshUI();
+ }
+
+ private void refreshUI() {
+ Log.d(TAG, "refreshUI");
+
+ updateConnectionStatus();
+ updateConnectButton();
+ }
+
+ private void updateConnectionStatus() {
+ Log.d(TAG, "updateConnectionStatus");
+
+ if (isConnected) {
+ Log.d(TAG, "Status: Connected");
+ runOnUiThread(() -> {
+ textViewConnectionStatus.setText(R.string.status_connected);
+ textViewConnectionStatus.setBackgroundColor(ContextCompat.getColor(SettingActivity.this, R.color.green));
+ });
+ } else {
+ Log.d(TAG, "Status: Not Connected");
+ runOnUiThread(() -> {
+ textViewConnectionStatus.setText(R.string.status_not_connected);
+ textViewConnectionStatus.setBackgroundColor(ContextCompat.getColor(SettingActivity.this, R.color.red));
+ });
+ }
+ }
+
+ private void updateConnectButton() {
+ Log.d(TAG, "updateConnectButton");
+
+ if (!isConnected) {
+ runOnUiThread(() -> {
+ buttonConnect.setText(R.string.button_connect);
+ buttonConnect.setOnClickListener(v -> connectEchoClient());
+ });
+ } else {
+ runOnUiThread(() -> {
+ buttonConnect.setText(R.string.button_disconnect);
+ buttonConnect.setOnClickListener(v -> disconnectEchoClient());
+ });
+ }
+ }
+
+ private void buttonCheckConnectionStatusClicked() {
+ if (echoClient.isConnected()) {
+ runOnUiThread(() -> Toast.makeText(SettingActivity.this, "Yes, it is connected.", Toast.LENGTH_SHORT).show());
+ } else {
+ runOnUiThread(() -> Toast.makeText(SettingActivity.this, "No, it doesn't seem to be connected.", Toast.LENGTH_SHORT).show());
+ }
+ }
+
+ // Connect Success
+ private void onConnectSuccess(Object[] args) {
+ Log.d(TAG, "onConnectSuccess");
+
+ isConnected = true;
+ refreshUI();
+
+ runOnUiThread(() -> Toast.makeText(SettingActivity.this, "Connected!", Toast.LENGTH_SHORT).show());
+
+ echoClient.channel(Constants.PAYMENT_CHANNEL_ID + Constants.KIOSK_CODE)
+ .listen(Constants.PAYMENT_EVENT_TYPE, this::receiveMessage);
+
+ }
+
+ // Connect Failure/Error
+ private void onConnectFailure(Object[] args) {
+ Log.d(TAG, "onConnectFailure");
+
+ isConnected = false;
+ refreshUI();
+
+ runOnUiThread(() -> Toast.makeText(SettingActivity.this, "Failed to Connect!", Toast.LENGTH_SHORT).show());
+ }
+
+ private void receiveMessage(Object... args) {
+ Log.d(TAG, "receiveMessage");
+ JSONObject jsonObject = (JSONObject) args[1];
+ String data = null;
+ try {
+ data = jsonObject.getString("data");
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ if (data != null) {
+ String finalData = data;
+
+ // Changing UI Elements must be on UI/Main Thread
+ runOnUiThread(() -> textViewResponse.setText(finalData));
+
+ final Handler handler = new Handler(Looper.getMainLooper());
+ handler.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ //Do something after 5000ms = 5 seconds
+ //clearInfo();
+ }
+ }, 5000);
+
+ //buttonTriggerPayment(finalData);
+
+ }
+ }
+
+
+ @Override
+ public void onDestroy() {
+ Log.d(TAG, "onDestroy");
+ super.onDestroy();
+
+ //disconnectEchoClient();
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/cst/im30/activity/StatusActivity.java b/app/src/main/java/com/cst/im30/activity/StatusActivity.java
new file mode 100644
index 0000000..1c8b21a
--- /dev/null
+++ b/app/src/main/java/com/cst/im30/activity/StatusActivity.java
@@ -0,0 +1,624 @@
+package com.cst.im30.activity;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import androidx.appcompat.app.AppCompatActivity;
+
+import com.bumptech.glide.Glide;
+import com.cst.im30.R;
+import com.cst.im30.entity.Transaction;
+import com.cst.im30.retrofit.RetrofitAPICollection;
+import com.cst.im30.retrofit.RetrofitClient;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.math.BigInteger;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+import retrofit2.Call;
+import retrofit2.Callback;
+import retrofit2.Response;
+import retrofit2.Retrofit;
+import retrofit2.converter.gson.GsonConverterFactory;
+
+public class StatusActivity extends AppCompatActivity {
+
+ //Set value to get temp value-RefNum
+ private static String vRefNum;
+ //Set value to get temp value-Status
+ private static String vStatus;
+ //Set value to get temp value-Amount
+ private static String vAmount;
+ private Transaction transaction;
+ private Button buttonDonationSuccess, buttonRetry, buttonNoRetry;
+ //private Transaction transaction;
+ private TextView textStatus, textInfo, textAmount;
+ private ImageView imageStatus;
+ private String status, responseCode, responseDesc, referenceNum, amountTransaction;
+
+ public static String getRefNum() {
+ return vRefNum;
+ }
+
+ public static String getStatus() {
+ return vStatus;
+ }
+
+ public static String getAmount() {
+ return vAmount;
+ }
+
+ public static void showFinishMessage(final Context context, String title, String message) {
+ AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(context);
+ LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ View dialogView = inflater.inflate(R.layout.pop_up_message_no_option, null);
+
+ TextView textTitle = dialogView.findViewById(R.id.text_title_pop_up_message_no_option);
+ TextView textMessage = dialogView.findViewById(R.id.text_message_pop_up_message_no_option);
+ Button buttonOk = dialogView.findViewById(R.id.button_ok_pop_up_message_no_option);
+
+ textTitle.setText(title);
+ textMessage.setText(message);
+
+ dialogBuilder.setCancelable(false);
+ dialogBuilder.setView(dialogView);
+
+ final AlertDialog alertDialogFinishMessage = dialogBuilder.create();
+ alertDialogFinishMessage.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
+ alertDialogFinishMessage.show();
+
+ buttonOk.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ alertDialogFinishMessage.dismiss();
+ ((Activity) context).finish();
+
+ }
+ });
+ }
+
+ private static String encrytThisString(String input) {
+
+ try {
+ // getInstance() method is called with algorithm SHA-512
+ MessageDigest md = MessageDigest.getInstance("SHA-512");
+
+ // digest() method is called
+ // to calculate message digest of the input string
+ // returned as array of byte
+ byte[] messageDigest = md.digest(input.getBytes());
+
+ // Convert byte array into signum representation
+ BigInteger no = new BigInteger(1, messageDigest);
+
+ // Convert message digest into hex value
+ String hashtext = no.toString(16);
+
+ // Add preceding 0s to make it 32 bit
+ while (hashtext.length() < 32) {
+ hashtext = "0" + hashtext;
+ }
+
+ // return the HashText
+ return hashtext;
+ } // For specifying wrong message digest algorithms
+ catch (NoSuchAlgorithmException e) {
+ throw new RuntimeException(e);
+ }
+
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_status);
+
+ /*try {
+ transaction = (Transaction) getIntent().getSerializableExtra("transaction");
+ } catch (Exception e) {
+ //Bugsnag.notify(e);
+ }*/
+
+ buttonDonationSuccess = findViewById(R.id.button_ok_donation_sta);
+ buttonRetry = findViewById(R.id.button_pay_again_sta);
+ buttonNoRetry = findViewById(R.id.button_no_pay_again_sta);
+ textStatus = findViewById(R.id.text_status_sta);
+ textInfo = findViewById(R.id.text_info_sta);
+ textAmount = findViewById(R.id.text_info_amount_sta);
+ imageStatus = findViewById(R.id.image_status_sta);
+
+ //Get data from StatusActivty - refNum & amount only
+ String referenceNumber = ResponseActivity.getRefNum();
+ //get and set again
+ vRefNum = referenceNumber;
+ String statusTemp = ResponseActivity.getStatus();
+ vStatus = statusTemp;
+ String amount = ResponseActivity.getAmount();
+ vAmount = amount;
+
+
+ //Get status from Response Screen
+ Intent intentRefNum = getIntent();
+ Bundle refNumGet = intentRefNum.getExtras();
+ if (refNumGet != null) {
+ String refNumSet = (String) refNumGet.get("referenceNumTransaction");
+ referenceNum = refNumSet;
+ }
+
+ /*Intent intentSign = getIntent();
+ Bundle signGet = intentSign.getExtras();
+ String */
+
+ Intent intentStatus = getIntent();
+ Bundle statusGet = intentStatus.getExtras();
+ if (statusGet != null) {
+ String statusSet = (String) statusGet.get("statusTransaction");
+ status = statusSet;
+ }
+
+ Intent intentAmount = getIntent();
+ Bundle amountGet = intentAmount.getExtras();
+ if (amountGet != null) {
+ String amountSet = (String) amountGet.get("amountTransaction");
+ amountTransaction = amountSet;
+ }
+
+ //Get HLB response from Response Activity
+ Intent intentResponse = getIntent();
+ Bundle extra = intentResponse.getExtras();
+ String payRespCodeTransaction = extra.getString("payRespCodeTransaction");
+ //transaction.setResponseCode(payRespCodeTransaction);
+ //all HLB response
+ String getAllHLBresponse = extra.getString("hlbResponse");
+ //String payResponseCode = transaction.getResponseCode();
+ String payRespErrorDescTransaction = extra.getString("payRespErrorDescTransaction");
+ String payRespIssuerIdTransaction = extra.getString("payRespIssuerIdTransaction");
+ String payFunctionTransaction = extra.getString("payFunctionTransaction");
+ //String payFunction = transaction.setFunction(payFunctionTransaction);
+ String payRespQrTxnIdTransaction = extra.getString("payRespQrTxnIdTransaction");
+ String payRespInvoiceNoTransaction = extra.getString("payRespInvoiceNoTransaction");
+ String payRespSchemeTransaction = extra.getString("payRespSchemeTransaction");
+ String payRespBatchNoTransaction = extra.getString("payRespBatchNoTransaction");
+ String payRespTxnDateTransaction = extra.getString("payRespTxnDateTransaction");
+ String payRespTxnTimeTransaction = extra.getString("payRespTxnTimeTransaction");
+ String payPrintReceiptIdTransaction = extra.getString("payPrintReceiptIdTransaction");
+ String payRespQrWalletIdTransaction = extra.getString("payRespQrWalletIdTransaction");
+ String payRespCardAppCryptogramTransaction = extra.getString("payRespCardAppCryptogramTransaction");
+ String payRespAppLabelTransaction = extra.getString("payRespAppLabelTransaction");
+ String payRespCardRefNumTransaction = extra.getString("payRespCardRefNumTransaction");
+ String payCameraModeTransaction = extra.getString("payCameraModeTransaction");
+ //String payCameraMode = transaction.setCameraMode(payCameraModeTransaction);
+ String payRespCardAuthCodeTransaction = extra.getString("payRespCardAuthCodeTransaction");
+ String payRespCardAidTransaction = extra.getString("payRespCardAidTransaction");
+ String payRespHashPanTransaction = extra.getString("payRespHashPanTransaction");
+ String payRespMerchInfoTransaction = extra.getString("payRespMerchInfoTransaction");
+ String payRespMidTransaction = extra.getString("payRespMidTransaction");
+ String payRespTidTransaction = extra.getString("payRespTidTransaction");
+ String payRespTvrTransaction = extra.getString("payRespTvrTransaction");
+ String payRespCustomerIdTransaction = extra.getString("payRespCustomerIdTransaction");
+ String payTypeTransaction = extra.getString("payTypeTransaction");
+ //String payType = transaction.setType(payTypeTransaction);
+ String payRespTraceNoTransaction = extra.getString("payRespTraceNoTransaction");
+ String payRespCvmDescTransaction = extra.getString("payRespCvmDescTransaction");
+ String payAddAmountTransaction = extra.getString("payAddAmountTransaction");
+ String payRespCardNoTransaction = extra.getString("payRespCardNoTransaction");
+ String payAmountTransaction = extra.getString("payAmountTransaction");
+
+ String merchanCode = "MER0001";
+ //String terminalCode = transaction.getTid();
+ String secretKey = "Uthos^eY5pfO";
+ //Signature=merchant_code+secret_key_reference_number+amount+payment_type ->23/08/2021-requery
+ //String encryptedSign = merchanCode + secretKey + referenceNum + amount + payTypeTransaction;
+ //String encryptedSignValueRequery = encrytThisString(encryptedSign);
+ //Signature = merchant_code+secret_key+reference_number+amount+response_code ->23/08/2021-update
+ //String encryptedSigns = merchanCode + secretKey + referenceNum + amount + payRespCodeTransaction;
+ //String encryptedSignValueUpdate = encrytThisString(encryptedSigns);
+ //String paramsResponse = "{\"id\":13,\"merchant_code\":\"MER0001\"}";
+ //String paramsResponse = {"id":13,"merchant_code":"MER0001","terminal_code":"TER001","reference_number":"PAY0021","response_code":"00","payment_type":"01","amount":"1.00","payment_function":"01","payment_camera_mode":null,"status":"success","created_at":"2021-08-23T03:19:30.000000Z","updated_at":"2021-08-23T06:29:40.000000Z"};
+ String paramsResponse = getAllHLBresponse;
+
+
+ //if (status.toLowerCase().trim().equals("success") && transaction.getType().toLowerCase().contains("sale")) {
+ if (status.toLowerCase().trim().equals("success")) {
+ textStatus.setText(getResources().getString(R.string.txt_success_status));
+ textInfo.setText(getResources().getString(R.string.txt_info_status));
+ textAmount.setText("Donation Amount: " + "RM " + amount);
+ Glide.with(StatusActivity.this).asBitmap().load(R.drawable.ic_status_success_fancy).into(imageStatus);
+
+ /*//direct update the status to server
+ String refNum = referenceNum;
+ String finalResultPayRespCodeStatus = status;
+ String finalAmount = amountTransaction;
+ //String paymentTypeTransaction = payTypeTransaction;
+ //String paymentFunctionTransaction = payFunctionTransaction;
+ //String paymentCameraMode = payCameraModeTransaction;
+ //TODO: change this hardcoded value later
+ //String signValue = "testSignature";
+ //String paramResponse = "HLB params here..";
+ //JSONObject obj = ((Parcel) ((Bundle) getArguments()).getSerializable("events")).getObj();
+ //String paramResponse = obj.toString();
+
+ String merchanCode = "MER0001";
+ //String terminalCode = transaction.getTid();
+ String secretKey = "Uthos^eY5pfO";
+ //String finalStatus = "fail";
+ //String amount = realAmount;
+ //String responseCode = transaction.getResponseCode();
+ //Signature = merchant_code+secret_key+reference_number+amount+response_code ->23/08/2021-update
+ String encryptedSign = merchanCode + secretKey + refNum + amount + payRespCodeTransaction;
+ String encryptedSignValueUpdate = encrytThisString(encryptedSign);
+ String paramsResponse = "{\"id\":13,\"merchant_code\":\"MER0001\"}";*/
+
+ //Signature = merchant_code+secret_key+reference_number+amount+response_code ->23/08/2021-update
+ String encryptedSigns = merchanCode + secretKey + referenceNum + amount + payRespCodeTransaction;
+ String encryptedSignValueUpdate = encrytThisString(encryptedSigns);
+
+ //hide button so user won't need to interact with it
+ //buttonDonationSuccess.setVisibility(View.VISIBLE);
+ buttonDonationSuccess.setVisibility(View.GONE);
+ buttonRetry.setVisibility(View.GONE);
+ buttonNoRetry.setVisibility(View.GONE);
+
+ //hold the info from UDC kiosk donation received for 5 second then proceed to HLB app
+ final Handler handler = new Handler(Looper.getMainLooper());
+ handler.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ //Do something after 5000ms = 5 seconds
+ //update Status success to server
+ //updateResponseToApi(String referenceNumber, String status, String merchantCode, String amount, String responseCode,
+ // String encryptedSignValueUpdate, String paramsResponse)
+ updateResponseFromhlb(referenceNum, status, merchanCode, amountTransaction, payRespCodeTransaction,
+ encryptedSignValueUpdate, paramsResponse);
+ //updateResponseFromhlb(payment);
+
+ /*{ //current jSON at API side -UPDATE
+ "id": 11,
+ "reference_number": "PAY001",
+ "payment_type": null,
+ "payment_function": null,
+ "payment_camera_mode": null,
+ "signature": null,
+ "amount": "1.00",
+ "status": "success",
+ "params_response": null,
+ "created_at": "2021-06-20T13:32:40.000000Z",
+ "updated_at": "2021-08-19T00:32:17.000000Z"
+ }*/
+
+ Intent i = new Intent(StatusActivity.this, MainActivity.class);
+ i.putExtra("statusCurrent", status);
+ i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
+ startActivity(i);
+ }
+ }, 5000);
+
+ } else {
+ textStatus.setText(getResources().getString(R.string.txt_fail_status));
+ textInfo.setText(getResources().getString(R.string.txt_fail_info_status));
+ textAmount.setText("Donation Amount: " + "RM " + amount);
+ Glide.with(StatusActivity.this).asBitmap().load(R.drawable.ic_status_fail_fancy).into(imageStatus);
+
+ buttonDonationSuccess.setVisibility(View.GONE);
+ buttonRetry.setVisibility(View.VISIBLE);
+ buttonNoRetry.setVisibility(View.VISIBLE);
+
+ }
+
+ //button ok ->hide because useless/ no need user to press
+ /*buttonDonationSuccess.setOnClickListener(view -> {
+
+ String refNum = referenceNum;
+ String finalResultPayRespCodeStatus = status;
+ String finalAmount = amountTransaction;
+
+ //update Status to server
+ updateResponseFromhlb(refNum, finalResultPayRespCodeStatus, finalAmount);
+
+
+ Intent i = new Intent(StatusActivity.this, MainActivity.class);
+ i.putExtra("statusCurrent", finalResultPayRespCodeStatus);
+ i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
+ startActivity(i);
+ });*/
+
+ //button no retry pay again
+ buttonNoRetry.setOnClickListener(view -> {
+
+ String refNum = referenceNum;
+ String finalResultPayRespCodeStatus = status;
+ String finalAmount = amountTransaction;
+ String paymentTypeTransaction = payTypeTransaction;
+ String paymentFunctionTransaction = payFunctionTransaction;
+ String paymentCameraMode = payCameraModeTransaction;
+
+ //Signature = merchant_code+secret_key+reference_number+amount+response_code ->23/08/2021-update
+ String encryptedSigns = merchanCode + secretKey + referenceNum + amount + payRespCodeTransaction;
+ String encryptedSignValueUpdate = encrytThisString(encryptedSigns);
+
+ //updateResponseToApi(String referenceNumber, String status, String merchantCode, String amount, String responseCode,
+ // String encryptedSignValueUpdate, String paramsResponse)
+ //update Status = FAIL to server
+ //updateResponseToApi(String referenceNumber, String status, String merchantCode, String amount, String responseCode,
+ // String encryptedSignValueUpdate, String paramsResponse)
+ updateResponseFromhlb(referenceNum, finalResultPayRespCodeStatus, merchanCode, finalAmount, payRespCodeTransaction,
+ encryptedSignValueUpdate, paramsResponse);
+
+ /*updateResponseFromhlb(refNum, paymentTypeTransaction, paymentFunctionTransaction,
+ paymentCameraMode, signValue, finalAmount, finalResultPayRespCodeStatus, paramResponse);*/
+
+ Intent intent = new Intent(StatusActivity.this, MainActivity.class);
+ intent.putExtra("statusCurrent", finalResultPayRespCodeStatus);
+ intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
+ startActivity(intent);
+
+ });
+
+ //button retry
+ //buttonRetry.setOnClickListener(view -> buttonRetryPayment(status));
+ buttonRetry.setOnClickListener(view -> {
+
+ String refNum = referenceNum;
+ String finalResultPayRespCodeStatus = "pending";
+ vStatus = finalResultPayRespCodeStatus;
+ String finalAmount = amountTransaction;
+
+ //Signature=merchant_code+secret_key_reference_number+amount+payment_type ->23/08/2021-requery
+ String encryptedSign = merchanCode + secretKey + referenceNum + amount + payTypeTransaction;
+ String encryptedSignValueRequery = encrytThisString(encryptedSign);
+
+ //Signature = merchant_code+secret_key+reference_number+amount+response_code ->23/08/2021-update
+ String encryptedSigns = merchanCode + secretKey + referenceNum + amount + payRespCodeTransaction;
+ String encryptedSignValueUpdate = encrytThisString(encryptedSigns);
+
+
+ //update Status to server ->no need to update 1st, just retry the payment
+ //updateResponseFromhlb(refNum, finalResultPayRespCodeStatus, finalAmount);
+
+ //check the status from server 1st, if pending proceed, if fail sho success show something
+ //requery + update API
+ checkStatusPayment(refNum, merchanCode, payTypeTransaction, finalAmount, encryptedSignValueRequery,
+ paramsResponse, payRespCodeTransaction, encryptedSignValueUpdate);
+
+ /*//String transactionStatus = status; ->pending
+ String transactionReference = refNum;
+ String transactionStatus = finalResultPayRespCodeStatus;
+ String transactionAmount = finalAmount;
+
+ retryPayment(finalAmount);*/
+
+ /*Intent intents = new Intent(StatusActivity.this, MainActivity.class);
+ intents.putExtra("referenceCurrent", transactionReference);
+ intents.putExtra("statusCurrent", transactionStatus);
+ intents.putExtra("amountCurrent", transactionAmount);
+ intents.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
+ startActivity(intents);*/
+
+ });
+
+
+ }
+
+ //refNum, merchanCode, payTypeTransaction, finalAmount, encryptedSignValueRequery
+ private void checkStatusPayment(String referenceNumber, String merchanCode, String payType, String amount, String encryptedSignValueRequery,
+ String paramResponse, String payRespCode, String encryptedSignValueUpdate) {
+
+ //TODO: Please cleanup and fix afterwards
+ String tempHostUrl = "http://udcsys-api-build.testpigeon.net";
+ String buildToken = "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiIxIiwianRpIjoiOTA2ZTNkN2VmNmZkNmNhZjVjYTVkNWEzYjI5ZDRiMWYxZjlmYTc4ZDcxYzYyNGE0N2FmMTYwMGQzZWY3ZGU5OGE5MGY2NzJlNzE4NmVmZGIiLCJpYXQiOjE2MDg1MzYyMTMsIm5iZiI6MTYwODUzNjIxMywiZXhwIjoxNjQwMDcyMjEzLCJzdWIiOiIxMSIsInNjb3BlcyI6W119.i2jDd1Zux2UkoLhzif762ghsJFhQ32Gk6g0Z2pXDRHKWVoK4kHv__Fnxb4XhdJncfzSmMibZGguOEVPNuRotMjhC7a-lgHKItqeamOSxQNONuhea601R3k8QVDA92mnRKBsDiQw6-mcCw-K5t49I1TkkwauQ1EYQU5GI4vttxbdO_irZfQgINfyCmAkqo_IWgc8498pCuI5lMA2vI9X3BETtNt8WS451hU59fy7K_sjiojFG6mvwu7C-z0ZPcqKQ8F7c2JfZq0qphslMrqj0nZh0skGf0Qf6ZmRrftkNONcO9j9jh5eJfEHIEmGqNhDeO9ftQq5BuWfm6FhYVIW1YnBKrNk6lLkk38fuKjk8FevNwH6knVZjb3Q27Kr7K2cbbvlPEp846VrJrwIdJjfpDuAoorjMQAw-yVJQYOrb_v8F1jhnoMC_Qdu5Qc1AjbDrHggrZtkG9f7pw60reoNk01OCVsOD5ecldm05PfJ2NqhdZn1oXXxFOXc8lcBWpYkfhrOzw0fpxH4hFk4j8HSvy4n0EkB5ZfctDYx6JxXfoCsW7zYgm52ZCZISV5Kchkhlk6W2C1pUs8YjtxAU2I8A6wVbJwGVbwsDudgPXMuNH_PVk3YkljWU-zkPbMLWMOc-DNyioE-dAoq1VWPXoNuhaOqMDR4RCiZPhvJg0yxfA68";
+
+ //String paymentType = "01"; //01=Card Payment
+
+ //Get REQUERY Payment from UDC Laravel Echo Listener Server
+ RetrofitAPICollection service = RetrofitClient.getRetrofitClient(tempHostUrl).create(RetrofitAPICollection.class);
+ /*Retrofit retrofit = new Retrofit.Builder()
+ .baseUrl("http://udcsys-api-build.testpigeon.net")
+ .addConverterFactory(GsonConverterFactory.create())
+ .build();*/
+
+ Call callCardPayStatus = service.requeryCardPayment("Bearer " + buildToken,
+ referenceNumber,
+ merchanCode,
+ payType,
+ amount,
+ encryptedSignValueRequery);
+
+ callCardPayStatus.enqueue(new Callback() {
+ @Override
+ public void onResponse(Call call, Response response) {
+
+ /*Toast.makeText(StatusActivity.this,"\n" +
+ "Update data process completed!",Toast.LENGTH_SHORT).show();*/
+ if (response.isSuccessful()) {
+ try {
+ JSONObject responseJSON = new JSONObject(response.body());
+
+ String responseStatus = responseJSON.getString("status");
+
+ if (responseStatus.toLowerCase().trim().equals("fail")) {
+ //set the fail info
+ String refNum = referenceNum;
+ String finalResultPayRespCodeStatus = status;
+ String finalAmount = amountTransaction;
+ String payRespCodeTransaction = payRespCode;
+ String encryptedSignUpdate = encryptedSignValueUpdate;
+ //String paymentTypeTransaction = transaction.getType();
+ //String paymentFunctionTransaction = transaction.getFunction();
+ //String paymentCameraMode = transaction.getCameraMode();
+ //TODO: change this hardcoded value later
+ //String signValue = "testSignature";
+ //String paramResponse = "HLB params here..";
+/*updateResponseFromhlb(refNum, payTypeTransaction, payFunctionTransaction,
+ payCameraModeTransaction, signValue, finalAmount, finalResultPayRespCodeStatus, paramResponse);*/
+
+ //updateResponseToApi(String referenceNumber, String status, String merchantCode, String amount, String responseCode,
+ // String encryptedSignValueUpdate, String paramsResponse)
+ //update Status = FAIL to server
+ //updateResponseToApi(String referenceNumber, String status, String merchantCode, String amount, String responseCode,
+ // String encryptedSignValueUpdate, String paramsResponse)
+ updateResponseFromhlb(referenceNum, finalResultPayRespCodeStatus, merchanCode, finalAmount, payRespCodeTransaction,
+ encryptedSignUpdate, paramResponse);
+
+ /*updateResponseFromhlb(refNum, paymentTypeTransaction, paymentFunctionTransaction, paymentCameraMode,
+ signValue, finalAmount, finalResultPayRespCodeStatus, paramResponse);*/
+
+ //show screen/info about cannot retry
+ setResult(RESULT_OK);
+ StatusActivity.showFinishMessage(StatusActivity.this, "Payment Fail!", "Payment status : " + responseStatus);
+
+ //hold the info from UDC kiosk donation received for 5 second then proceed to HLB app
+ final Handler handler = new Handler(Looper.getMainLooper());
+ handler.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ //Do something after 5000ms = 5 seconds
+ //direct user to main screen
+
+ Intent intent = new Intent(StatusActivity.this, MainActivity.class);
+ intent.putExtra("statusCurrent", finalResultPayRespCodeStatus);
+ intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
+ startActivity(intent);
+ }
+ }, 5000);
+
+
+ } else if (responseStatus.toLowerCase().trim().equals("pending")) {
+ //if status not fail, proceed the retry payment process
+ String refNum = referenceNum;
+ String finalResultPayRespCodeStatus = "pending";
+ vStatus = finalResultPayRespCodeStatus;
+ String finalAmount = amountTransaction;
+
+ //String transactionStatus = status; ->pending
+ String transactionReference = refNum;
+ String transactionStatus = finalResultPayRespCodeStatus;
+ String transactionAmount = finalAmount;
+
+ retryPayment(transactionAmount);
+ }
+
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ } //if response is NoSuccessful
+
+ }
+
+ @Override
+ public void onFailure(Call call, Throwable t) {
+ Toast.makeText(StatusActivity.this, "Unsuccessfully update data!\n", Toast.LENGTH_SHORT).show();
+ }
+ });
+
+ }
+
+ private void retryPayment(String finalAmount) {
+
+ String amount = finalAmount;
+ //Get the amount from current screen
+ String payAmount = amount;
+
+ //Convert double value of amount from UDC kiosk app to integer 1st
+ double doubleValue = Double.parseDouble(payAmount);
+
+ //Convert amount to time 100 for HLB to process
+ int correctAmount = (int) Math.round(doubleValue * 100);
+
+ String pay_amount = "";
+
+ Bundle extra = new Bundle();
+ String pay_function = "01"; //Sale Payment Function
+ pay_amount = pay_amount.valueOf(correctAmount);
+ String pay_type = "01"; //Card Payment
+ String pay_camera_mode = "01"; //Internal Device Back Camera
+ String pay_print_receipt_id = "N"; //Set Requirement
+ String pay_resp_code = "";
+
+ //Pack Request Message
+ extra.putString("pay_function", pay_function);
+ extra.putString("pay_amount", pay_amount);
+ extra.putString("pay_type", pay_type);
+ extra.putString("pay_camera_mode", pay_camera_mode);
+ extra.putString("pay_print_receipt_id", pay_print_receipt_id);
+ extra.putString("pay_resp_code", pay_resp_code);
+
+ //API to call Payment App
+ Intent intent = new Intent("com.revenue.edc.hlb.pro.app2app");
+ intent.putExtras(extra);
+
+ startActivity(intent);
+
+ }
+
+ //updateResponseToApi(String referenceNumber, String status, String merchantCode, String amount, String responseCode,
+ // String encryptedSignValueUpdate, String paramsResponse)
+ //Signature = merchant_code+secret_key+reference_number+amount+response_code ->23/08/2021-update
+ private void updateResponseFromhlb(String referenceNumber, String status, String merchantCode, String amount, String responseCode,
+ String encryptedSignValueUpdate, String paramsResponse) {
+ String buildToken = "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiIxIiwianRpIjoiOTA2ZTNkN2VmNmZkNmNhZjVjYTVkNWEzYjI5ZDRiMWYxZjlmYTc4ZDcxYzYyNGE0N2FmMTYwMGQzZWY3ZGU5OGE5MGY2NzJlNzE4NmVmZGIiLCJpYXQiOjE2MDg1MzYyMTMsIm5iZiI6MTYwODUzNjIxMywiZXhwIjoxNjQwMDcyMjEzLCJzdWIiOiIxMSIsInNjb3BlcyI6W119.i2jDd1Zux2UkoLhzif762ghsJFhQ32Gk6g0Z2pXDRHKWVoK4kHv__Fnxb4XhdJncfzSmMibZGguOEVPNuRotMjhC7a-lgHKItqeamOSxQNONuhea601R3k8QVDA92mnRKBsDiQw6-mcCw-K5t49I1TkkwauQ1EYQU5GI4vttxbdO_irZfQgINfyCmAkqo_IWgc8498pCuI5lMA2vI9X3BETtNt8WS451hU59fy7K_sjiojFG6mvwu7C-z0ZPcqKQ8F7c2JfZq0qphslMrqj0nZh0skGf0Qf6ZmRrftkNONcO9j9jh5eJfEHIEmGqNhDeO9ftQq5BuWfm6FhYVIW1YnBKrNk6lLkk38fuKjk8FevNwH6knVZjb3Q27Kr7K2cbbvlPEp846VrJrwIdJjfpDuAoorjMQAw-yVJQYOrb_v8F1jhnoMC_Qdu5Qc1AjbDrHggrZtkG9f7pw60reoNk01OCVsOD5ecldm05PfJ2NqhdZn1oXXxFOXc8lcBWpYkfhrOzw0fpxH4hFk4j8HSvy4n0EkB5ZfctDYx6JxXfoCsW7zYgm52ZCZISV5Kchkhlk6W2C1pUs8YjtxAU2I8A6wVbJwGVbwsDudgPXMuNH_PVk3YkljWU-zkPbMLWMOc-DNyioE-dAoq1VWPXoNuhaOqMDR4RCiZPhvJg0yxfA68";
+
+ //Get REQUERY Payment from UDC Laravel Echo Listener Server
+ Retrofit retrofit = new Retrofit.Builder()
+ .baseUrl("http://udcsys-api-build.testpigeon.net")
+ .addConverterFactory(GsonConverterFactory.create())
+ .build();
+
+ RetrofitAPICollection retrofitAPICollection = retrofit.create(RetrofitAPICollection.class);
+ Call call = retrofitAPICollection.updateStatusCardPayment("Bearer " + buildToken,
+ referenceNumber,
+ status,
+ merchantCode,
+ amount,
+ responseCode,
+ encryptedSignValueUpdate,
+ paramsResponse);
+
+ call.enqueue(new Callback() {
+ @Override
+ public void onResponse(Call call, Response response) {
+ //txtStatus.setText(response.body().getReferenceNumber()+ " ".concat(response.body().getStatus()+ " "));
+
+ Toast.makeText(StatusActivity.this, "\n" +
+ "Update data process completed!", Toast.LENGTH_SHORT).show();
+ }
+
+ @Override
+ public void onFailure(Call call, Throwable t) {
+ Toast.makeText(StatusActivity.this, "Unsuccessfully update data!\n", Toast.LENGTH_SHORT).show();
+ }
+ });
+
+
+ }
+
+ private void buttonRetryPayment(String transactionStatus) {
+
+ //Get status from Response Screen , send to MainActivity for retry process
+ Intent intent = new Intent(StatusActivity.this, MainActivity.class);
+ //intent.putExtra("transaction", transaction);
+ intent.putExtra("status", transactionStatus);
+ startActivity(intent);
+ //setResult(RESULT_OK);
+ //finish();
+
+
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/cst/im30/common/CallableInterface.java b/app/src/main/java/com/cst/im30/common/CallableInterface.java
new file mode 100644
index 0000000..014a961
--- /dev/null
+++ b/app/src/main/java/com/cst/im30/common/CallableInterface.java
@@ -0,0 +1,9 @@
+package com.cst.im30.common;
+
+public interface CallableInterface {
+
+ void callBack(String source);
+
+ void callBack(String source, Object object);
+
+}
diff --git a/app/src/main/java/com/cst/im30/common/Constants.java b/app/src/main/java/com/cst/im30/common/Constants.java
new file mode 100644
index 0000000..7e95828
--- /dev/null
+++ b/app/src/main/java/com/cst/im30/common/Constants.java
@@ -0,0 +1,26 @@
+package com.cst.im30.common;
+
+public class Constants {
+
+ public static final String SERVER_URL = "http://hello-booking-api-build.testpigeon.net";
+ public static final String CLIENT_ID = "3";
+ public static final String CLIENT_SECRET = "w5RJ7bMF6NH39aDVyJJV0M1gOg0nZQcO2atVcXyF";
+
+ public static final String ECHO_SERVER_URL = "http://hello-booking-api-build.testpigeon.net";
+ public static final String ECHO_SERVER_PORT = "6001";
+
+ public static final String KIOSK_CODE = "KIOSK001";
+
+ public static final String SOCKET_PREFIX = "HelloBookingApi_";
+
+ public static final String PAYMENT_CHANNEL_ID = "payment#";
+ public static final String PAYMENT_EVENT_TYPE = ".makepayment";
+
+ public static final String IC_CHANNEL_ID = "verification#";
+ public static final String IC_EVENT_TYPE = ".guestverification";
+
+ //trigger
+ //public static final String LAUNCH_URL = "http://laravel-echo-server.testpigeon.net";
+ //public static final String LAUNCH_URL = "http://udcsys-api-build.testpigeon.net";
+
+}
diff --git a/app/src/main/java/com/cst/im30/common/Parcel.java b/app/src/main/java/com/cst/im30/common/Parcel.java
new file mode 100644
index 0000000..02d1591
--- /dev/null
+++ b/app/src/main/java/com/cst/im30/common/Parcel.java
@@ -0,0 +1,21 @@
+package com.cst.im30.common;
+
+import org.json.JSONObject;
+
+import java.io.Serializable;
+
+public class Parcel implements Serializable {
+ private JSONObject obj;
+
+ public Parcel(JSONObject obj) {
+ this.obj = obj;
+ }
+
+ public Parcel(String toString) {
+ }
+
+ public JSONObject getObj() {
+ return obj;
+ }
+
+}
diff --git a/app/src/main/java/com/cst/im30/common/Payment.java b/app/src/main/java/com/cst/im30/common/Payment.java
new file mode 100644
index 0000000..bf51128
--- /dev/null
+++ b/app/src/main/java/com/cst/im30/common/Payment.java
@@ -0,0 +1,107 @@
+package com.cst.im30.common;
+
+import com.google.gson.annotations.Expose;
+import com.google.gson.annotations.SerializedName;
+
+public class Payment {
+ @SerializedName("reference_number")
+ @Expose
+ private String referenceNumber;
+
+ /*@Field("reference_number") String referenceNumber,
+ @Field("payment_type") String paymentType,
+ @Field("payment_function") String paymentFunction,
+ @Field("payment_camera_mode") String paymentCameraMode,
+ @Field("signature") String signature,
+ @Field("amount") String amount,
+ @Field("status") String status,
+ @Field("params_response") String paramsResponse);*/
+
+ @SerializedName("payment_type")
+ @Expose
+ private String paymentType;
+
+ @SerializedName("payment_function")
+ @Expose
+ private String paymentFunction;
+
+ @SerializedName("payment_camera_mode")
+ @Expose
+ private String paymentCameraMode;
+
+ @SerializedName("signature")
+ @Expose
+ private String signature;
+
+ @SerializedName("amount")
+ @Expose
+ private String amount;
+
+ @SerializedName("status")
+ @Expose
+ private String status;
+
+ @SerializedName("params_response")
+ @Expose
+ private String[] params;
+
+ public Payment(String referenceNumber, String paymentType, String paymentFunction, String paymentCameraMode, String signature,
+ String amount, String status, String[] params) {
+ this.referenceNumber = referenceNumber;
+ this.paymentType = paymentType;
+ this.paymentFunction = paymentFunction;
+ this.paymentCameraMode = paymentCameraMode;
+ this.signature = signature;
+ this.amount = amount;
+ this.status = status;
+ this.params = params;
+ }
+
+ //GETTER
+ public String getReferenceNumber() {
+ return referenceNumber;
+ }
+
+ public void setReferenceNumber(String referenceNumber) {
+ this.referenceNumber = referenceNumber;
+ }
+
+ public String getPaymentType() {
+ return paymentType;
+ }
+
+ public String getPaymentFunction() {
+ return paymentFunction;
+ }
+
+ public String getPaymentCameraMode() {
+ return paymentCameraMode;
+ }
+
+ public String getSignature() {
+ return signature;
+ }
+
+ public String getAmount() {
+ return amount;
+ }
+
+ public void setAmount(String amount) {
+ this.amount = amount;
+ }
+
+
+ //SETTER
+
+ public String getStatus() {
+ return status;
+ }
+
+ public void setStatus(String status) {
+ this.status = status;
+ }
+
+ public String[] getParams() {
+ return params;
+ }
+}
diff --git a/app/src/main/java/com/cst/im30/entity/Transaction.java b/app/src/main/java/com/cst/im30/entity/Transaction.java
new file mode 100644
index 0000000..a4f2fdb
--- /dev/null
+++ b/app/src/main/java/com/cst/im30/entity/Transaction.java
@@ -0,0 +1,400 @@
+package com.cst.im30.entity;
+
+import androidx.room.ColumnInfo;
+import androidx.room.Entity;
+import androidx.room.PrimaryKey;
+
+import java.io.Serializable;
+
+@Entity(tableName = Transaction.TABLE_NAME)
+public class Transaction implements Serializable {
+
+ public static final String TABLE_NAME = "transactions";
+ public static final String COLUMN_ID = "id";
+ public static final String COLUMN_TYPE = "type";
+ public static final String COLUMN_KEY_INDEX = "key_index";
+ public static final String COLUMN_SIGNATURE = "signature";
+ public static final String COLUMN_SIGNATURE_METHOD = "signature_method";
+ public static final String COLUMN_AMOUNT = "amount";
+ public static final String COLUMN_CAMERA_MODE = "camera_mode";
+ public static final String COLUMN_BANK_REF_NUM = "bank_ref_num";
+ public static final String COLUMN_BATCH_NO = "batch_no";
+ public static final String COLUMN_RESPONSE_CODE = "response_code";
+ public static final String COLUMN_RESPONSE_CODE_DESC = "response_code_desc";
+ public static final String COLUMN_CURRENCY = "currency";
+ public static final String COLUMN_CUSTOMER_ID = "customer_id";
+ public static final String COLUMN_DISPLAY_MID = "display_mid";
+ public static final String COLUMN_DISPLAY_TID = "display_tid";
+ public static final String COLUMN_ENTRY_MODE = "entry_mode";
+ public static final String COLUMN_FUNCTION = "function";
+ public static final String COLUMN_INVOICE_NO = "invoice_no";
+ public static final String COLUMN_MID = "mid";
+ public static final String COLUMN_QR_CODE = "qr_code";
+ public static final String COLUMN_SCHEME = "scheme";
+ public static final String COLUMN_TID = "tid";
+ public static final String COLUMN_TRACE_NO = "trace_no";
+ public static final String COLUMN_TXN_DESC = "txn_desc";
+ public static final String COLUMN_TXN_DT = "txn_dt";
+ public static final String COLUMN_TXN_ID = "txn_id";
+ public static final String COLUMN_STATUS = "status";
+ public static final String COLUMN_ORI_INVOICE_NO = "ori_invoice_no";
+ public static final String COLUMN_VOIDED_AT = "voided_at";
+ public static final String COLUMN_SETTLED_AT = "settled_at";
+ public static final String COLUMN_CREATED_AT = "created_at";
+ public static final String COLUMN_UPDATED_AT = "updated_at";
+
+ @PrimaryKey(autoGenerate = true)
+ private int id;
+
+ @ColumnInfo(name = COLUMN_TYPE)
+ private String type;
+
+ @ColumnInfo(name = COLUMN_KEY_INDEX)
+ private String keyIndex;
+
+ @ColumnInfo(name = COLUMN_SIGNATURE)
+ private String signature;
+
+ @ColumnInfo(name = COLUMN_SIGNATURE_METHOD)
+ private String signatureMethod;
+
+ @ColumnInfo(name = COLUMN_AMOUNT)
+ private String amount;
+
+ @ColumnInfo(name = COLUMN_CAMERA_MODE)
+ private String cameraMode;
+
+ @ColumnInfo(name = COLUMN_BANK_REF_NUM)
+ private String bankRefNum;
+
+ @ColumnInfo(name = COLUMN_BATCH_NO)
+ private String batchNo;
+
+ @ColumnInfo(name = COLUMN_RESPONSE_CODE)
+ private String responseCode;
+
+ @ColumnInfo(name = COLUMN_RESPONSE_CODE_DESC)
+ private String responseCodeDesc;
+
+ @ColumnInfo(name = COLUMN_CURRENCY)
+ private String currency;
+
+ @ColumnInfo(name = COLUMN_CUSTOMER_ID)
+ private String customerId;
+
+ @ColumnInfo(name = COLUMN_DISPLAY_MID)
+ private String displayMid;
+
+ @ColumnInfo(name = COLUMN_DISPLAY_TID)
+ private String displayTid;
+
+ @ColumnInfo(name = COLUMN_ENTRY_MODE)
+ private String entryMode;
+
+ @ColumnInfo(name = COLUMN_FUNCTION)
+ private String function;
+
+ @ColumnInfo(name = COLUMN_INVOICE_NO)
+ private String invoiceNo;
+
+ @ColumnInfo(name = COLUMN_MID)
+ private String mid;
+
+ @ColumnInfo(name = COLUMN_QR_CODE)
+ private String qrCode;
+
+ @ColumnInfo(name = COLUMN_SCHEME)
+ private String scheme;
+
+ @ColumnInfo(name = COLUMN_TID)
+ private String tid;
+
+ @ColumnInfo(name = COLUMN_TRACE_NO)
+ private String traceNo;
+
+ @ColumnInfo(name = COLUMN_TXN_DESC)
+ private String transactionDesc;
+
+ @ColumnInfo(name = COLUMN_TXN_DT)
+ private String transactionDt;
+
+ @ColumnInfo(name = COLUMN_TXN_ID)
+ private String transactionId;
+
+ @ColumnInfo(name = COLUMN_STATUS)
+ private String status;
+
+ @ColumnInfo(name = COLUMN_ORI_INVOICE_NO)
+ private String oriInvoiceNo;
+
+ @ColumnInfo(name = COLUMN_VOIDED_AT)
+ private String voidedAt;
+
+ @ColumnInfo(name = COLUMN_SETTLED_AT)
+ private String settledAt;
+
+ @ColumnInfo(name = COLUMN_CREATED_AT)
+ private String createdAt;
+
+ @ColumnInfo(name = COLUMN_UPDATED_AT)
+ private String updatedAt;
+
+ public Transaction() {
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getType() {
+ return type == null ? "" : type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public String getKeyIndex() {
+ return keyIndex == null ? "" : keyIndex;
+ }
+
+ public void setKeyIndex(String keyIndex) {
+ this.keyIndex = keyIndex;
+ }
+
+ public String getSignature() {
+ return signature == null ? "" : signature;
+ }
+
+ public void setSignature(String signature) {
+ this.signature = signature;
+ }
+
+ public String getSignatureMethod() {
+ return signatureMethod == null ? "" : signatureMethod;
+ }
+
+ public void setSignatureMethod(String signatureMethod) {
+ this.signatureMethod = signatureMethod;
+ }
+
+ public String getAmount() {
+ return amount == null ? "" : amount;
+ }
+
+ public void setAmount(String amount) {
+ this.amount = amount;
+ }
+
+ public String getCameraMode() {
+ return cameraMode == null ? "" : cameraMode;
+ }
+
+ public void setCameraMode(String cameraMode) {
+ this.cameraMode = cameraMode;
+ }
+
+ public String getBankRefNum() {
+ return bankRefNum == null ? "" : bankRefNum;
+ }
+
+ public void setBankRefNum(String bankRefNum) {
+ this.bankRefNum = bankRefNum;
+ }
+
+ public String getBatchNo() {
+ return batchNo == null ? "" : batchNo;
+ }
+
+ public void setBatchNo(String batchNo) {
+ this.batchNo = batchNo;
+ }
+
+ public String getResponseCode() {
+ return responseCode == null ? "" : responseCode;
+ }
+
+ public void setResponseCode(String responseCode) {
+ this.responseCode = responseCode;
+ }
+
+ public String getResponseCodeDesc() {
+ return responseCodeDesc == null ? "" : responseCodeDesc;
+ }
+
+ public void setResponseCodeDesc(String responseCodeDesc) {
+ this.responseCodeDesc = responseCodeDesc;
+ }
+
+ public String getCurrency() {
+ return currency == null ? "" : currency;
+ }
+
+ public void setCurrency(String currency) {
+ this.currency = currency;
+ }
+
+ public String getCustomerId() {
+ return customerId == null ? "" : customerId;
+ }
+
+ public void setCustomerId(String customerId) {
+ this.customerId = customerId;
+ }
+
+ public String getDisplayMid() {
+ return displayMid == null ? "" : displayMid;
+ }
+
+ public void setDisplayMid(String displayMid) {
+ this.displayMid = displayMid;
+ }
+
+ public String getDisplayTid() {
+ return displayTid == null ? "" : displayTid;
+ }
+
+ public void setDisplayTid(String displayTid) {
+ this.displayTid = displayTid;
+ }
+
+ public String getEntryMode() {
+ return entryMode == null ? "" : entryMode;
+ }
+
+ public void setEntryMode(String entryMode) {
+ this.entryMode = entryMode;
+ }
+
+ public String getFunction() {
+ return function == null ? "" : function;
+ }
+
+ public void setFunction(String function) {
+ this.function = function;
+ }
+
+ public String getInvoiceNo() {
+ return invoiceNo == null ? "" : invoiceNo;
+ }
+
+ public void setInvoiceNo(String invoiceNo) {
+ this.invoiceNo = invoiceNo;
+ }
+
+ public String getMid() {
+ return mid == null ? "" : mid;
+ }
+
+ public void setMid(String mid) {
+ this.mid = mid;
+ }
+
+ public String getQrCode() {
+ return qrCode == null ? "" : qrCode;
+ }
+
+ public void setQrCode(String qrCode) {
+ this.qrCode = qrCode;
+ }
+
+ public String getScheme() {
+ return scheme == null ? "" : scheme;
+ }
+
+ public void setScheme(String scheme) {
+ this.scheme = scheme;
+ }
+
+ public String getTid() {
+ return tid == null ? "" : tid;
+ }
+
+ public void setTid(String tid) {
+ this.tid = tid;
+ }
+
+ public String getTraceNo() {
+ return traceNo == null ? "" : traceNo;
+ }
+
+ public void setTraceNo(String traceNo) {
+ this.traceNo = traceNo;
+ }
+
+ public String getTransactionDesc() {
+ return transactionDesc == null ? "" : transactionDesc;
+ }
+
+ public void setTransactionDesc(String transactionDesc) {
+ this.transactionDesc = transactionDesc;
+ }
+
+ public String getTransactionDt() {
+ return transactionDt == null ? "" : transactionDt;
+ }
+
+ public void setTransactionDt(String transactionDt) {
+ this.transactionDt = transactionDt;
+ }
+
+ public String getTransactionId() {
+ return transactionId == null ? "" : transactionId;
+ }
+
+ public void setTransactionId(String transactionId) {
+ this.transactionId = transactionId;
+ }
+
+ public String getStatus() {
+ return status == null ? "" : status;
+ }
+
+ public void setStatus(String status) {
+ this.status = status;
+ }
+
+ public String getOriInvoiceNo() {
+ return oriInvoiceNo == null ? "" : oriInvoiceNo;
+ }
+
+ public void setOriInvoiceNo(String oriInvoiceNo) {
+ this.oriInvoiceNo = oriInvoiceNo;
+ }
+
+ public String getVoidedAt() {
+ return voidedAt == null ? "" : voidedAt;
+ }
+
+ public void setVoidedAt(String voidedAt) {
+ this.voidedAt = voidedAt;
+ }
+
+ public String getSettledAt() {
+ return settledAt == null ? "" : settledAt;
+ }
+
+ public void setSettledAt(String settledAt) {
+ this.settledAt = settledAt;
+ }
+
+ public String getCreatedAt() {
+ return createdAt == null ? "" : createdAt;
+ }
+
+ public void setCreatedAt(String createdAt) {
+ this.createdAt = createdAt;
+ }
+
+ public String getUpdatedAt() {
+ return updatedAt == null ? "" : updatedAt;
+ }
+
+ public void setUpdatedAt(String updatedAt) {
+ this.updatedAt = updatedAt;
+ }
+}
diff --git a/app/src/main/java/com/cst/im30/model/EventLogDetailed.java b/app/src/main/java/com/cst/im30/model/EventLogDetailed.java
new file mode 100644
index 0000000..d1a28fb
--- /dev/null
+++ b/app/src/main/java/com/cst/im30/model/EventLogDetailed.java
@@ -0,0 +1,11 @@
+package com.cst.im30.model;
+
+import java.io.Serializable;
+
+import lombok.Data;
+
+@Data
+public class EventLogDetailed implements Serializable {
+
+ String type, status, documentType, documentNumber, firstName, lastName;
+}
diff --git a/app/src/main/java/com/cst/im30/retrofit/RetrofitAPICollection.java b/app/src/main/java/com/cst/im30/retrofit/RetrofitAPICollection.java
new file mode 100644
index 0000000..8212eec
--- /dev/null
+++ b/app/src/main/java/com/cst/im30/retrofit/RetrofitAPICollection.java
@@ -0,0 +1,73 @@
+package com.cst.im30.retrofit;
+
+import com.cst.im30.common.Payment;
+
+import retrofit2.Call;
+import retrofit2.http.Field;
+import retrofit2.http.FormUrlEncoded;
+import retrofit2.http.GET;
+import retrofit2.http.Header;
+import retrofit2.http.Headers;
+import retrofit2.http.PUT;
+import retrofit2.http.Path;
+import retrofit2.http.Query;
+
+public interface RetrofitAPICollection {
+
+ @GET("launch")
+ Call getLaunch();
+
+ //Get data from Laravel Echo Server
+ @GET("/payment-request")
+ Call getData();
+
+
+ @Headers({
+ "Accept: application/json",
+ "Content-Type: application/json"
+ })
+ @GET("api/v1/kiosk/broadcast-event-log/{eventCode}")
+ Call getBroadcastEventLogDetails(
+ @Header("Client-Id") String clientId,
+ @Header("Client-Secret") String clientSecret,
+ @Path("eventCode") String referenceNumber
+ );
+
+
+ @Headers({
+ "Accept: application/json"
+ })
+ @GET("api/intentpayment/requery")
+ Call requeryCardPayment(@Header("Authorization") String token,
+ @Query("reference_number") String referenceNumberQuery,
+ @Query("merchant_code") String merchantCode,
+ @Query("payment_type") String paymentType,
+ @Query("amount") String amount,
+ @Query("signature") String signature);
+
+ @Headers({
+ "Accept: application/json",
+ "Content-Type: application/x-www-form-urlencoded"
+ })
+ @FormUrlEncoded
+ @PUT("api/intentpayment/update-status")
+ Call updateStatusCardPayment(@Header("Authorization") String token,
+ @Field("reference_number") String referenceNumber,
+ @Field("status") String status,
+ @Field("merchant_code") String merchantCode,
+ @Field("amount") String amount,
+ @Field("response_code") String response_code,
+ @Field("signature") String signature,
+ @Field("params_response") String params_response);
+
+ /*Call updateStatusCardPayment(@Header("Authorization") String token,
+ @Field("reference_number") String referenceNumber,
+ @Field("payment_type") String paymentType,
+ @Field("payment_function") String paymentFunction,
+ @Field("payment_camera_mode") String paymentCameraMode,
+ @Field("signature") String signature,
+ @Field("amount") String amount,
+ @Field("status") String status,
+ @Field("params_response") String paramsResponse);*/
+
+}
diff --git a/app/src/main/java/com/cst/im30/retrofit/RetrofitClient.java b/app/src/main/java/com/cst/im30/retrofit/RetrofitClient.java
new file mode 100644
index 0000000..35f7428
--- /dev/null
+++ b/app/src/main/java/com/cst/im30/retrofit/RetrofitClient.java
@@ -0,0 +1,34 @@
+package com.cst.im30.retrofit;
+
+import java.util.concurrent.TimeUnit;
+
+import okhttp3.OkHttpClient;
+import retrofit2.Retrofit;
+import retrofit2.converter.gson.GsonConverterFactory;
+import retrofit2.converter.scalars.ScalarsConverterFactory;
+
+public class RetrofitClient {
+
+ public static Retrofit getRetrofitClient(String serverUrl) {
+ String endPointUrl;
+
+ if (!serverUrl.trim().endsWith("/")) {
+ endPointUrl = serverUrl.trim() + "/";
+ } else {
+ endPointUrl = serverUrl.trim();
+ }
+
+ OkHttpClient okHttpClient = new OkHttpClient.Builder()
+ .connectTimeout(1, TimeUnit.MINUTES)
+ .readTimeout(60, TimeUnit.SECONDS)
+ .writeTimeout(60, TimeUnit.SECONDS)
+ .build();
+
+ return new Retrofit.Builder()
+ .baseUrl(endPointUrl)
+ .client(okHttpClient)
+ .addConverterFactory(ScalarsConverterFactory.create())
+ .addConverterFactory(GsonConverterFactory.create())
+ .build();
+ }
+}
diff --git a/app/src/main/java/com/cst/im30/service/IDVerificationService.java b/app/src/main/java/com/cst/im30/service/IDVerificationService.java
new file mode 100644
index 0000000..47c3b66
--- /dev/null
+++ b/app/src/main/java/com/cst/im30/service/IDVerificationService.java
@@ -0,0 +1,95 @@
+package com.cst.im30.service;
+
+import android.content.Context;
+
+import androidx.annotation.NonNull;
+
+import com.cst.im30.common.CallableInterface;
+import com.cst.im30.common.Constants;
+import com.cst.im30.model.EventLogDetailed;
+import com.cst.im30.retrofit.RetrofitAPICollection;
+import com.cst.im30.retrofit.RetrofitClient;
+
+import org.json.JSONObject;
+
+import retrofit2.Call;
+import retrofit2.Callback;
+import retrofit2.Response;
+
+public class IDVerificationService {
+
+ public static final String CALLBACK_SUCCESS_GET_EVENT_LOG = "callback_success_get_event_log";
+ public static final String CALLBACK_FAIL_GET_EVENT_LOG = "callback_fail_get_event_log";
+
+ private final Context context;
+ private final CallableInterface callback;
+
+ private final String hostUrl;
+ private final String clientId;
+ private final String clientSecret;
+
+ public IDVerificationService(Context context, CallableInterface callback) {
+ this.context = context;
+ this.callback = callback;
+
+ this.hostUrl = Constants.SERVER_URL;
+ this.clientId = Constants.CLIENT_ID;
+ this.clientSecret = Constants.CLIENT_SECRET;
+ }
+
+ public void getEventLog(String code) {
+
+ RetrofitAPICollection service = RetrofitClient.getRetrofitClient(hostUrl).create(RetrofitAPICollection.class);
+ Call call = service.getBroadcastEventLogDetails(clientId, clientSecret, code);
+
+ call.enqueue(new Callback() {
+
+ @Override
+ public void onResponse(@NonNull Call call, @NonNull Response response) {
+ onResponseGetEventLog(response);
+ }
+
+ @Override
+ public void onFailure(@NonNull Call call, @NonNull Throwable t) {
+ onFailureGetEventLog(t);
+ }
+ });
+ }
+
+ private void onResponseGetEventLog(Response response) {
+ try {
+ if (!response.isSuccessful()) {
+
+ } else {
+ JSONObject responseJSON = new JSONObject(response.body());
+ EventLogDetailed eventLogDetailed = this.parseGetEventLogResponse(responseJSON);
+ callback.callBack(CALLBACK_SUCCESS_GET_EVENT_LOG, eventLogDetailed);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ private void onFailureGetEventLog(Throwable t) {
+
+ }
+
+ private EventLogDetailed parseGetEventLogResponse(JSONObject jsonObject) throws Exception {
+ String type = jsonObject.getJSONObject("data").getString("type");
+ String status = jsonObject.getJSONObject("data").getString("status");
+ String documentType = jsonObject.getJSONObject("data").getJSONObject("content").getString("document_type");
+ String documentNumber = jsonObject.getJSONObject("data").getJSONObject("content").getString("document_number");
+ String firstName = jsonObject.getJSONObject("data").getJSONObject("content").getString("first_name");
+ String lastName = jsonObject.getJSONObject("data").getJSONObject("content").getString("last_name");
+
+ EventLogDetailed eventLogDetailed = new EventLogDetailed();
+ eventLogDetailed.setType(type);
+ eventLogDetailed.setStatus(status);
+ eventLogDetailed.setDocumentType(documentType);
+ eventLogDetailed.setDocumentNumber(documentNumber);
+ eventLogDetailed.setFirstName(firstName);
+ eventLogDetailed.setLastName(lastName);
+
+ return eventLogDetailed;
+ }
+}
diff --git a/app/src/main/java/com/cst/im30/utility/BootReceiver.java b/app/src/main/java/com/cst/im30/utility/BootReceiver.java
new file mode 100644
index 0000000..6798335
--- /dev/null
+++ b/app/src/main/java/com/cst/im30/utility/BootReceiver.java
@@ -0,0 +1,21 @@
+package com.cst.im30.utility;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+import com.cst.im30.activity.MainActivity;
+
+public class BootReceiver extends BroadcastReceiver {
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+
+ if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
+ Intent myIntent = new Intent(context, MainActivity.class);
+ myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ context.startActivity(myIntent);
+ }
+
+ }
+}
diff --git a/app/src/main/java/com/cst/im30/utility/IccTester.java b/app/src/main/java/com/cst/im30/utility/IccTester.java
new file mode 100644
index 0000000..1a92f3d
--- /dev/null
+++ b/app/src/main/java/com/cst/im30/utility/IccTester.java
@@ -0,0 +1,93 @@
+package com.cst.im30.utility;
+
+import android.content.Context;
+
+import com.pax.dal.IDAL;
+import com.pax.dal.IIcc;
+import com.pax.dal.exceptions.IccDevException;
+import com.pax.neptunelite.api.NeptuneLiteUser;
+
+public class IccTester {
+
+ public static IDAL idal = null;
+ private static IccTester iccTester;
+ private IIcc icc;
+
+ private IccTester(Context context) {
+ try {
+ idal = NeptuneLiteUser.getInstance().getDal(context);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ icc = idal.getIcc();
+ }
+
+ public static IccTester getInstance(Context context) {
+ if (iccTester == null) {
+ iccTester = new IccTester(context);
+ }
+
+ return iccTester;
+ }
+
+ public byte[] init(byte slot) {
+ byte[] initRes = null;
+
+ try {
+ initRes = icc.init(slot);
+ return initRes;
+ } catch (IccDevException e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ public boolean detect(byte slot) {
+ boolean res = false;
+
+ try {
+ res = icc.detect(slot);
+ return res;
+ } catch (IccDevException e) {
+ e.printStackTrace();
+ return res;
+ }
+ }
+
+ public void close(byte slot) {
+ try {
+ icc.close(slot);
+ } catch (IccDevException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void autoResp(byte slot, boolean autoResp) {
+ try {
+ icc.autoResp(slot, autoResp);
+ } catch (IccDevException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public byte[] isoCommand(byte slot, byte[] send) {
+ try {
+ byte[] resp = icc.isoCommand(slot, send);
+ return resp;
+ } catch (IccDevException e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ public void light(boolean flag) {
+ try {
+ icc.light(flag);
+
+ } catch (IccDevException e) {
+ e.printStackTrace();
+
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/jniLibs/armeabi-v7a/libDCL.so b/app/src/main/jniLibs/armeabi-v7a/libDCL.so
new file mode 100644
index 0000000..647516b
Binary files /dev/null and b/app/src/main/jniLibs/armeabi-v7a/libDCL.so differ
diff --git a/app/src/main/jniLibs/armeabi-v7a/libDeviceConfig.so b/app/src/main/jniLibs/armeabi-v7a/libDeviceConfig.so
new file mode 100644
index 0000000..d5a1ca6
Binary files /dev/null and b/app/src/main/jniLibs/armeabi-v7a/libDeviceConfig.so differ
diff --git a/app/src/main/jniLibs/armeabi-v7a/libIGLBarDecoder.so b/app/src/main/jniLibs/armeabi-v7a/libIGLBarDecoder.so
new file mode 100644
index 0000000..6b36f2b
Binary files /dev/null and b/app/src/main/jniLibs/armeabi-v7a/libIGLBarDecoder.so differ
diff --git a/app/src/main/jniLibs/armeabi-v7a/libZBarDecoder.so b/app/src/main/jniLibs/armeabi-v7a/libZBarDecoder.so
new file mode 100644
index 0000000..91f13e1
Binary files /dev/null and b/app/src/main/jniLibs/armeabi-v7a/libZBarDecoder.so differ
diff --git a/app/src/main/jniLibs/armeabi-v7a/libiconv.so b/app/src/main/jniLibs/armeabi-v7a/libiconv.so
new file mode 100644
index 0000000..f39935d
Binary files /dev/null and b/app/src/main/jniLibs/armeabi-v7a/libiconv.so differ
diff --git a/app/src/main/jniLibs/armeabi/libDCL.so b/app/src/main/jniLibs/armeabi/libDCL.so
new file mode 100644
index 0000000..647516b
Binary files /dev/null and b/app/src/main/jniLibs/armeabi/libDCL.so differ
diff --git a/app/src/main/jniLibs/armeabi/libDeviceConfig.so b/app/src/main/jniLibs/armeabi/libDeviceConfig.so
new file mode 100644
index 0000000..d5a1ca6
Binary files /dev/null and b/app/src/main/jniLibs/armeabi/libDeviceConfig.so differ
diff --git a/app/src/main/jniLibs/armeabi/libIGLBarDecoder.so b/app/src/main/jniLibs/armeabi/libIGLBarDecoder.so
new file mode 100644
index 0000000..6b36f2b
Binary files /dev/null and b/app/src/main/jniLibs/armeabi/libIGLBarDecoder.so differ
diff --git a/app/src/main/jniLibs/armeabi/libZBarDecoder.so b/app/src/main/jniLibs/armeabi/libZBarDecoder.so
new file mode 100644
index 0000000..91f13e1
Binary files /dev/null and b/app/src/main/jniLibs/armeabi/libZBarDecoder.so differ
diff --git a/app/src/main/jniLibs/armeabi/libiconv.so b/app/src/main/jniLibs/armeabi/libiconv.so
new file mode 100644
index 0000000..f39935d
Binary files /dev/null and b/app/src/main/jniLibs/armeabi/libiconv.so differ
diff --git a/app/src/main/res/drawable-hdpi/new1.png b/app/src/main/res/drawable-hdpi/new1.png
new file mode 100644
index 0000000..7853b11
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/new1.png differ
diff --git a/app/src/main/res/drawable-hdpi/new2.png b/app/src/main/res/drawable-hdpi/new2.png
new file mode 100644
index 0000000..55a42a1
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/new2.png differ
diff --git a/app/src/main/res/drawable-hdpi/new3.png b/app/src/main/res/drawable-hdpi/new3.png
new file mode 100644
index 0000000..fb3d39a
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/new3.png differ
diff --git a/app/src/main/res/drawable-hdpi/new4.png b/app/src/main/res/drawable-hdpi/new4.png
new file mode 100644
index 0000000..a6ae3e9
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/new4.png differ
diff --git a/app/src/main/res/drawable-hdpi/new5.png b/app/src/main/res/drawable-hdpi/new5.png
new file mode 100644
index 0000000..49f46bb
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/new5.png differ
diff --git a/app/src/main/res/drawable-hdpi/new6.png b/app/src/main/res/drawable-hdpi/new6.png
new file mode 100644
index 0000000..a1974de
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/new6.png differ
diff --git a/app/src/main/res/drawable-mdpi/new1.png b/app/src/main/res/drawable-mdpi/new1.png
new file mode 100644
index 0000000..e6b6a6c
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/new1.png differ
diff --git a/app/src/main/res/drawable-mdpi/new2.png b/app/src/main/res/drawable-mdpi/new2.png
new file mode 100644
index 0000000..312d598
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/new2.png differ
diff --git a/app/src/main/res/drawable-mdpi/new3.png b/app/src/main/res/drawable-mdpi/new3.png
new file mode 100644
index 0000000..c976408
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/new3.png differ
diff --git a/app/src/main/res/drawable-mdpi/new4.png b/app/src/main/res/drawable-mdpi/new4.png
new file mode 100644
index 0000000..9e491c7
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/new4.png differ
diff --git a/app/src/main/res/drawable-mdpi/new5.png b/app/src/main/res/drawable-mdpi/new5.png
new file mode 100644
index 0000000..7dfc286
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/new5.png differ
diff --git a/app/src/main/res/drawable-mdpi/new6.png b/app/src/main/res/drawable-mdpi/new6.png
new file mode 100644
index 0000000..afe834c
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/new6.png differ
diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
new file mode 100644
index 0000000..2b068d1
--- /dev/null
+++ b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable-v24/ic_udc_launcher_background.xml b/app/src/main/res/drawable-v24/ic_udc_launcher_background.xml
new file mode 100644
index 0000000..07d5da9
--- /dev/null
+++ b/app/src/main/res/drawable-v24/ic_udc_launcher_background.xml
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable-xhdpi/new1.png b/app/src/main/res/drawable-xhdpi/new1.png
new file mode 100644
index 0000000..72416a9
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/new1.png differ
diff --git a/app/src/main/res/drawable-xhdpi/new2.png b/app/src/main/res/drawable-xhdpi/new2.png
new file mode 100644
index 0000000..a88a83f
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/new2.png differ
diff --git a/app/src/main/res/drawable-xhdpi/new3.png b/app/src/main/res/drawable-xhdpi/new3.png
new file mode 100644
index 0000000..5b9c6f9
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/new3.png differ
diff --git a/app/src/main/res/drawable-xhdpi/new4.png b/app/src/main/res/drawable-xhdpi/new4.png
new file mode 100644
index 0000000..ec9fba9
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/new4.png differ
diff --git a/app/src/main/res/drawable-xhdpi/new5.png b/app/src/main/res/drawable-xhdpi/new5.png
new file mode 100644
index 0000000..5438c76
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/new5.png differ
diff --git a/app/src/main/res/drawable-xhdpi/new6.png b/app/src/main/res/drawable-xhdpi/new6.png
new file mode 100644
index 0000000..2271c07
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/new6.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/new1.png b/app/src/main/res/drawable-xxhdpi/new1.png
new file mode 100644
index 0000000..ff7f69f
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/new1.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/new2.png b/app/src/main/res/drawable-xxhdpi/new2.png
new file mode 100644
index 0000000..2dd5036
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/new2.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/new3.png b/app/src/main/res/drawable-xxhdpi/new3.png
new file mode 100644
index 0000000..16a4db4
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/new3.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/new4.png b/app/src/main/res/drawable-xxhdpi/new4.png
new file mode 100644
index 0000000..f29a497
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/new4.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/new5.png b/app/src/main/res/drawable-xxhdpi/new5.png
new file mode 100644
index 0000000..1a02ce6
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/new5.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/new6.png b/app/src/main/res/drawable-xxhdpi/new6.png
new file mode 100644
index 0000000..88cb1d1
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/new6.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/new1.png b/app/src/main/res/drawable-xxxhdpi/new1.png
new file mode 100644
index 0000000..e18c8e8
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/new1.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/new2.png b/app/src/main/res/drawable-xxxhdpi/new2.png
new file mode 100644
index 0000000..2bc1c8e
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/new2.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/new3.png b/app/src/main/res/drawable-xxxhdpi/new3.png
new file mode 100644
index 0000000..cc3a373
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/new3.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/new4.png b/app/src/main/res/drawable-xxxhdpi/new4.png
new file mode 100644
index 0000000..d86953d
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/new4.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/new5.png b/app/src/main/res/drawable-xxxhdpi/new5.png
new file mode 100644
index 0000000..547a370
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/new5.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/new6.png b/app/src/main/res/drawable-xxxhdpi/new6.png
new file mode 100644
index 0000000..144b7f9
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/new6.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/read_card.jpg b/app/src/main/res/drawable-xxxhdpi/read_card.jpg
new file mode 100644
index 0000000..93da004
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/read_card.jpg differ
diff --git a/app/src/main/res/drawable/btn_general_disable_bg.xml b/app/src/main/res/drawable/btn_general_disable_bg.xml
new file mode 100644
index 0000000..df42bea
--- /dev/null
+++ b/app/src/main/res/drawable/btn_general_disable_bg.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/btn_general_enable_bg.xml b/app/src/main/res/drawable/btn_general_enable_bg.xml
new file mode 100644
index 0000000..23a2ffc
--- /dev/null
+++ b/app/src/main/res/drawable/btn_general_enable_bg.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_baseline_keyboard_return_24.xml b/app/src/main/res/drawable/ic_baseline_keyboard_return_24.xml
new file mode 100644
index 0000000..ad2c579
--- /dev/null
+++ b/app/src/main/res/drawable/ic_baseline_keyboard_return_24.xml
@@ -0,0 +1,11 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_baseline_settings_24.xml b/app/src/main/res/drawable/ic_baseline_settings_24.xml
new file mode 100644
index 0000000..154a7f0
--- /dev/null
+++ b/app/src/main/res/drawable/ic_baseline_settings_24.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 0000000..07d5da9
--- /dev/null
+++ b/app/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_status_fail.xml b/app/src/main/res/drawable/ic_status_fail.xml
new file mode 100644
index 0000000..c1339e0
--- /dev/null
+++ b/app/src/main/res/drawable/ic_status_fail.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_status_fail_fancy.png b/app/src/main/res/drawable/ic_status_fail_fancy.png
new file mode 100644
index 0000000..1529496
Binary files /dev/null and b/app/src/main/res/drawable/ic_status_fail_fancy.png differ
diff --git a/app/src/main/res/drawable/ic_status_success.xml b/app/src/main/res/drawable/ic_status_success.xml
new file mode 100644
index 0000000..b3a501a
--- /dev/null
+++ b/app/src/main/res/drawable/ic_status_success.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_status_success_fancy.png b/app/src/main/res/drawable/ic_status_success_fancy.png
new file mode 100644
index 0000000..0d3963b
Binary files /dev/null and b/app/src/main/res/drawable/ic_status_success_fancy.png differ
diff --git a/app/src/main/res/drawable/img_front_1.jpg b/app/src/main/res/drawable/img_front_1.jpg
new file mode 100644
index 0000000..edfd90b
Binary files /dev/null and b/app/src/main/res/drawable/img_front_1.jpg differ
diff --git a/app/src/main/res/drawable/img_front_2.jpg b/app/src/main/res/drawable/img_front_2.jpg
new file mode 100644
index 0000000..c4959d6
Binary files /dev/null and b/app/src/main/res/drawable/img_front_2.jpg differ
diff --git a/app/src/main/res/drawable/loading.xml b/app/src/main/res/drawable/loading.xml
new file mode 100644
index 0000000..a3c5300
--- /dev/null
+++ b/app/src/main/res/drawable/loading.xml
@@ -0,0 +1,149 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/pop_up_bg.xml b/app/src/main/res/drawable/pop_up_bg.xml
new file mode 100644
index 0000000..1184d85
--- /dev/null
+++ b/app/src/main/res/drawable/pop_up_bg.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/pop_up_round_top_text.xml b/app/src/main/res/drawable/pop_up_round_top_text.xml
new file mode 100644
index 0000000..b9dad4c
--- /dev/null
+++ b/app/src/main/res/drawable/pop_up_round_top_text.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_icc.xml b/app/src/main/res/layout/activity_icc.xml
new file mode 100644
index 0000000..04c37dd
--- /dev/null
+++ b/app/src/main/res/layout/activity_icc.xml
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
\ 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
new file mode 100644
index 0000000..a46568e
--- /dev/null
+++ b/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_pay.xml b/app/src/main/res/layout/activity_pay.xml
new file mode 100644
index 0000000..33feff2
--- /dev/null
+++ b/app/src/main/res/layout/activity_pay.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_response.xml b/app/src/main/res/layout/activity_response.xml
new file mode 100644
index 0000000..8578814
--- /dev/null
+++ b/app/src/main/res/layout/activity_response.xml
@@ -0,0 +1,262 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_setting.xml b/app/src/main/res/layout/activity_setting.xml
new file mode 100644
index 0000000..7c7b1ad
--- /dev/null
+++ b/app/src/main/res/layout/activity_setting.xml
@@ -0,0 +1,67 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_status.xml b/app/src/main/res/layout/activity_status.xml
new file mode 100644
index 0000000..c8025f2
--- /dev/null
+++ b/app/src/main/res/layout/activity_status.xml
@@ -0,0 +1,189 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/confirm.xml b/app/src/main/res/layout/confirm.xml
new file mode 100644
index 0000000..0b6d576
--- /dev/null
+++ b/app/src/main/res/layout/confirm.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/pop_up_message_no_option.xml b/app/src/main/res/layout/pop_up_message_no_option.xml
new file mode 100644
index 0000000..8156757
--- /dev/null
+++ b/app/src/main/res/layout/pop_up_message_no_option.xml
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/pop_up_message_option.xml b/app/src/main/res/layout/pop_up_message_option.xml
new file mode 100644
index 0000000..95c9ccf
--- /dev/null
+++ b/app/src/main/res/layout/pop_up_message_option.xml
@@ -0,0 +1,78 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/toolbar.xml b/app/src/main/res/layout/toolbar.xml
new file mode 100644
index 0000000..a7b6cce
--- /dev/null
+++ b/app/src/main/res/layout/toolbar.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/toolbar_setting.xml b/app/src/main/res/layout/toolbar_setting.xml
new file mode 100644
index 0000000..6ba3509
--- /dev/null
+++ b/app/src/main/res/layout/toolbar_setting.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 0000000..eca70cf
--- /dev/null
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 0000000..eca70cf
--- /dev/null
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_udc_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_udc_launcher.xml
new file mode 100644
index 0000000..77f652d
--- /dev/null
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_udc_launcher.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_udc_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_udc_launcher_round.xml
new file mode 100644
index 0000000..77f652d
--- /dev/null
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_udc_launcher_round.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..a571e60
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
new file mode 100644
index 0000000..61da551
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-hdpi/ic_udc_launcher.png b/app/src/main/res/mipmap-hdpi/ic_udc_launcher.png
new file mode 100644
index 0000000..94ce845
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_udc_launcher.png differ
diff --git a/app/src/main/res/mipmap-hdpi/ic_udc_launcher_foreground.png b/app/src/main/res/mipmap-hdpi/ic_udc_launcher_foreground.png
new file mode 100644
index 0000000..5eb4656
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_udc_launcher_foreground.png differ
diff --git a/app/src/main/res/mipmap-hdpi/ic_udc_launcher_round.png b/app/src/main/res/mipmap-hdpi/ic_udc_launcher_round.png
new file mode 100644
index 0000000..a7a868f
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_udc_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..c41dd28
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
new file mode 100644
index 0000000..db5080a
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_udc_launcher.png b/app/src/main/res/mipmap-mdpi/ic_udc_launcher.png
new file mode 100644
index 0000000..f78e2c9
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_udc_launcher.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_udc_launcher_foreground.png b/app/src/main/res/mipmap-mdpi/ic_udc_launcher_foreground.png
new file mode 100644
index 0000000..84b8542
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_udc_launcher_foreground.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_udc_launcher_round.png b/app/src/main/res/mipmap-mdpi/ic_udc_launcher_round.png
new file mode 100644
index 0000000..484aa4d
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_udc_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..6dba46d
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..da31a87
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_udc_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_udc_launcher.png
new file mode 100644
index 0000000..c57353a
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_udc_launcher.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_udc_launcher_foreground.png b/app/src/main/res/mipmap-xhdpi/ic_udc_launcher_foreground.png
new file mode 100644
index 0000000..056b07a
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_udc_launcher_foreground.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_udc_launcher_round.png b/app/src/main/res/mipmap-xhdpi/ic_udc_launcher_round.png
new file mode 100644
index 0000000..d3b3080
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_udc_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..15ac681
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..b216f2d
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_udc_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_udc_launcher.png
new file mode 100644
index 0000000..94d8de4
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_udc_launcher.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_udc_launcher_foreground.png b/app/src/main/res/mipmap-xxhdpi/ic_udc_launcher_foreground.png
new file mode 100644
index 0000000..d388506
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_udc_launcher_foreground.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_udc_launcher_round.png b/app/src/main/res/mipmap-xxhdpi/ic_udc_launcher_round.png
new file mode 100644
index 0000000..c7bcc34
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_udc_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..f25a419
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..e96783c
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_udc_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_udc_launcher.png
new file mode 100644
index 0000000..d49a5c7
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_udc_launcher.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_udc_launcher_foreground.png b/app/src/main/res/mipmap-xxxhdpi/ic_udc_launcher_foreground.png
new file mode 100644
index 0000000..531bd88
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_udc_launcher_foreground.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_udc_launcher_round.png b/app/src/main/res/mipmap-xxxhdpi/ic_udc_launcher_round.png
new file mode 100644
index 0000000..f36ee73
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_udc_launcher_round.png differ
diff --git a/app/src/main/res/values-night/themes.xml b/app/src/main/res/values-night/themes.xml
new file mode 100644
index 0000000..697d78f
--- /dev/null
+++ b/app/src/main/res/values-night/themes.xml
@@ -0,0 +1,16 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..e5e48ed
--- /dev/null
+++ b/app/src/main/res/values/colors.xml
@@ -0,0 +1,23 @@
+
+
+
+ #6200EE
+ #3700B3
+ #03DAC5
+ #8A8A8A
+
+ #FFBB86FC
+ #FF6200EE
+ #FF3700B3
+ #FF03DAC5
+ #FF018786
+ #FF000000
+ #FFFFFFFF
+
+ #FF0000
+ #FFEB3B
+ #00FF00
+ #2DCC70
+ #8e98a6
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..3e73b9c
--- /dev/null
+++ b/app/src/main/res/values/strings.xml
@@ -0,0 +1,77 @@
+
+
+ CST - Hello Kiosk
+
+
+ Title
+ Message
+ Please wait...
+ Ok
+ Cancel
+ Yes
+ No
+ Back
+
+
+ --Connection Status--
+
+ Online
+
+ Offline
+ Processing...
+
+ Connect
+ Disconnect
+ Check Connection Status
+ Trigger "Launch"
+ Trigger "Payment"
+ Refresh "Payment"
+ Previous "Payment"
+ Retry Payment
+
+
+ OK
+
+
+ Complete
+ Success!
+ OK
+
+
+ Transaction Detail
+ Transaction Type:
+ Merchant ID:
+ Terminal ID:
+ Batch No.:
+ Trace No.:
+ Invoice No.:
+ Ori. Invoice No.:
+ Transaction ID:
+ Customer ID:
+ Bank Ref. No.:
+ Description:
+ Date/Time:
+ Payment Scheme:
+ Payment Currency:
+ Payment Amount:
+ Status:
+ Voided At:
+ Inquiry
+ Void
+ Print Receipt
+
+
+ N/A
+
+
+ image
+ Donate Successful
+ Thank you for the contribution.
+ RM..
+ Payment Failed
+ Oops, your payment has failed!
+ Ok
+ Retry Payment
+ Cancel
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/style.xml b/app/src/main/res/values/style.xml
new file mode 100644
index 0000000..49ec9a5
--- /dev/null
+++ b/app/src/main/res/values/style.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml
new file mode 100644
index 0000000..3e82936
--- /dev/null
+++ b/app/src/main/res/values/themes.xml
@@ -0,0 +1,16 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/test/java/com/cst/im30/ExampleUnitTest.java b/app/src/test/java/com/cst/im30/ExampleUnitTest.java
new file mode 100644
index 0000000..8e9fb92
--- /dev/null
+++ b/app/src/test/java/com/cst/im30/ExampleUnitTest.java
@@ -0,0 +1,17 @@
+package com.cst.im30;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see Testing documentation
+ */
+public class ExampleUnitTest {
+ @Test
+ public void addition_isCorrect() {
+ assertEquals(4, 2 + 2);
+ }
+}
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000..89a5a5d
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,26 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+buildscript {
+ repositories {
+ google()
+ mavenCentral()
+ }
+ dependencies {
+ //noinspection AndroidGradlePluginVersion
+ classpath 'com.android.tools.build:gradle:3.4.1'
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+}
+
+allprojects {
+ repositories {
+ google()
+ mavenCentral()
+ maven { url 'https://jitpack.io' }
+ //jcenter() // Warning: this repository is going to shut down soon
+ }
+}
+
+task clean(type: Delete) {
+ delete rootProject.buildDir
+}
\ No newline at end of file
diff --git a/gradle.properties b/gradle.properties
new file mode 100644
index 0000000..76356a6
--- /dev/null
+++ b/gradle.properties
@@ -0,0 +1,18 @@
+# Project-wide Gradle settings.
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
+# AndroidX package structure to make it clearer which packages are bundled with the
+# Android operating system, and which are packaged with your app"s APK
+# https://developer.android.com/topic/libraries/support-library/androidx-rn
+android.useAndroidX=true
+android.enableJetifier=true
\ No newline at end of file
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..f6b961f
Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..e72f266
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Fri Jul 16 14:20:26 SGT 2021
+distributionBase=GRADLE_USER_HOME
+distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip
+distributionPath=wrapper/dists
+zipStorePath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
diff --git a/gradlew b/gradlew
new file mode 100644
index 0000000..cccdd3d
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,172 @@
+#!/usr/bin/env sh
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=$(save "$@")
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
+ cd "$(dirname "$0")"
+fi
+
+exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100644
index 0000000..f955316
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,84 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/settings.gradle b/settings.gradle
new file mode 100644
index 0000000..332f54e
--- /dev/null
+++ b/settings.gradle
@@ -0,0 +1,2 @@
+rootProject.name = "kiosk-im30"
+include ':app'