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 @@ + + + +