0

I am building an app that requires me to display the text written on a nfc tag as a humanly readable string. I am currently using nfc_manager here is a screenshot of the response i get in-app which is json:

{iso15693: {identifier: [224, 4, 1, 8, 62, 149, 102, 100], icManufacturerCode: 4, icSerialNumber: [1, 8, 62, 149, 102, 100]}, ndef: {cachedMessage: {records: [payload: [2, 101, 110, 65, 100, 97, 109], typeNameFormat: 1, identifier: [], type: [84]}]}, isWritable: true, maxSize: 312}}

my code is the following :

class NFC_scanner extends StatefulWidget {
  const NFC_scanner({Key? key}) : super(key: key);

  @override
  State<StatefulWidget> createState() => MyNFCState();
}

class MyNFCState extends State<NFC_scanner> {
  ValueNotifier<dynamic> result = ValueNotifier(null);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        appBar: AppBar(
          title: Text('NfcManager Plugin Example'),
          backgroundColor: Colors.transparent,
          foregroundColor: Colors.lightGreen,
          elevation: 0.0,
        ),
        body: SafeArea(
          child: FutureBuilder<bool>(
            future: NfcManager.instance.isAvailable(),
            builder: (context, ss) => ss.data != true
                ? Center(child: Text('NfcManager.isAvailable(): ${ss.data}'))
                : Flex(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    direction: Axis.vertical,
                    children: [
                      Flexible(
                        flex: 2,
                        child: Container(
                          margin: EdgeInsets.all(4),
                          constraints: BoxConstraints.expand(),
                          decoration: BoxDecoration(shape: BoxShape.circle),
                          child: SingleChildScrollView(
                            child: ValueListenableBuilder<dynamic>(
                              valueListenable: result,
                              builder: (context, value, _) =>
                                  Container(
                                    height: 200,
                                    width: 200,
                                    child: Text('${value ?? ''}')
                                    ),
                            ),
                          ),
                        ),
                      ),
                      Container(
                        height: 300,
                        width: 300,
                        child: Lottie.network('https://lottie.host/124ecd28-8486-478f-a479-4fa22242dda5/ycBN8Sr5aP.json')
                      ),
                      Text('Please keep your device near your phone'),
                      SizedBox(height: 100),
                      FloatingActionButton(
                        onPressed: _tagRead,
                        backgroundColor: Colors.lightGreen,
                        child: Icon(
                          Icons.zoom_in,
                        ),

                      )
                    ],
                  ),
          ),
        ),
      ),
    );
  }

  void _tagRead() async {
    showDialog(
        context: context,
        builder: (context) {
          return AlertDialog(content: Text('You can tap the tag now !'));
        });
    try {
      
      await NfcManager.instance.startSession(onDiscovered: (NfcTag tag) async {
        result.value = tag.data;
        print('tag.data: ${tag.data}');
        NfcManager.instance.stopSession();
      });
    } catch (e) {
      result.value = e.toString();
    }
  }
}



I tried to parse the json response but couldn't get the payload value that needs to be converted to strings with the following code from stackoverflow :

NfcManager.instance.startSession(onDiscovered : (NfcTag tag) async{
var payload = tag.data["ndef"]["cachedMessage"]["record"][0]["payload"];
// now convert that payload into string
var stringPayload = String.fromCharCodes(payload);
}

whenever i run it, it blocks the NFC tag read.

Thank you in advance for your help

Aphtn
  • 1
  • 1
  • The text in that message is "Adam" once you have parsed the language code from it (the code probably does not like parsing the "2" as this is not in the standard char code range.) – Andrew Aug 26 '23 at 06:02
  • @Andrew The thing is that i can’t parse the json response it makes the app not reading the tag. Do you have any example in Dart (flutter framework) to achieve displaying the String stored in the NFC tag in app ? – Aphtn Aug 26 '23 at 07:51

1 Answers1

0

This is not an answer to your question how to solve your problem in Dart/Flutter, but to help you in your coding.

Your payload is a NDEF message that may contain several NDEF Records.

In your case your payload (in decimal) is "2, 101, 110, 65, 100, 97, 109". Please google for "NDEF message and record" to understand how a NDEF message is constructed.

As @Andrew already commented the content you are looking for has a trailing "2" followed by "101, 110, 65, 100, 97, 109".

Using an online "decimal to text" converter like https://www.browserling.com/tools/decimal-to-text and using these numbers WITHOUT commas: "101 110 65 100 97 109" will give you this result:

enAdam.

The trailing "en" is a language code, followed by the text that was read from the tag as text: "Adam".

Michael Fehr
  • 5,827
  • 2
  • 19
  • 40