Commit b5ebd25e authored by Ahmad Abi Mulya's avatar Ahmad Abi Mulya

fix some bug

parent ff37e1b7
ImplementationPartnerConnect
\ No newline at end of file
...@@ -51,13 +51,13 @@ dependencies { ...@@ -51,13 +51,13 @@ dependencies {
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1' implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
implementation 'io.reactivex.rxjava2:rxjava:2.2.10' implementation 'io.reactivex.rxjava2:rxjava:2.2.10'
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.4.0' implementation 'com.squareup.retrofit2:adapter-rxjava2:2.4.0'
implementation(group: 'com.mdd.payment', name: 'mybanklibrary-release', version: '3.5.8', ext: 'aar') implementation(group: 'com.mdd.payment', name: 'mybanklibrary-release', version: '3.5.9', ext: 'aar')
implementation(group: 'com.mdd.payment', name: 'nativecripto-release', version: '2.0.0', ext: 'aar') implementation(group: 'com.mdd.payment', name: 'nativecripto-release', version: '2.0.0', ext: 'aar')
implementation(group: 'com.mdd.payment', name: 'organicdrv-release', version: '2.1.0', ext: 'aar') implementation(group: 'com.mdd.payment', name: 'organicdrv-release', version: '2.1.0', ext: 'aar')
implementation(group: 'com.mdd.payment', name: 'isodeplibrary-release', version: '2.1.1', ext: 'aar') implementation(group: 'com.mdd.payment', name: 'isodeplibrary-release', version: '2.1.1', ext: 'aar')
implementation(group: 'com.mdd.payment', name: 'z91library-release', version: '2.1.0', ext: 'aar') implementation(group: 'com.mdd.payment', name: 'z91library-release', version: '2.1.0', ext: 'aar')
implementation(group: 'com.mdd.payment', name: 'aar-deviceid-release', version: '2.0.4', ext: 'aar') implementation(group: 'com.mdd.payment', name: 'aar-deviceid-release', version: '2.0.4', ext: 'aar')
implementation(group: 'com.mdd.service', name: 'partner-connect', version: '2.2.5', ext: 'aar') implementation(group: 'com.mdd.service', name: 'partner-connect', version: '2.2.7', ext: 'aar')
implementation(group: 'com.mdd.topup', name: 'update-balance', version: '2.3.5', ext: 'aar') implementation(group: 'com.mdd.topup', name: 'update-balance', version: '2.4.0', ext: 'aar')
} }
\ No newline at end of file
package id.mdd.implementationpartnerconnect;
import com.mdd.topupUnik.ubal.InitReader;
public interface InitListener {
void onInitReaderComplete(InitReader reader);
}
\ No newline at end of file
package id.mdd.implementationpartnerconnect; package id.mdd.implementationpartnerconnect;
import android.Manifest; import android.Manifest;
import android.app.AlertDialog;
import android.content.AsyncQueryHandler; import android.content.AsyncQueryHandler;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.media.MediaPlayer;
import android.nfc.NfcAdapter; import android.nfc.NfcAdapter;
import android.nfc.NfcManager; import android.nfc.NfcManager;
import android.nfc.Tag; import android.nfc.Tag;
import android.os.AsyncTask;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.CountDownTimer; import android.os.CountDownTimer;
import android.os.Message; import android.os.Message;
import android.os.StrictMode;
import android.util.Log; import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat; import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import com.mdd.topupUnik.ubal.InitReader; import com.mdd.topupUnik.ubal.InitReader;
import com.mdd.topupUnik.ubal.MainCardProcessor; import com.mdd.topupUnik.ubal.MainCardProcessor;
import com.mdd.topupUnik.ubal.ReversalObject;
import com.mdd.topupUnik.ubal.SuccessUpdateBalance; import com.mdd.topupUnik.ubal.SuccessUpdateBalance;
import com.mdd.topupUnik.ubal.UpdateBalanceView; import com.mdd.topupUnik.ubal.UpdateBalanceView;
import com.mdd.topupUnik.ubal.http.response.CardBalanceAPDUResponse;
import com.mdd.topupUnik.ubal.lib.CardInfo; import com.mdd.topupUnik.ubal.lib.CardInfo;
import com.mdd.topupUnik.ubal.lib.CardInfoCommand; import com.mdd.topupUnik.ubal.lib.CardInfoCommand;
import com.mdd.topupUnik.ubal.lib.CommandResult; import com.mdd.topupUnik.ubal.lib.CommandResult;
import com.mdd.topupUnik.ubal.lib.FindCardResponse; import com.mdd.topupUnik.ubal.lib.FindCardResponse;
import com.medicom.organicdrv.OrganicDriver; import com.medicom.organicdrv.OrganicDriver;
import java.io.IOException;
import java.net.InetAddress;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.NumberFormat;
import java.util.Locale;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import id.emhusnan.mdd.service.MDDCommand; import id.emhusnan.mdd.service.MDDCommand;
import id.emhusnan.mdd.service.MDDService; import id.emhusnan.mdd.service.MDDService;
import id.emhusnan.mdd.service.MDDUpdateBalanceView; import id.emhusnan.mdd.service.MDDUpdateBalanceView;
...@@ -40,85 +69,253 @@ import static com.medicom.organicdrv.utilsLib.ByteArrayToHexString; ...@@ -40,85 +69,253 @@ import static com.medicom.organicdrv.utilsLib.ByteArrayToHexString;
import static id.emhusnan.mdd.service.MDDCommand.COMMAND_GET_BALANCE; import static id.emhusnan.mdd.service.MDDCommand.COMMAND_GET_BALANCE;
import static id.emhusnan.mdd.service.MDDCommand.COMMAND_UPDATE_BALANCE; import static id.emhusnan.mdd.service.MDDCommand.COMMAND_UPDATE_BALANCE;
public class MainActivity extends AppCompatActivity implements MDDUpdateBalanceView, NfcAdapter.ReaderCallback { public class MainActivity extends AppCompatActivity implements MDDUpdateBalanceView, InitListener, NfcAdapter.ReaderCallback {
@BindView(R.id.pgProcess)
ProgressBar mProgress;
@BindView(R.id.pbloading)
ProgressBar pbloading;
@BindView(R.id.txtStatus)
TextView mOpsResult;
@BindView(R.id.textCardBalance)
TextView textBalance;
@BindView(R.id.textCardBalanceNew)
TextView textNewBalance;
@BindView(R.id.textCardNumber)
TextView textCardNumber;
@BindView(R.id.txtAmount)
TextView textAmount;
@BindView(R.id.bgCard)
LinearLayout bgCard;
@BindView(R.id.logoCard)
ImageView logoCard;
@BindView(R.id.btnUpdateBalance)
Button btnUpdateBalance;
@BindView(R.id.btnGantiKartu)
ImageButton btnGantiKartu;
private long oldBalance;
private boolean working = false;
DecimalFormat formatter = (DecimalFormat) NumberFormat.getInstance(Locale.US);
private int MY_PERMISSIONS_REQUEST_READ_CONTACTS = 1;
private static final int STORAGE_PERMISSION_CODE = 101;
private int COMMAND = MDDCommand.COMMAND_GET_BALANCE;
private String TAG = "MDDService"; private String TAG = "MDDService";
private int COMMAND = COMMAND_GET_BALANCE; boolean hasPendingOperation = false;
private InitReader reader; @BindView(R.id.btnAktivasiAar)
Button btnAktivasiAar;
private MainCardProcessor cardProcessor; private MainCardProcessor cardProcessor;
private boolean isProcessingTag; private InitReader reader;
private UpdateBalanceUiThreadHandler updateBalanceUiThreadHandler;
protected int getCommand() { protected int getCommand() {
return COMMAND; return COMMAND;
} }
CountDownTimer timer = new CountDownTimer(7000, 1000) { @OnClick(R.id.btnGantiKartu)
@Override void gantiKartuClicked() {
public void onTick(long millisUntilFinished) { setCommand(MDDCommand.COMMAND_GET_BALANCE);
Log.d(TAG, "## ticker timed out remaining: " + millisUntilFinished / 1000 + "s"); Log.d("btnGantiKartu", "clicked");
Toast.makeText(this, "Tempel kartu anda..", Toast.LENGTH_SHORT).show();
// execute();
} }
@Override @OnClick(R.id.btnUpdateBalance)
public void onFinish() { void updateBalance() {
if (isProcessingTag) { setCommand(MDDCommand.COMMAND_UPDATE_BALANCE);
Message msg = UpdateBalanceUiMessageFactory.updateBalanceErrorMsg( Log.d("btnUpdateBalance", "clicked");
"Timed out" Toast.makeText(this, "Tempel kartu anda..", Toast.LENGTH_SHORT).show();
); // execute();
sendToUI(msg);
} }
private void setCommand(int commandUpdateBalance) {
COMMAND = commandUpdateBalance;
btnUpdateBalance.setText(COMMAND == MDDCommand.COMMAND_UPDATE_BALANCE ? "Update Balance" : "Cek Balance");
} }
};
@Override @Override
protected void onCreate(Bundle savedInstanceState) { public void onCreate(@Nullable Bundle savedInstanceState) {
// Here, thisActivity is the current activity validateHasPermissions();
if (ContextCompat.checkSelfPermission(this, super.onCreate(savedInstanceState);
Manifest.permission.READ_PHONE_STATE) setContentView(R.layout.activity_main);
!= PackageManager.PERMISSION_GRANTED) { ButterKnife.bind(this);
// config = Config.load(this);
if (isInternetAvailable()) {
setUp();
NfcManager manager = (NfcManager) getSystemService(Context.NFC_SERVICE);
NfcAdapter adapter = manager.getDefaultAdapter();
Log.d(TAG, "adapter:" + adapter + "," + Build.MODEL + "," + Build.BRAND);
if (adapter == null || !adapter.isEnabled()) {
displayResult(R.color.text_error, R.string.nfc_not_found);
}
} else {
Toast.makeText(MainActivity.this, getResources().getString(R.string.connection_error), Toast.LENGTH_SHORT).show();
hideProgressBar();
hideResult();
showDialog();
}
reader = ((MyApp) getApplication()).getReader();
Log.d("ReaderApp", String.valueOf(reader));
// cardProcessor = new MainCardProcessor(MainActivity.this, reader, new UpdateBalanceView() {
// @Override
// public void onUpdateBalanceSuccess(SuccessUpdateBalance successUpdateBalance) {
// runOnUiThread(() -> MainActivity.this.onUpdateBalaceSuccess(successUpdateBalance));
// }
//
// @Override
// public void onUpdateBalanceError(String reason) {
// runOnUiThread(() -> MainActivity.this.onUpdateBalanceError(reason));
// }
//
// @Override
// public void onCardDetected(CardInfo cardInfo) {
// Log.d("Card", "card kedetek nih");
// runOnUiThread(() -> MainActivity.this.onBalanceInfoAvailable(cardInfo));
// }
//
// @Override
// public void onErrorNfcCardMsg(int errorCode) {
// runOnUiThread(() -> MainActivity.this.onUpdateBalanceError(""));
// }
// });
// cardProcessor.getBalance();
Tag tagFromIntent = getIntent().getParcelableExtra(NfcAdapter.EXTRA_TAG);
if (tagFromIntent != null) {
onTagDiscovered(tagFromIntent);
}
}
// private void getBalance() {
// Log.d("getBalance", "udh sampe getbalance");
// String response = new Gson().toJson(cardProcessor.findCardUid());
// Log.d("response", response);
// FindCardResponse response1 = cardProcessor.findCardUid();
// response1.getUid();
//
// CardInfoCommand command = new CardInfoCommand(reader.myReader);
// final CommandResult<CardInfo> execute = command.execute(cardProcessor.findCardUid());
// CardInfo cardInfo = execute.getResult();
// Log.d("CardInfo", "Ini card infonya bro : "+cardInfo);
//
// }
private void hideResult() {
mOpsResult.setVisibility(View.GONE);
}
private void showProgressBar() {
mProgress.setVisibility(View.VISIBLE);
}
private void validateHasPermissions() {
if (Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
// permission READ_PHONE_STATE
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "Please grant permission", Toast.LENGTH_SHORT).show(); Toast.makeText(this, "Please grant permission", Toast.LENGTH_SHORT).show();
// Permission is not granted
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(this, if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.READ_PHONE_STATE)) { Manifest.permission.READ_PHONE_STATE)) {
// Show an explanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
} else { } else {
// No explanation needed; request the permission
ActivityCompat.requestPermissions(this, ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.READ_PHONE_STATE, Manifest.permission.INTERNET, Manifest.permission.WRITE_EXTERNAL_STORAGE}, new String[]{Manifest.permission.READ_PHONE_STATE,
1); Manifest.permission.INTERNET,
Manifest.permission.READ_EXTERNAL_STORAGE},
MY_PERMISSIONS_REQUEST_READ_CONTACTS);
} }
} else {
// Permission has already been granted
((MyApp) getApplication()).initConfig();
} else {
Log.d("validate", "Mau init niih");
((MyApp) getApplication()).initConfig(this);
}
} }
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
updateBalanceUiThreadHandler = new UpdateBalanceUiThreadHandler(getMDDView());
setCommand(COMMAND_GET_BALANCE);
enableReaderMode();
}
@Override @Override
protected void onResume() { protected void onResume() {
super.onResume(); super.onResume();
// FindCardResponse findCardResponse = cardProcessor.findCardUid(); if (isInternetAvailable()) {
// Log.e("findCardResponse", findCardResponse.getUid() + " " + findCardResponse.getCardType()); setCommand(MDDCommand.COMMAND_GET_BALANCE);
// execute();
NfcManager manager = (NfcManager) getSystemService(Context.NFC_SERVICE);
NfcAdapter adapter = manager.getDefaultAdapter();
final int READER_FLAGS = NfcAdapter.FLAG_READER_NFC_A | NfcAdapter.FLAG_READER_SKIP_NDEF_CHECK;
if (adapter != null && adapter.isEnabled()) {
adapter.enableReaderMode(this, this, READER_FLAGS, null);
}
// if (EMoneyUtils.isPax()) {
//// Log.d(TAG, "IS PAX");
//// if (eMoneyUtils == null) {
//// displayResult(R.color.text_error, R.string.error_not_setup);
//// return;
//// }
//// if (eMoneyUtils == null) return;
//// if (working) return;
//// displayResult(R.color.text_normal, R.string.keep_tap);
//// showProgressBar();
//// findViewById(R.id.lyUpdateBalance).setVisibility(View.GONE);
//// COMMAND = MDDCommand.COMMAND_GET_BALANCE;
// } else {
// setCommand(MDDCommand.COMMAND_GET_BALANCE);
//
// NfcManager manager = (NfcManager) getSystemService(Context.NFC_SERVICE);
// NfcAdapter adapter = manager.getDefaultAdapter();
// Log.d(TAG, "adapter:" + adapter + "," + Build.MODEL + "," + Build.BRAND);
//
// if (adapter == null || !adapter.isEnabled()) {
// displayResult(R.color.text_error, R.string.nfc_not_found);
// }
// }
} else {
Toast.makeText(MainActivity.this, getResources().getString(R.string.connection_error), Toast.LENGTH_SHORT).show();
hideProgressBar();
hideResult();
showDialog();
}
}
@Override
protected void onPause() {
super.onPause();
NfcManager manager = (NfcManager) getSystemService(Context.NFC_SERVICE); NfcManager manager = (NfcManager) getSystemService(Context.NFC_SERVICE);
NfcAdapter adapter = manager.getDefaultAdapter(); NfcAdapter adapter = manager.getDefaultAdapter();
Log.d(TAG, "adapter:" + adapter + "," + Build.MODEL + "," + Build.BRAND); if (adapter != null && adapter.isEnabled()) {
adapter.disableReaderMode(this);
}
} }
private void displayResult(int p, int p2) {
mOpsResult.setTextColor(getColorRes(p));
mOpsResult.setText(p2);
}
private void setUp() {
DecimalFormatSymbols symbols = formatter.getDecimalFormatSymbols();
symbols.setGroupingSeparator('.');
formatter.setDecimalFormatSymbols(symbols);
TextView text = findViewById(R.id.version);
try {
PackageInfo pInfo = getPackageManager().getPackageInfo(getPackageName(), 0);
String version = pInfo.versionName;
text.setText("Version: " + version);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
hideProgressBar();
private void setCommand(int commandUpdateBalance) {
COMMAND = commandUpdateBalance;
} }
protected MDDUpdateBalanceView getMDDView() { protected MDDUpdateBalanceView getMDDView() {
...@@ -127,168 +324,314 @@ public class MainActivity extends AppCompatActivity implements MDDUpdateBalanceV ...@@ -127,168 +324,314 @@ public class MainActivity extends AppCompatActivity implements MDDUpdateBalanceV
@Override @Override
public void onNFcCardNotSupported(int error_code) { public void onNFcCardNotSupported(int error_code) {
Toast.makeText(this, "onNFcCardNotSupported " + error_code, Toast.LENGTH_SHORT).show(); hasPendingOperation = false;
Toast.makeText(MainActivity.this, R.string.nfc_not_found, Toast.LENGTH_SHORT).show();
NfcManager manager = (NfcManager) getSystemService(Context.NFC_SERVICE);
NfcAdapter adapter = manager.getDefaultAdapter();
Log.d(TAG, "adapter:" + adapter + "," + Build.MODEL + "," + Build.BRAND);
if (adapter == null || !adapter.isEnabled()) {
mOpsResult.setTextColor(getResources().getColor(R.color.text_error));
mOpsResult.setText(R.string.nfc_not_found);
}
showProgressBar();
displayResult(R.color.text_normal, R.string.nfc_not_found);
findViewById(R.id.lyUpdateBalance).setVisibility(View.GONE);
} }
@Override @Override
public void onNfcCardFound() { public void onNfcCardFound() {
Toast.makeText(this, "Card found", Toast.LENGTH_SHORT).show(); hasPendingOperation = true;
Toast.makeText(MainActivity.this, "Mohon Tunggu...", Toast.LENGTH_LONG).show();
showProgressBar();
displayResult(R.color.text_normal, R.string.keep_tap);
btnGantiKartu.setEnabled(false);
findViewById(R.id.lyUpdateBalance).setVisibility(View.GONE);
} }
@Override @Override
public void onFinishOperation() { public void onFinishOperation() {
Log.d(TAG, "onFinishOperation: "); hasPendingOperation = false;
Toast.makeText(MainActivity.this, "On Finishoperation", Toast.LENGTH_SHORT).show();
} }
@Override
public void onBeginOperation() {
hasPendingOperation = true;
Toast.makeText(MainActivity.this, "Begin Transaction", Toast.LENGTH_SHORT).show();
Log.d(TAG, "onBeginOperation: ");
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
displayResult(R.color.text_normal, R.string.keep_tap);
btnGantiKartu.setEnabled(false);
showProgressBar();
findViewById(R.id.lyUpdateBalance).setVisibility(View.GONE);
}
@Override @Override
public void onBalanceInfoAvailable(CardInfo cardInfo) { public void onBalanceInfoAvailable(CardInfo cardInfo) {
Log.d(TAG, "Hai guys udh sampe onbalanceinfoavailable loh ...");
hasPendingOperation = false;
Log.d(TAG, "onBalanceInfoAvailable: " + cardInfo.getBalance()); Log.d(TAG, "onBalanceInfoAvailable: " + cardInfo.getBalance());
Toast.makeText(this, "Balance " + cardInfo.getBalance(), Toast.LENGTH_SHORT).show();
COMMAND = COMMAND_UPDATE_BALANCE; runOnUiThread(() -> {
mProgress.setVisibility(View.INVISIBLE);
if (cardInfo.getBankType().equals("BNI")) {
bgCard.getBackground().setColorFilter(Color.parseColor("#F6630E"), PorterDuff.Mode.SRC_ATOP);
logoCard.setImageResource(R.drawable.tapcash_logo);
} else {
bgCard.getBackground().setColorFilter(Color.parseColor("#013C76"), PorterDuff.Mode.SRC_ATOP);
logoCard.setImageResource(R.drawable.logo_emoney);
}
oldBalance = cardInfo.getBalance();
textBalance.setText("Rp " + formatter.format(cardInfo.getBalance()));
textCardNumber.setText(cardInfo.getCardNumber());
mOpsResult.setTextColor(getColorRes(R.color.text_normal));
mOpsResult.setText(getResources().getString(R.string.TapMore));
setCommand(MDDCommand.COMMAND_UPDATE_BALANCE);
});
beep();
} }
@Override @Override
public void onUpdateBalaceSuccess(SuccessUpdateBalance successUpdateBalance) { public void onUpdateBalaceSuccess(SuccessUpdateBalance successUpdateBalance) {
hasPendingOperation = false;
Log.d(TAG, "onUpdateBalaceSuccess: " + successUpdateBalance.getBalance());
Log.d(TAG, "onUpdateBalaceSuccess: " + successUpdateBalance.getMessage()); Log.d(TAG, "onUpdateBalaceSuccess: " + successUpdateBalance.getMessage());
Toast.makeText(this, successUpdateBalance.getMessage(), Toast.LENGTH_SHORT).show(); String appletType = successUpdateBalance.getAppletType().toUpperCase();
String message = successUpdateBalance.getMessage();
if (!message.contains("Tidak ada Pending Balance")) {
long amount = successUpdateBalance.getBalance() - oldBalance;
findViewById(R.id.lyUpdateBalance).setVisibility(View.VISIBLE);
textBalance.setText("Rp " + formatter.format(successUpdateBalance.getBalance()));
textAmount.setText("Rp " + formatter.format(amount));
textNewBalance.setText("Rp " + formatter.format(successUpdateBalance.getBalance()));
displayResult(R.color.text_success, R.string.update_success);
hideProgressBar();
beep();
oldBalance = successUpdateBalance.getBalance();
} else {
findViewById(R.id.lyUpdateBalance).setVisibility(View.GONE);
displayResult(R.color.text_success, R.string.no_pending_balance);
mProgress.setVisibility(View.INVISIBLE);
}
}
private void beep() {
MediaPlayer mp = MediaPlayer.create(this, R.raw.beep);
mp.start();
}
private void hideProgressBar() {
mProgress.setVisibility(View.GONE);
} }
@Override @Override
public void onUpdateBalanceError(String reason) { public void onUpdateBalanceError(String reason) {
hasPendingOperation = false;
mProgress.setVisibility(View.INVISIBLE);
findViewById(R.id.lyUpdateBalance).setVisibility(View.GONE);
Log.d(TAG, "onUpdateBalanceError: " + reason); Log.d(TAG, "onUpdateBalanceError: " + reason);
Log.i("ErrorUB", reason);
if (reason.equalsIgnoreCase("Timed out")) {
displayResult(R.color.text_error, R.string.connection_error);
} else if (reason.contains("Reversal Success")) {
Log.d("onUpdateBalanceError", "Halo Anda sudah di onupdatebalance error");
displayResult(R.color.text_error, R.string.reversal_success);
} else {
displayResult(R.color.text_error, R.string.update_balance_failed);
}
}
private int getColorRes(int res) {
if (Build.VERSION.SDK_INT < 23) {
return getResources().getColor(res);
}
return getColor(res);
}
public boolean isInternetAvailable() {
try {
InetAddress ipAddr = InetAddress.getByName("google.com");
return !ipAddr.equals("");
} catch (Exception e) {
return false;
}
}
private void showDialog() {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
alertDialogBuilder.setTitle("Butuh koneksi internet");
alertDialogBuilder
.setMessage("Koneksi internet diperlukan untuk update balance silahkan ulangi")
.setIcon(R.mipmap.ic_launcher)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
} }
});
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
}
InitReader paxReader = null;
// private void execute() {
// Log.d("Execute", "execute dipanggil");
// AsyncTask.execute(new Runnable() {
// @Override
// public void run() {
// FindCardResponse findCardResponse = cardProcessor.findCardUid();
// String cardUid = findCardResponse.getUid();
// Log.d("cardUid", cardUid);
// boolean hasCardUid = !cardUid.isEmpty();
// if (hasCardUid) {
// Log.d(TAG, "---> Send to UI Card Found");
// runOnUiThread(new Runnable() {
// @Override
// public void run() {
// onNfcCardFound();
// }
// });
//
// CardInfoCommand command = new CardInfoCommand(paxReader.myReader);
//
// final CommandResult<CardInfo> execute = command.execute(findCardResponse);
// CardInfo detectedCardInfo = execute.getResult();
// if (execute.isSuccess()) {
// switch (getCommand()) {
// case MDDCommand.COMMAND_GET_BALANCE:
// cardProcessor.getBalance(detectedCardInfo);
// break;
// case MDDCommand.COMMAND_UPDATE_BALANCE:
// cardProcessor.updateBalance(detectedCardInfo, 1);
// break;
// }
// } else {
// runOnUiThread(() -> {
// MainActivity.this.onUpdateBalanceError("Kartu tidak terdeteksi");
// });
// }
//
//
// } else {
// //wrong card type
// }
// }
// });
// }
@Override @Override
public void onBeginOperation() { public void onInitReaderComplete(InitReader reader) {
Log.d(TAG, "onBeginOperation: "); paxReader = reader;
pbloading.setVisibility(View.GONE);
cardProcessor = new MainCardProcessor(MainActivity.this, reader, new UpdateBalanceView() {
@Override
public void onUpdateBalanceSuccess(SuccessUpdateBalance successUpdateBalance) {
runOnUiThread(() -> MainActivity.this.onUpdateBalaceSuccess(successUpdateBalance));
}
@Override
public void onUpdateBalanceError(String reason) {
runOnUiThread(() -> MainActivity.this.onUpdateBalanceError(reason));
} }
@Override
public void onCardDetected(CardInfo cardInfo) {
runOnUiThread(() -> MainActivity.this.onBalanceInfoAvailable(cardInfo));
}
@Override
public void onErrorNfcCardMsg(int errorCode) {
runOnUiThread(() -> MainActivity.this.onUpdateBalanceError(""));
}
});
}
@Override @Override
public void onTagDiscovered(Tag tag) { public void onTagDiscovered(Tag tag) {
reader = MDDService.getInstance().getInitReader();
cardProcessor = new MainCardProcessor(this, reader, new UpdateBalanceView() { cardProcessor = new MainCardProcessor(MainActivity.this, paxReader, new UpdateBalanceView() {
@Override @Override
public void onUpdateBalanceSuccess(SuccessUpdateBalance successUpdateBalance) { public void onUpdateBalanceSuccess(SuccessUpdateBalance successUpdateBalance) {
runOnUiThread(() -> onUpdateBalaceSuccess(successUpdateBalance)); runOnUiThread(() -> MainActivity.this.onUpdateBalaceSuccess(successUpdateBalance));
} }
@Override @Override
public void onUpdateBalanceError(String reason) { public void onUpdateBalanceError(String reason) {
runOnUiThread(() -> onUpdateBalanceError(reason)); runOnUiThread(() -> MainActivity.this.onUpdateBalanceError(reason));
} }
@Override @Override
public void onCardDetected(CardInfo cardInfo) { public void onCardDetected(CardInfo cardInfo) {
runOnUiThread(() -> onBalanceInfoAvailable(cardInfo)); Log.d("Card", "card kedetek nih");
runOnUiThread(() -> MainActivity.this.onBalanceInfoAvailable(cardInfo));
} }
@Override @Override
public void onErrorNfcCardMsg(int errorCode) { public void onErrorNfcCardMsg(int errorCode) {
runOnUiThread(() -> onUpdateBalanceError("")); runOnUiThread(() -> MainActivity.this.onUpdateBalanceError(""));
} }
}); });
if(reader == null){
Toast.makeText(this, "please activate library", Toast.LENGTH_SHORT).show();
}else{
String cardUid = ByteArrayToHexString(tag.getId()); String cardUid = ByteArrayToHexString(tag.getId());
cardProcessor.lockIsoDepCard(tag); cardProcessor.lockIsoDepCard(tag);
Log.d("TagFromIntent", cardUid);
boolean hasCardUid = !cardUid.isEmpty(); boolean hasCardUid = !cardUid.isEmpty();
if (hasCardUid) { if (hasCardUid) {
Log.d(TAG, "---> UID : " + cardUid);
setProcessingTag();
// IsoDep iso = IsoDep.get(tag);
// try {
// iso.connect();
// } catch (IOException e) {
// e.printStackTrace();
// }
// iso.setTimeout(10000);
Log.d(TAG, "---> Send to UI Card Found"); Log.d(TAG, "---> Send to UI Card Found");
// final Message msg = UpdateBalanceUiMessageFactory.nfcCardFoundMsg(); runOnUiThread(new Runnable() {
// sendToUI(msg); @Override
public void run() {
onNfcCardFound();
}
});
CardInfoCommand command = new CardInfoCommand(reader.myReader); CardInfoCommand command = new CardInfoCommand(paxReader.myReader);
FindCardResponse findCardResponse = new FindCardResponse(); Log.e("myReader", "Myreader : "+paxReader.myReader);
findCardResponse.setUid(cardUid);
findCardResponse.setCardType(OrganicDriver.CARDTYPE_JAVA);
final CommandResult<CardInfo> execute = command.execute(findCardResponse); final CommandResult<CardInfo> execute = command.execute(cardUid);
CardInfo detectedCardInfo = execute.getResult(); CardInfo detectedCardInfo = execute.getResult();
Log.d("cardInfo", "ini card infonnya bro : "+detectedCardInfo);
Log.d("executeSuccess", "executeIsSuccess = " + execute.isSuccess());
if (execute.isSuccess()) { if (execute.isSuccess()) {
switch (getCommand()) { switch (getCommand()) {
case COMMAND_GET_BALANCE: case MDDCommand.COMMAND_GET_BALANCE:
Log.d(TAG, "getBalance");
cardProcessor.getBalance(detectedCardInfo); cardProcessor.getBalance(detectedCardInfo);
break; break;
case COMMAND_UPDATE_BALANCE: case MDDCommand.COMMAND_UPDATE_BALANCE:
Log.d(TAG, "updateBalance");
cardProcessor.updateBalance(detectedCardInfo, 1); cardProcessor.updateBalance(detectedCardInfo, 1);
break; break;
} }
} else { } else {
if (execute.getMessage().equals("27266")) {//27266 int of 6A82: Bank not activatated runOnUiThread(() -> {
sendToUI(UpdateBalanceUiMessageFactory.errorNfcCardMsg(ERROR_DIFFERENT_ISSUER_CARD)); Log.e("error", "Messagenya : "+execute.getMessage());
} else { MainActivity.this.onUpdateBalanceError("Kartu tidak terdeteksi");
sendToUI(UpdateBalanceUiMessageFactory.errorNfcCardMsg(ERROR_CARD_NOT_SUPPORTED));
}
setNotProcessingTag();
cardProcessor.unlockIsoDepCard(); cardProcessor.unlockIsoDepCard();
});
} }
} else { } else {
sendToUI(UpdateBalanceUiMessageFactory.errorNfcCardMsg(ERROR_CARD_NOT_SUPPORTED)); //wrong card type
setNotProcessingTag();
cardProcessor.unlockIsoDepCard(); cardProcessor.unlockIsoDepCard();
}
}
}
protected void setNotProcessingTag() {
isProcessingTag = false;
Log.d(TAG, "--> Mark tag processing finish");
timer.cancel();
Log.d(TAG, "--> Cancel time out timer");
} }
protected void setProcessingTag() {
isProcessingTag = true;
Log.d(TAG, "--> Mark tag on process");
timer.start();
Log.d(TAG, "--> Start countdown timer for timed out");
} }
private void sendToUI(Message msg) { private String convertToNumber(String number) {
updateBalanceUiThreadHandler.handleMessage(msg); StringBuilder builder = new StringBuilder();
builder.append(number.substring(0, 4));
builder.append(" ").append(number.substring(4, 8));
builder.append(" ").append(number.substring(8, 12));
builder.append(" ").append(number.substring(12));
return builder.toString();
} }
@Override
protected void onDestroy() {
super.onDestroy();
disableReaderMode();
}
private void enableReaderMode() {
int READER_FLAGS = NfcAdapter.FLAG_READER_NFC_A | NfcAdapter.FLAG_READER_SKIP_NDEF_CHECK;
NfcAdapter nfc = NfcAdapter.getDefaultAdapter(this);
if (nfc != null && nfc.isEnabled())
nfc.enableReaderMode(this, this, READER_FLAGS, null);
}
private void disableReaderMode() {
if (!isDestroyed()) {
NfcAdapter nfc = NfcAdapter.getDefaultAdapter(this);
if (nfc != null && nfc.isEnabled())
nfc.disableReaderMode(this);
}
}
} }
\ No newline at end of file
...@@ -7,15 +7,23 @@ import android.content.pm.PackageManager; ...@@ -7,15 +7,23 @@ import android.content.pm.PackageManager;
import android.os.Build; import android.os.Build;
import android.telephony.TelephonyManager; import android.telephony.TelephonyManager;
import android.util.Log; import android.util.Log;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.Toast; import android.widget.Toast;
import com.mdd.aar.deviceid.AarDeviceId; import com.mdd.aar.deviceid.AarDeviceId;
import com.mdd.aar.deviceid.DeviceEnvironment; import com.mdd.aar.deviceid.DeviceEnvironment;
import com.mdd.aar.deviceid.exceptions.DeviceNotRegisteredException; import com.mdd.aar.deviceid.exceptions.DeviceNotRegisteredException;
import com.mdd.topupUnik.ubal.InitReader; import com.mdd.topupUnik.ubal.InitReader;
import com.medicom.dudikov.mybanklibrary.nativeLib;
import butterknife.BindView;
import id.emhusnan.mdd.service.ConfigService; import id.emhusnan.mdd.service.ConfigService;
import id.emhusnan.mdd.service.MDDService; import id.emhusnan.mdd.service.MDDService;
import io.reactivex.SingleObserver;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
public class MyApp extends Application { public class MyApp extends Application {
String GIVE_MID = "ba7db816e59612f8ce1630a095ef01c5"; // please ask us for credential String GIVE_MID = "ba7db816e59612f8ce1630a095ef01c5"; // please ask us for credential
...@@ -23,10 +31,15 @@ public class MyApp extends Application { ...@@ -23,10 +31,15 @@ public class MyApp extends Application {
String GIVEN_TOKEN = "5b423ef49cb029340d7231cace0de201";// please ask us for credential String GIVEN_TOKEN = "5b423ef49cb029340d7231cace0de201";// please ask us for credential
private final String accessToken = "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJhdXRoLXNlcnZpY2U6MS4wLjAiLCJzdWIiOnsibmFtZSI6IlRlc3RQcm9kMyIsInVzZXJuYW1lIjoiVGVzdFByb2QzIiwiYXV0aF9sZXZlbCI6Ik1FUkNIQU5UIiwibWlkIjoiMWZiNTdmMTY2YTQ4MGU5N2JmN2EzZGNiZjkzMTkyOTMifSwiaWF0IjoxNTk3NzM3NzIxLCJleHAiOjE1OTc4MjQxMjEsIm5iZiI6MTU5NzczNzcyM30.CXM-5mCv91Yo17c9zHXQKPGR5gqAeu-LADta-_qnABYxzmnE4Dx0q7NQ9IYr6cYO6cXp40UW4s632fzVYmPCXH8f0RtSwLPqTT7_lWHK--fHCP-LZOmfgwUBxdNocYY9xAi-NyWqCmTnkjWx91lqh9S9Fcue6nO_KrBqngUpBPhpS0hPwgmkqHXX6yAdVs931NbfNM3cYW9PpGIw8K-OxoPDHByD61uAFxT9FCrTbca7vV3HFQnZEKpwxxdECu7DCQAsGTl7JqfbH2j5swe_t97rSDAGyE1HRzGX-SMqPULkC-XravF2m_HucosacYQuSdRaxAWfEIQvtQhAcRXwTA"; private final String accessToken = "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJhdXRoLXNlcnZpY2U6MS4wLjAiLCJzdWIiOnsibmFtZSI6IlRlc3RQcm9kMyIsInVzZXJuYW1lIjoiVGVzdFByb2QzIiwiYXV0aF9sZXZlbCI6Ik1FUkNIQU5UIiwibWlkIjoiMWZiNTdmMTY2YTQ4MGU5N2JmN2EzZGNiZjkzMTkyOTMifSwiaWF0IjoxNTk3NzM3NzIxLCJleHAiOjE1OTc4MjQxMjEsIm5iZiI6MTU5NzczNzcyM30.CXM-5mCv91Yo17c9zHXQKPGR5gqAeu-LADta-_qnABYxzmnE4Dx0q7NQ9IYr6cYO6cXp40UW4s632fzVYmPCXH8f0RtSwLPqTT7_lWHK--fHCP-LZOmfgwUBxdNocYY9xAi-NyWqCmTnkjWx91lqh9S9Fcue6nO_KrBqngUpBPhpS0hPwgmkqHXX6yAdVs931NbfNM3cYW9PpGIw8K-OxoPDHByD61uAFxT9FCrTbca7vV3HFQnZEKpwxxdECu7DCQAsGTl7JqfbH2j5swe_t97rSDAGyE1HRzGX-SMqPULkC-XravF2m_HucosacYQuSdRaxAWfEIQvtQhAcRXwTA";
private InitReader reader; private InitReader reader;
int idDriver = nativeLib.USE_NFC_NATIVE;
@Override
public void onCreate() {
super.onCreate();
}
public void initConfig(InitListener initListener) {
public void initConfig() {
TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
if (idDriver == 1) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) { if (checkSelfPermission(Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "Please grant permission", Toast.LENGTH_SHORT).show(); Toast.makeText(this, "Please grant permission", Toast.LENGTH_SHORT).show();
...@@ -37,9 +50,33 @@ public class MyApp extends Application { ...@@ -37,9 +50,33 @@ public class MyApp extends Application {
} else { } else {
doInit(); doInit();
} }
}else{
Log.d("lariKemana", "Lari ke else bro");
new RXReader().initEdcReader(this, nativeLib.USE_NFC_NATIVE)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new SingleObserver<InitReader>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onSuccess(InitReader initReader) {
initListener.onInitReaderComplete(initReader);
Log.e("initReader", String.valueOf(initReader));
}
@Override
public void onError(Throwable e) {
}
});
}
} }
private void doInit() { public void doInit() {
ConfigService configService = new ConfigService(); ConfigService configService = new ConfigService();
configService.setMid(GIVE_MID); configService.setMid(GIVE_MID);
configService.setTid(GIVE_TID); configService.setTid(GIVE_TID);
...@@ -58,14 +95,16 @@ public class MyApp extends Application { ...@@ -58,14 +95,16 @@ public class MyApp extends Application {
MDDService initialize = MDDService.with(this, configService); MDDService initialize = MDDService.with(this, configService);
if (initialize.isValid()) { if (initialize.isValid()) {
reader = initialize.getInitReader(); reader = initialize.getInitReader();
if (reader != null) if (reader != null) {
Log.e("MyApp", "Aktivasi library sukses"); Log.e("MyApp", "Aktivasi library sukses");
else Toast.makeText(this, "Aktivasi library sukses", Toast.LENGTH_SHORT).show();
}else {
Log.e("MyApp", "Library belum aktif reader null"); Log.e("MyApp", "Library belum aktif reader null");
// Toast.makeText(this, "Aktivasi library sukses", Toast.LENGTH_SHORT).show(); Toast.makeText(this, "Library belum aktif reader null", Toast.LENGTH_SHORT).show();
}
} else { } else {
Log.e("MyApp", "Library belum aktif"); Log.e("MyApp", "Library belum aktif");
// Toast.makeText(this, "Library belum aktif", Toast.LENGTH_SHORT).show(); Toast.makeText(this, "Library belum aktif", Toast.LENGTH_SHORT).show();
} }
} }
......
package id.mdd.implementationpartnerconnect;
import android.content.Context;
import com.mdd.aar.deviceid.AarDeviceId;
import com.mdd.aar.deviceid.DeviceEnvironment;
import com.mdd.aar.deviceid.exceptions.DeviceNotRegisteredException;
import com.mdd.topupUnik.ubal.InitDebugCertificate;
import com.mdd.topupUnik.ubal.InitReader;
import com.medicom.dudikov.mybanklibrary.nativeLib;
import id.emhusnan.mdd.service.ConfigService;
import id.emhusnan.mdd.service.LibraryConfig;
import io.reactivex.Single;
public class RXReader {
Single<InitReader> initEdcReader(Context context, int deviceDriver) {
return Single.create(emitter -> {
String accessToken = "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJhdXRoLXNlcnZpY2U6MS4wLjAiLCJzdWIiOnsibmFtZSI6IlRlc3RTdGFnIiwidXNlcm5hbWUiOiJUZXN0U3RhZyIsImF1dGhfbGV2ZWwiOiJNRVJDSEFOVCIsIm1pZCI6IjIwZjFmMTNmODA1MGFjY2QxYjNjNzFlOWUyYTQ0NzU3In0sImlhdCI6MTU5MzQxMzM5MCwiZXhwIjoxNzUxMTk4MTUwLCJuYmYiOjE1OTM0MTMzOTJ9.E6UJMKha5YCbri4KRExDV4zeA1ZBfabpW-O6SInxxvfyTTYnUZCEu58STBGrOCL0RuxTFp5Y-XEyoa932fQcTpMBMsKkvDmGeftJ0hmjzAxAjHTfUxUyEa-HHF1whsM4YQUG9CesEBjU9IUcE6Rs-jykYxuryvvqqop5BoEIwO71qQBrq6DtpwjwFk9hbNt0EKs_HmCpySfXQxorfLMbAVJCHBYoo4UVymUfwUbps7hW6eQwNoBnt11O59CRPf6uUVIfCrsaaBMcJI-mc214-EMyl3RmMbqNl_f_0ITEJhMtK2zbUFZ8dMrGdZZgWJxiHdmzxqdaEPDVshYi9Uo31w";
AarDeviceId aarDeviceId = new AarDeviceId(context);
try {
aarDeviceId.getDeviceId();
} catch (DeviceNotRegisteredException e) {
aarDeviceId.init(accessToken, DeviceEnvironment.PROD);
}
try {
ConfigService configService = new ConfigService();
configService.setMid("ba7db816e59612f8ce1630a095ef01c5");
configService.setTid("1234");
configService.setToken("5b423ef49cb029340d7231cace0de201");
LibraryConfig config = new LibraryConfig(
configService.getMid(),
configService.getTid(),
configService.getToken(),
accessToken
);
nativeLib nativeLibrary = new nativeLib(context, deviceDriver);
InitDebugCertificate debugCertificate = new InitDebugCertificate();
InitReader reader = debugCertificate.getDebug(nativeLibrary, context, deviceDriver, config);
emitter.onSuccess(reader);
} catch (Exception e) {
emitter.onError(e);
}
});
}
}
...@@ -39,10 +39,10 @@ ...@@ -39,10 +39,10 @@
<TextView <TextView
android:id="@+id/textCardBalance" android:id="@+id/textCardBalance"
android:layout_width="wrap_content" android:layout_width="600px"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="left" android:layout_gravity="left"
android:gravity="center_horizontal" android:gravity="left"
android:text="Rp. - -" android:text="Rp. - -"
android:textColor="#ffffff" android:textColor="#ffffff"
android:textSize="28sp" /> android:textSize="28sp" />
...@@ -233,4 +233,10 @@ ...@@ -233,4 +233,10 @@
android:text="1.0.1" android:text="1.0.1"
android:textColor="#dcdcdc" /> android:textColor="#dcdcdc" />
</LinearLayout> </LinearLayout>
<ProgressBar
android:id="@+id/pbloading"
android:layout_width="75dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:visibility="visible"/>
</LinearLayout> </LinearLayout>
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<color name="colorPrimary">#6200EE</color> <color name="colorPrimary">#008577</color>
<color name="colorPrimaryDark">#3700B3</color> <color name="colorPrimaryDark">#00574B</color>
<color name="colorAccent">#03DAC5</color> <color name="colorAccent">#D81B60</color>
<color name="text_label">#ffffff</color> <color name="text_label">#ffffff</color>
<color name="text_normal">#000</color>
<color name="text_label2">#414042</color> <color name="text_label2">#414042</color>
<color name="text_success">#22bb33</color>
<color name="text_error">#bb2124</color>
<color name="text_warning">#f0ad4e</color>
<color name="text_normal">#000</color>
</resources> </resources>
\ No newline at end of file
<resources> <resources>
<string name="app_name">ImplementationPartnerConnect</string> <string name="app_name">ImplementationPartnerConnect</string>
<string name="balance">Balance</string>
<string name="card_number">Card Number</string> <string name="card_number">Card Number</string>
<string name="tap_card">Tap Card</string> <string name="old_balance">Previous Balance</string>
<string name="amount">Amount</string>
<string name="new_balance">New Balance</string> <string name="new_balance">New Balance</string>
<string name="amount">Amount</string>
<string name="balance">Balance</string>
<string name="check_balance">Check Balance</string>
<string name="update_balance">Update Balance</string>
<string name="update_success">Update Success</string>
<string name="tap_card">Tap Card</string>
<string name="card_info">Card Info</string>
<string name="keep_tap">Please wait, card must always be tapped</string>
<string name="nfc_not_found">NFC reader not found or disable</string>
<string name="no_pending_balance">No Pending Balance</string>
<string name="card_detect_error">No Card Detected</string>
<string name="update_balance_failed">Update Balance Failed, please re-tap</string>
<string name="update_balance_data_missmatch">Sorry, Cannot update balance right now, please update balance at Mandiri ATM machine</string>
<string name="reversal_failed">Update Balance Failed, please re-tap.</string>
<string name="reversal_success">Update Balance Failed, Please re-tap.</string>
<string name="write_card_failed">Update Balance Failed, Please re-tap. [%s]</string>
<string name="tap_for_reversal">Tap For Reversal</string>
<string name="loading">Please Wait.</string>
<string name="loading_reversal">Please Wait..</string>
<string name="copied">Copy Card Number</string>
<string name="error_not_setup">Not Setup yet</string>
<string name="connection_error">Connection Error</string>
<string name="TapMore" translatable="false">Tempelkan sekali lagi untuk memperbarui Saldo</string>
<string name="SuccessGetCard" translatable="false">Sukses mendapatkan info kartu</string>
<string name="title_activity_manual_library">ManualLibraryActivity</string>
</resources> </resources>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment