Sample code for 30+ languages & platforms
Dart

PC/SC Wait for Smart Card Status Change (Inserted, Removed from Reader, etc.)

See more SCard Examples

Demonstrates how to synchronously wait for a status change, such as for a smart card to be inserted into a reader, or removed from a reader.

Note: This functionality was introduced in Chilkat v9.5.0.87.

Chilkat Dart Downloads

Dart
import 'package:chilkat/chilkat.dart';

void main() {
  // This example requires the Chilkat API to have been previously unlocked.
  // See Global Unlock Sample for sample code.

  final scard = CkSCard();

  // First establish a context to the PC/SC Resource Manager
  try {
    scard.establishContext('user');
  } on ChilkatException catch (e) {
    print(e.lastErrorText);
    return;
  }

  // First we'll examine the state of all connected readers to see which have smartcards already inserted..
  // Get JSON containing information about the smartcards currently inserted into readers.
  // This also includes information about USB security tokens.
  final json = CkJsonObject();
  try {
    scard.findSmartcards(json);
  } on ChilkatException catch (e) {
    print(e.lastErrorText);
    return;
  }

  // When writing this example, I have 3 smart card readers plugged into my system.
  // One of them has a smart card inserted.
  // Here's the JSON returned by FindSmartcards...

  // {
  //   "reader": [
  //     {
  //       "name": "Alcor Micro USB Smart Card Reader 0",
  //       "state": "empty"
  //     },
  //     {
  //       "name": "Generic Smart Card Reader Interface 0",
  //       "state": "present",
  //       "vendorName": "Generic",
  //       "serialNumber": "3230303730383138303030303030303030",
  //       "systemName": "Generic Smart Card Reader Interface 0",
  //       "card": {
  //         "atr": "3BFC180000813180459067464A00641606F2727E00E0",
  //         "windows": {
  //           "miniDriver": "tagliov70px.dll",
  //           "cryptoProvider": "Microsoft Base Smart Card Crypto Provider",
  //           "keyStorageProvider": "Microsoft Smart Card Key Storage Provider"
  //         }
  //       }
  //     },
  //     {
  //       "name": "SCM Microsystems Inc. SCR33x USB Smart Card Reader 0",
  //       "state": "empty"
  //     }
  //   ]
  // }

  json.emitCompact = false;
  print(json.emit());
  print(' ');

  // We can iterate over the JSON to find the readers with a smart card already inserted..
  var name = '';
  final sbState = CkStringBuilder();

  var i = 0;
  var countI = json.sizeOfArray('reader');
  while (i < countI) {
    json.i = i;
    name = json.stringOf('reader[i].name');

    sbState.clear();
    json.stringOfSb('reader[i].state', sbState);

    if (sbState.contains('present', true)) {
      print('$name has a smart card inserted.');
    } else {
      print('$name does not have a smart card inserted.');
    }

    i++;
  }

  print(' ');

  // Now let's begin the code to wait for a change (where a smart card gets inserted or removed)

  // Get the list of all readers.
  final stReaders = CkStringTable();
  try {
    scard.listReaders(stReaders);
  } on ChilkatException catch (e) {
    print(e.lastErrorText);
    return;
  }

  // Show the reader names..
  final numReaders = stReaders.count;
  i = 0;
  while (i < numReaders) {
    print('$i: ${stReaders.stringAt(i)}');
    i++;
  }

  // Sample output from the above loop.
  // 0: Alcor Micro USB Smart Card Reader 0
  // 1: Generic Smart Card Reader Interface 0
  // 2: SCM Microsystems Inc. SCR33x USB Smart Card Reader 0
  // 

  // Synchronously wait 30 seconds for a card to be inserted or removed from any of the above readers.
  final json2 = CkJsonObject();
  try {
    scard.getStatusChange(30000, stReaders, json2);
  } on ChilkatException catch (e) {
    print(e.lastErrorText);
    return;
  }

  print(' ');

  // Let's see what happened...
  json2.emitCompact = false;
  print(json2.emit());
  print(' ');

  // This is what json2 contains.
  // A card was inserted into the reader named "SCM Microsystems Inc. SCR33x USB Smart Card Reader 0"
  // The "numChanged" indicates that one reader's status changed.  
  // The "changed":true indicates the reader that changed.   The state is now "present".

  // {
  //   "numChanged": 1,
  //   "reader": [
  //     {
  //       "name": "Alcor Micro USB Smart Card Reader 0",
  //       "changed": false,
  //       "state": "empty"
  //     },
  //     {
  //       "name": "Generic Smart Card Reader Interface 0",
  //       "changed": false,
  //       "state": "present",
  //       "atr": "3BFC180000813180459067464A00641606F2727E00E0"
  //     },
  //     {
  //       "name": "SCM Microsystems Inc. SCR33x USB Smart Card Reader 0",
  //       "changed": true,
  //       "state": "present",
  //       "atr": "3BDF96FF8131FE455A018048494443313158587300011B09"
  //     }
  //   ]
  // }

  // Find the reader that changed...
  var changed = false;
  var state = '';
  var atr = '';

  final numChanged = json2.intOf('numChanged');
  print('number of readers with a changed state: $numChanged');

  i = 0;
  countI = json2.sizeOfArray('reader');
  while (i < countI) {
    json2.i = i;
    changed = json2.boolOf('reader[i].changed');
    if (changed) {
      name = json2.stringOf('reader[i].name');
      state = json2.stringOf('reader[i].state');

      print('Changed: ');
      print('    reader name: $name');
      print('    new state: $state');

      // If a card is now in this reader, we should have the ATR of the card..
      if (json2.hasMember('reader[i].atr')) {
        atr = json2.stringOf('reader[i].atr');
        print('    ATR of card inserted into this reader: $atr');
      }
    }

    i++;
  }

  // The output from the above loop:

  // number of readers with a changed state: 1
  // Changed: 
  //     reader name: SCM Microsystems Inc. SCR33x USB Smart Card Reader 0
  //     new state: present
  //     ATR of card inserted into this reader: 3BDF96FF8131FE455A018048494443313158587300011B09

  // Applications should always release the context when finished.
  try {
    scard.releaseContext();
  } on ChilkatException catch (e) {
    print(e.lastErrorText);
  }
}