School Project for EMP 2019/2020 - Žiga Klemenčič (63170145)
This is an Android App that is designed to read, modify and create UPNQR Codes for Slovenian bills and banks.
UPNQR Codes are essetially only QR codes that hold markup, that bank apps can read. Read more about Slovenian UPNQR Specification Or more about UPNQR Overall
The application consists of three activities, one main and two sub activities, it uses a green-ish color theme. The main activity is actually a navigational activity, that with a click of the butto redirects us to the desired functionality of the App
Functionallities consist of
- First activity - Creating and sharing a custom UPNQR Code
- Second activity - Reading, splitting and sharing a Premade UPNQR Code.
I used a library barcode-reader to help me read QR codes. ` Here is a code snippet of reading the UPNQR Code:
qrCodeButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Intent launchIntent = BarcodeReaderActivity
.getLaunchIntent(MainActivity.this, true, false);
startActivityForResult(launchIntent, BARCODE_READER_ACTIVITY_REQUEST);
}
});
// Later - onActivityResult
if (requestCode == BARCODE_READER_ACTIVITY_REQUEST && data != null) {
Barcode qrCode = data.getParcelableExtra(BarcodeReaderActivity.KEY_CAPTURED_BARCODE);
Intent qrCodeSplitterIntent = new Intent(this, QRSplitterActivity.class);
qrCodeSplitterIntent.putExtra("qrData", qrCode.rawValue);
startActivity(qrCodeSplitterIntent);
To split the UPNQR code I decode the QR code, get it's amount value, witch is on index 8. I then get the value from splitting input, to know how on many parts I have to split the bill (Max 99)
I then use this snippet of code to accomplish splitting:
String[] UPNValues = qrData.split("\\r?\\n");
if (UPNValues.length < 19 || !isNumeric(UPNValues[8])) {
Toast.makeText(
this,
"Nepravilna oblika QR kode",
Toast.LENGTH_SHORT
).show();
finish();
return;
}
int splitNumber = Integer.parseInt(
splitNumberText.getText().toString().length() > 0 ?
splitNumberText.getText().toString() :
"1"
);
UPNValues[8] = (Integer.parseInt(UPNValues[8]) / splitNumber) + "";
String splitQrData = "";
for (String UPNValue : UPNValues) {
splitQrData += UPNValue.trim() + '\n';
}
QRGEncoder qrgEncoder = new QRGEncoder(
splitQrData,
null,
QRGContents.Type.TEXT,
500
);
To share an UPNQR Code I have to first get it from the ImageView and save to to local storage, after that I can use androids built-in sharing activity.
This is the snippet of code showing you how I accomplished this.
Bitmap bitmap = ((BitmapDrawable) qrCodeView.getDrawable()).getBitmap();
if (bitmap == null) {
Toast.makeText(
QRSplitterActivity.this,
"Nekaj je šlo narobe",
Toast.LENGTH_SHORT
).show();
return;
}
if (ContextCompat.checkSelfPermission(QRSplitterActivity.this,
Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(QRSplitterActivity.this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
0);
ActivityCompat.requestPermissions(QRSplitterActivity.this,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
0);
} else {
final File dir =
new File(Environment.getExternalStorageDirectory(), "qrCodeSplitter");
if (!dir.exists()) {
dir.mkdirs();
}
final File img = new File(dir, System.currentTimeMillis() + ".png");
if (img.exists()) {
img.delete();
}
try {
final OutputStream outStream = new FileOutputStream(img);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
outStream.flush();
outStream.close();
Intent share = new Intent(Intent.ACTION_SEND);
share.setType("image/*");
share.putExtra(
Intent.EXTRA_STREAM,
Uri.fromFile(img)
);
startActivity(Intent.createChooser(share, "Deli kodo"));
} catch (Throwable throwable) {
throwable.printStackTrace();
Toast.makeText(
QRSplitterActivity.this,
"Nekaj je šlo narobe",
Toast.LENGTH_SHORT
).show();
}
}
Here is a code snippet of how an UPNQR Code is generated in my App. The activity also consists of 10 Input fields, defining what user will later see in his mobile bank app once he scans the created QR Code
if (validateParams()) {
String[] qrData = {
"UPNQR",
"",
"",
"",
"",
"",
"",
"",
((int) (Double.parseDouble(amountText.getText().toString()) * 100)) + "",
"",
"",
purposeCodeText.getText().toString(),
paymentPurposeText.getText().toString(),
dueDateText.getText().toString(),
IBANText.getText().toString(),
referenceText.getText().toString(),
nameText.getText().toString(),
addressText.getText().toString(),
placeText.getText().toString(),
"204"
};
String splitQrData = "";
for (String UPNValue : qrData) {
splitQrData += UPNValue.trim() + '\n';
}
final QRGEncoder qrgEncoder = new QRGEncoder(
splitQrData,
null,
QRGContents.Type.TEXT,
500
);
Log.d("splitData", splitQrData);
try {
qrCodeView = new ImageView(ManualEntry.this);
qrCodeView.setImageBitmap(qrgEncoder.encodeAsBitmap());
qrCodeView.setLayoutParams(
new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
)
);
qrCodesContainer.removeAllViews();
qrCodesContainer.addView(qrCodeView);
} catch (Exception ex) {
ex.printStackTrace();
Toast.makeText(ManualEntry.this, "Nekaj je slo narobe", Toast.LENGTH_SHORT).show();
}