Implement emulation (hopefully!)
This commit is contained in:
parent
6481878cee
commit
de97b9b7e1
@ -50,6 +50,7 @@ import androidx.compose.material3.SnackbarResult
|
|||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.DisposableEffect
|
import androidx.compose.runtime.DisposableEffect
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableIntStateOf
|
import androidx.compose.runtime.mutableIntStateOf
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
@ -83,7 +84,7 @@ class MainActivity : ComponentActivity() {
|
|||||||
lateinit var adapter: NfcAdapter
|
lateinit var adapter: NfcAdapter
|
||||||
|
|
||||||
var canEmulateCard: Boolean = false
|
var canEmulateCard: Boolean = false
|
||||||
var emulationActive: Boolean = false
|
var emulationCardID: String? = null
|
||||||
|
|
||||||
private val TAG = "AimeReader"
|
private val TAG = "AimeReader"
|
||||||
private val FILENAME = "cards.json"
|
private val FILENAME = "cards.json"
|
||||||
@ -158,7 +159,16 @@ class MainActivity : ComponentActivity() {
|
|||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
var snackbarHostState = remember { SnackbarHostState() }
|
var snackbarHostState = remember { SnackbarHostState() }
|
||||||
|
|
||||||
var selectedCardIndexForEmulation by rememberSaveable { mutableStateOf(-1) }
|
var selectedCardIndexForEmulation by rememberSaveable { mutableIntStateOf(-1) }
|
||||||
|
|
||||||
|
LaunchedEffect(selectedCardIndexForEmulation) {
|
||||||
|
if (selectedCardIndexForEmulation == -1) {
|
||||||
|
this@MainActivity.emulationCardID = null
|
||||||
|
} else {
|
||||||
|
this@MainActivity.emulationCardID = cards[selectedCardIndexForEmulation].getHexID()
|
||||||
|
}
|
||||||
|
updateEmulation()
|
||||||
|
}
|
||||||
|
|
||||||
AimeReaderTheme {
|
AimeReaderTheme {
|
||||||
Scaffold (
|
Scaffold (
|
||||||
@ -261,17 +271,28 @@ class MainActivity : ComponentActivity() {
|
|||||||
adapter.disableForegroundDispatch(this)
|
adapter.disableForegroundDispatch(this)
|
||||||
val nfcfCardEmulation = NfcFCardEmulation.getInstance(adapter)
|
val nfcfCardEmulation = NfcFCardEmulation.getInstance(adapter)
|
||||||
nfcfCardEmulation.disableService(this)
|
nfcfCardEmulation.disableService(this)
|
||||||
|
Log.i(TAG, "Pausing activity, emulation disabled")
|
||||||
}
|
}
|
||||||
|
|
||||||
public override fun onResume() {
|
public override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
adapter.enableForegroundDispatch(this, pendingIntent, intentFiltersArray, techListsArray)
|
adapter.enableForegroundDispatch(this, pendingIntent, intentFiltersArray, techListsArray)
|
||||||
val nfcfCardEmulation = NfcFCardEmulation.getInstance(adapter)
|
updateEmulation()
|
||||||
nfcfCardEmulation.registerSystemCodeForService(ComponentName(this, AimeHostApduService::class.java), "4000")
|
|
||||||
Log.d(TAG, nfcfCardEmulation.setNfcid2ForService(ComponentName(this, AimeHostApduService::class.java), "02FE000000000000").toString())
|
|
||||||
Log.d(TAG, nfcfCardEmulation.enableService(this, ComponentName(this, AimeHostApduService::class.java)).toString())
|
|
||||||
Log.i(TAG, "activity resumed")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun updateEmulation() {
|
||||||
|
val nfcfCardEmulation = NfcFCardEmulation.getInstance(adapter)
|
||||||
|
if (emulationCardID != null) {
|
||||||
|
Log.i(TAG, "Enabling emulation of card $emulationCardID")
|
||||||
|
nfcfCardEmulation.registerSystemCodeForService(ComponentName(this, AimeHostApduService::class.java), "4000")
|
||||||
|
Log.d(TAG, nfcfCardEmulation.setNfcid2ForService(ComponentName(this, AimeHostApduService::class.java), emulationCardID).toString())
|
||||||
|
Log.d(TAG, nfcfCardEmulation.enableService(this, ComponentName(this, AimeHostApduService::class.java)).toString())
|
||||||
|
} else {
|
||||||
|
Log.i(TAG, "Disabling card emulation")
|
||||||
|
nfcfCardEmulation.disableService(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@ -288,7 +309,7 @@ fun CardList(
|
|||||||
Column (
|
Column (
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
verticalArrangement = Arrangement.Center,
|
verticalArrangement = Arrangement.Center,
|
||||||
modifier = Modifier
|
modifier = modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.padding(innerPadding)
|
.padding(innerPadding)
|
||||||
) {
|
) {
|
||||||
@ -297,7 +318,7 @@ fun CardList(
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LazyColumn (
|
LazyColumn (
|
||||||
modifier = Modifier
|
modifier = modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(innerPadding)
|
.padding(innerPadding)
|
||||||
) {
|
) {
|
||||||
@ -327,7 +348,7 @@ fun CardDisplay(
|
|||||||
val coroutineScope = rememberCoroutineScope()
|
val coroutineScope = rememberCoroutineScope()
|
||||||
|
|
||||||
Row (
|
Row (
|
||||||
modifier = Modifier
|
modifier = modifier
|
||||||
.padding(horizontal = 8.dp, vertical = 8.dp)
|
.padding(horizontal = 8.dp, vertical = 8.dp)
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.clip(shape = RoundedCornerShape(16.dp))
|
.clip(shape = RoundedCornerShape(16.dp))
|
||||||
@ -383,7 +404,7 @@ fun CardDisplay(
|
|||||||
@Preview
|
@Preview
|
||||||
@Composable
|
@Composable
|
||||||
fun CardDisplayPreview(modifier: Modifier = Modifier) {
|
fun CardDisplayPreview(modifier: Modifier = Modifier) {
|
||||||
Column(modifier = Modifier.fillMaxSize()) {
|
Column(modifier = modifier.fillMaxSize()) {
|
||||||
CardDisplay(SavedCard(byteArrayOf(0x02, 0xFE.toByte(), 0x02, 0x03, 0x04, 0x05, 0x06, 0x07)), true, true, {}, {}, {})
|
CardDisplay(SavedCard(byteArrayOf(0x02, 0xFE.toByte(), 0x02, 0x03, 0x04, 0x05, 0x06, 0x07)), true, true, {}, {}, {})
|
||||||
CardDisplay(SavedCard(byteArrayOf(0x02, 0xFE.toByte(), 0x12, 0x34, 0x56, 0x78, 0x12, 0x34)), true, false, {}, {}, {})
|
CardDisplay(SavedCard(byteArrayOf(0x02, 0xFE.toByte(), 0x12, 0x34, 0x56, 0x78, 0x12, 0x34)), true, false, {}, {}, {})
|
||||||
CardDisplay(SavedCard(byteArrayOf(0x02, 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07)), true, false, {}, {}, {})
|
CardDisplay(SavedCard(byteArrayOf(0x02, 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07)), true, false, {}, {}, {})
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package me.kdcf.aimereader
|
package me.kdcf.aimereader
|
||||||
|
|
||||||
import android.os.Parcel
|
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
import kotlinx.parcelize.Parcelize
|
import kotlinx.parcelize.Parcelize
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
@ -25,6 +24,11 @@ class SavedCard(private var code: ByteArray, private var friendlyName: String =
|
|||||||
return getPadded().chunked(4).joinToString(" ")
|
return getPadded().chunked(4).joinToString(" ")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalStdlibApi::class)
|
||||||
|
fun getHexID(): String {
|
||||||
|
return getCode().toHexString()
|
||||||
|
}
|
||||||
|
|
||||||
fun getDisplay(): String {
|
fun getDisplay(): String {
|
||||||
if (friendlyName.isEmpty()) {
|
if (friendlyName.isEmpty()) {
|
||||||
return getSpaced()
|
return getSpaced()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user