problem is I try to add this functionality for users that they add their Rav-Kav(calypso cards ) I try to find API or library but I couldn’t find any resources on the internet.
Card Scanning and Storage Users can scan their Calypso standard cards (RavKav) and store the encrypted card details in Firestore and Card Users can emulate the card and use it to tap and pay at bus stations. They can also store, manage, and delete multiple cards and payment will be done with the help of HCE (Host card emulation).
here is my full code where i try to scan the card and store details in firestore but I don’t know how to scan and store the calypso(Rav Kav) transit card
import android.app.PendingIntent
import android.content.Intent
import android.content.IntentFilter
import android.nfc.NfcAdapter
import android.nfc.Tag
import android.nfc.tech.NfcA
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.google.firebase.firestore.FirebaseFirestore
class NfcScanActivity : AppCompatActivity() {
private lateinit var nfcAdapter: NfcAdapter
private lateinit var firestore: FirebaseFirestore
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_nfc_scan)
nfcAdapter = NfcAdapter.getDefaultAdapter(this)
firestore = FirebaseFirestore.getInstance()
}
override fun onResume() {
super.onResume()
val intent = Intent(this, javaClass).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
val pendingIntent = PendingIntent.getActivity(this, 0, intent, 0)
val filters = arrayOf(IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED))
val techList = arrayOf(arrayOf(NfcA::class.java.name))
nfcAdapter.enableForegroundDispatch(this, pendingIntent, filters, techList)
}
override fun onPause() {
super.onPause()
nfcAdapter.disableForegroundDispatch(this)
}
override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
if (intent?.action == NfcAdapter.ACTION_TECH_DISCOVERED) {
val tag: Tag? = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG)
tag?.let {
readFromNfc(it)
}
}
}
private fun readFromNfc(tag: Tag) {
val nfcA = NfcA.get(tag)
nfcA.connect()
// Replace with actual commands to read data
val response = nfcA.transceive(byteArrayOf(0x00, 0xA4, 0x04, 0x00, 0x07, 0xF0, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06))
nfcA.close()
storeCardData(response)
}
private fun storeCardData(data: ByteArray) {
// Encrypt the data
val encryptedData = encryptData(data)
// Store in Firestore
val cardData = hashMapOf("cardData" to encryptedData)
firestore.collection("cards")
.add(cardData)
.addOnSuccessListener { documentReference ->
// Handle success
}
.addOnFailureListener { e ->
// Handle failure
}
}
private fun encryptData(data: ByteArray): ByteArray {
// Implement encryption logic
return data // Placeholder
}
}
**and here is my code of HCE where I try to user done payment with the help of HCE **
import android.nfc.cardemulation.HostApduService
import android.os.Bundle
import android.util.Log
class MyHostApduService : HostApduService() {
override fun processCommandApdu(commandApdu: ByteArray?, extras: Bundle?): ByteArray {
if (commandApdu == null) {
return unknownCommandResponse()
}
val hexCommandApdu = commandApdu.joinToString("") { "%02x".format(it) }
Log.d("APDU", "Received APDU: $hexCommandApdu")
if (commandApdu.contentEquals(SELECT_APDU)) {
return selectApduResponse()
}
// Handle other APDU commands here
return fixedResponse()
}
override fun onDeactivated(reason: Int) {
Log.d("APDU", "Deactivated: $reason")
}
private fun selectApduResponse(): ByteArray {
// Replace with the actual response
return "9000".hexStringToByteArray()
}
private fun fixedResponse(): ByteArray {
// Replace with the actual response
return "9000".hexStringToByteArray()
}
private fun unknownCommandResponse(): ByteArray {
return "6F00".hexStringToByteArray()
}
companion object {
private val SELECT_APDU = "00A4040007F0010203040506".hexStringToByteArray()
}
}
// Extension function to convert a hex string to a byte array
fun String.hexStringToByteArray(): ByteArray {
val len = this.length
val data = ByteArray(len / 2)
var i = 0
while (i < len) {
data[i / 2] = ((Character.digit(this[i], 16) shl 4)
+ Character.digit(this[i + 1], 16)).toByte()
i += 2
}
return data
}
Lokesh Arora is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
3