Implemented generating EPC QR code on Android
This commit is contained in:
parent
e421cdb176
commit
c8d1a1a98c
|
@ -10,7 +10,7 @@ import java.io.ByteArrayOutputStream
|
||||||
|
|
||||||
class QrCodeGenerator {
|
class QrCodeGenerator {
|
||||||
|
|
||||||
fun generateQrCode(informationToEncode: String, config: EncodeToQrCodeConfig = EncodeToQrCodeConfig()): ByteArray {
|
fun generateQrCodeAsByteArray(informationToEncode: String, config: EncodeToQrCodeConfig = EncodeToQrCodeConfig()): ByteArray {
|
||||||
val bitMatrix = QRCodeWriter().encode(informationToEncode, BarcodeFormat.QR_CODE, config.width, config.height)
|
val bitMatrix = QRCodeWriter().encode(informationToEncode, BarcodeFormat.QR_CODE, config.width, config.height)
|
||||||
|
|
||||||
val bitmap = Bitmap.createBitmap(config.width, config.height, Bitmap.Config.RGB_565)
|
val bitmap = Bitmap.createBitmap(config.width, config.height, Bitmap.Config.RGB_565)
|
||||||
|
@ -26,4 +26,17 @@ class QrCodeGenerator {
|
||||||
return blob.toByteArray()
|
return blob.toByteArray()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun generateQrCode(informationToEncode: String, config: EncodeToQrCodeConfig = EncodeToQrCodeConfig()): Bitmap {
|
||||||
|
val bitMatrix = QRCodeWriter().encode(informationToEncode, BarcodeFormat.QR_CODE, config.width, config.height)
|
||||||
|
|
||||||
|
val bitmap = Bitmap.createBitmap(config.width, config.height, Bitmap.Config.RGB_565)
|
||||||
|
for (x in 0 until config.width) {
|
||||||
|
for (y in 0 until config.height) {
|
||||||
|
bitmap.setPixel(x, y, if (bitMatrix.get(x, y)) Color.BLACK else Color.WHITE)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return bitmap
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -2,8 +2,15 @@ package net.codinux.banking.epcqrcode
|
||||||
|
|
||||||
|
|
||||||
open class EncodeToQrCodeConfig(
|
open class EncodeToQrCodeConfig(
|
||||||
open val width: Int = 500,
|
open val width: Int = DefaultWidth,
|
||||||
open val height: Int = 500,
|
open val height: Int = DefaultHeight,
|
||||||
open val format: ImageFormat = ImageFormat.PNG,
|
open val format: ImageFormat = ImageFormat.PNG,
|
||||||
open val encoding: EpcQrCodeCharacterSet = EpcQrCodeCharacterSet.UTF_8
|
open val encoding: EpcQrCodeCharacterSet = EpcQrCodeCharacterSet.UTF_8
|
||||||
)
|
) {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val DefaultWidth = 350
|
||||||
|
const val DefaultHeight = 350
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -12,6 +12,8 @@ dependencies {
|
||||||
implementation("androidx.core:core-ktx:1.2.0")
|
implementation("androidx.core:core-ktx:1.2.0")
|
||||||
implementation("androidx.appcompat:appcompat:1.1.0")
|
implementation("androidx.appcompat:appcompat:1.1.0")
|
||||||
implementation("androidx.constraintlayout:constraintlayout:1.1.3")
|
implementation("androidx.constraintlayout:constraintlayout:1.1.3")
|
||||||
|
|
||||||
|
implementation("com.google.android.material:material:1.2.1")
|
||||||
}
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
package net.codinux.banking.epcqrcode
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.os.IBinder
|
||||||
|
import android.view.View
|
||||||
|
import android.view.inputmethod.InputMethodManager
|
||||||
|
import com.google.android.material.textfield.TextInputEditText
|
||||||
|
|
||||||
|
|
||||||
|
fun Context.hideKeyboard(anyViewInHierarchy: View, flags: Int = 0) {
|
||||||
|
hideKeyboard(anyViewInHierarchy.windowToken, flags)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Context.hideKeyboard(windowToken: IBinder, flags: Int = 0) {
|
||||||
|
val keyboard = this.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
|
||||||
|
keyboard.hideSoftInputFromWindow(windowToken, flags)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
val TextInputEditText.string: String
|
||||||
|
get() = this.text?.toString() ?: ""
|
|
@ -1,25 +1,50 @@
|
||||||
package net.codinux.banking.epcqrcode
|
package net.codinux.banking.epcqrcode
|
||||||
|
|
||||||
import android.graphics.BitmapFactory
|
import android.graphics.Bitmap
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import kotlinx.android.synthetic.main.activity_main.*
|
import kotlinx.android.synthetic.main.activity_main.*
|
||||||
|
import kotlin.concurrent.thread
|
||||||
|
|
||||||
|
|
||||||
class MainActivity : AppCompatActivity() {
|
class MainActivity : AppCompatActivity() {
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
setContentView(R.layout.activity_main)
|
setContentView(R.layout.activity_main)
|
||||||
|
|
||||||
|
btnGenerateQrCode.setOnClickListener { generateQrCode() }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onPostCreate(savedInstanceState: Bundle?) {
|
|
||||||
super.onPostCreate(savedInstanceState)
|
|
||||||
|
|
||||||
txtMessage.text = MppTest().showMessage()
|
private fun generateQrCode() {
|
||||||
|
hideKeyboard(edtxtReference)
|
||||||
|
|
||||||
val qrCodeContent = EpcQrCodeCreator().generateAsString(CreatorParam("Mahatma Gandhi", "IN00123456789876543210", null, 1234.56, "Struggle for independence"))
|
val param = CreatorParam(edtxtReceiver.string, edtxtIban.string, edtxtBic.string, map(edtxtAmount.string), edtxtReference.string)
|
||||||
val imageBytes = QrCodeGenerator().generateQrCode(qrCodeContent)
|
|
||||||
imgGeneratedQrCode.setImageBitmap(BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.size))
|
generateQrCodeAsync(param) { createdQrCode ->
|
||||||
|
imgGeneratedQrCode.setImageBitmap(createdQrCode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun generateQrCodeAsync(param: CreatorParam, done: (Bitmap) -> Unit) {
|
||||||
|
thread {
|
||||||
|
val density = resources.displayMetrics.density
|
||||||
|
val config = EncodeToQrCodeConfig((EncodeToQrCodeConfig.DefaultWidth * density).toInt(), (EncodeToQrCodeConfig.DefaultHeight * density).toInt())
|
||||||
|
|
||||||
|
val qrCodeContent = EpcQrCodeCreator().generateAsString(param)
|
||||||
|
|
||||||
|
// TODO: this takes a very long time. Improve it
|
||||||
|
val generatedQrCode = QrCodeGenerator().generateQrCode(qrCodeContent, config)
|
||||||
|
|
||||||
|
runOnUiThread {
|
||||||
|
done(generatedQrCode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun map(amount: String): Double? {
|
||||||
|
return amount.replace(',', '.').toDoubleOrNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,28 +1,126 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout
|
<ScrollView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_marginLeft="@dimen/activity_main_margin_start_end"
|
||||||
|
android:layout_marginStart="@dimen/activity_main_margin_start_end"
|
||||||
|
android:layout_marginRight="@dimen/activity_main_margin_start_end"
|
||||||
|
android:layout_marginEnd="@dimen/activity_main_margin_start_end"
|
||||||
|
>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="wrap_content"
|
||||||
tools:context=".MainActivity">
|
tools:context=".MainActivity">
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/txtMessage"
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="@dimen/form_edit_text_height"
|
||||||
android:text="Hello World!"
|
android:layout_marginTop="@dimen/form_edit_text_margin_top"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
android:layout_marginBottom="@dimen/form_edit_text_margin_bottom"
|
||||||
app:layout_constraintLeft_toLeftOf="parent"
|
android:hint="@string/receiver"
|
||||||
app:layout_constraintRight_toRightOf="parent"
|
>
|
||||||
app:layout_constraintTop_toTopOf="parent"/>
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/edtxtReceiver"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
/>
|
||||||
|
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/form_edit_text_height"
|
||||||
|
android:layout_marginTop="@dimen/form_edit_text_margin_top"
|
||||||
|
android:layout_marginBottom="@dimen/form_edit_text_margin_bottom"
|
||||||
|
android:hint="@string/iban"
|
||||||
|
>
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/edtxtIban"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
/>
|
||||||
|
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/form_edit_text_height"
|
||||||
|
android:layout_marginTop="@dimen/form_edit_text_margin_top"
|
||||||
|
android:layout_marginBottom="@dimen/form_edit_text_margin_bottom"
|
||||||
|
android:hint="@string/bic"
|
||||||
|
>
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/edtxtBic"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
/>
|
||||||
|
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/form_edit_text_height"
|
||||||
|
android:layout_marginTop="@dimen/form_edit_text_margin_top"
|
||||||
|
android:layout_marginBottom="@dimen/form_edit_text_margin_bottom"
|
||||||
|
android:hint="@string/amount"
|
||||||
|
>
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/edtxtAmount"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
/>
|
||||||
|
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/form_edit_text_height"
|
||||||
|
android:layout_marginTop="@dimen/form_edit_text_margin_top"
|
||||||
|
android:layout_marginBottom="@dimen/form_edit_text_margin_bottom"
|
||||||
|
android:hint="@string/reference"
|
||||||
|
>
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/edtxtReference"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
/>
|
||||||
|
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/btnGenerateQrCode"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/generate_button_height"
|
||||||
|
android:layout_marginTop="@dimen/generate_button_margin_top"
|
||||||
|
android:layout_marginBottom="@dimen/generate_button_margin_bottom"
|
||||||
|
android:textAllCaps="false"
|
||||||
|
android:text="@string/generate"
|
||||||
|
/>
|
||||||
|
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/imgGeneratedQrCode"
|
android:id="@+id/imgGeneratedQrCode"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="@dimen/generated_qr_code_bottom_margin"
|
||||||
android:scaleType="fitCenter"
|
android:scaleType="fitCenter"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
</ScrollView>
|
|
@ -0,0 +1,11 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
|
||||||
|
<string name="receiver">Empfänger</string>
|
||||||
|
<string name="iban">IBAN</string>
|
||||||
|
<string name="bic">BIC</string>
|
||||||
|
<string name="amount">Betrag</string>
|
||||||
|
<string name="reference">Verwendungszweck</string>
|
||||||
|
<string name="generate">Erstellen</string>
|
||||||
|
|
||||||
|
</resources>
|
|
@ -0,0 +1,16 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
|
||||||
|
<dimen name="activity_main_margin_start_end">4dp</dimen>
|
||||||
|
|
||||||
|
<dimen name="form_edit_text_height">60dp</dimen>
|
||||||
|
<dimen name="form_edit_text_margin_top">6dp</dimen>
|
||||||
|
<dimen name="form_edit_text_margin_bottom">6dp</dimen>
|
||||||
|
|
||||||
|
<dimen name="generate_button_height">55dp</dimen>
|
||||||
|
<dimen name="generate_button_margin_top">8dp</dimen>
|
||||||
|
<dimen name="generate_button_margin_bottom">20dp</dimen>
|
||||||
|
|
||||||
|
<dimen name="generated_qr_code_bottom_margin">6dp</dimen>
|
||||||
|
|
||||||
|
</resources>
|
|
@ -0,0 +1,11 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
|
||||||
|
<string name="receiver">Receiver</string>
|
||||||
|
<string name="iban">IBAN</string>
|
||||||
|
<string name="bic">BIC</string>
|
||||||
|
<string name="amount">Amount</string>
|
||||||
|
<string name="reference">Reference</string>
|
||||||
|
<string name="generate">Generate</string>
|
||||||
|
|
||||||
|
</resources>
|
|
@ -5,4 +5,4 @@
|
||||||
"Amount" = "Betrag";
|
"Amount" = "Betrag";
|
||||||
"Reference" = "Verwendungszweck";
|
"Reference" = "Verwendungszweck";
|
||||||
|
|
||||||
"Generate" = "Erzeugen";
|
"Generate" = "Erstellen";
|
||||||
|
|
Loading…
Reference in New Issue