title: IDTech Unimag Card Swiper on Android
body: <p>I've been working on <strong>Android (v2.3)</strong> for a couple of weeks now, and I've stumbled upon some problems with the <strong>Unimag Card Swiper from IDTECH</strong>.</p>
  
  <p>The unit comes with a scarce documentation and the demo app from the SDK implements the firmware update and a few classes for dialogs and such which really offuscate how to achieve basic functionality (added to the few and not so good comments in the code).</p>
  
  <p>I have implemented the interface in a basic activity and tried to detect when the unit is connected or disconnected but it seems the listener catches both events (connection/disconnection) as "disconnect", let alone trying to read a card.</p>
  
  <p><strong>Has anyone worked with this unit on Android and has some clear examples?</strong></p>
  
  <p>By the way, here is my class:</p>
  
  <pre><code>package com.card.swipe;
  
  import java.io.File;
  import java.io.FileOutputStream;
  import java.io.InputStream;
  import IDTech.MSR.uniMag.uniMagReader;
  import IDTech.MSR.uniMag.uniMagReaderMsg;
  import android.app.Activity;
  import android.os.Bundle;
  import android.util.Log;
  import android.view.View;
  import android.widget.TextView;
  import android.widget.Toast;
  
  public class CardSwipeTestActivity extends Activity implements uniMagReaderMsg {
  
      private uniMagReader myUniMagReader = null;
      private TextView etCardData;
      private String _strMSRData = null;
      private byte[]_MSRData = null;
      private String _strStatus = null;
      private int _nGetChallengeResult = 0;
  
      @Override
      public void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.main);
  //      InitializeUI();
          InitializeReader();  
          String strManufacture = myUniMagReader.getInfoManufacture();
          String strModel = myUniMagReader.getInfoModel();
          String strSDKVerInfo = myUniMagReader.getSDKVersionInfo();
          String strOSVerInfo = android.os.Build.VERSION.RELEASE;
          etCardData = (TextView)findViewById(R.id.text_view);
          etCardData.setText("Phone: "+strManufacture+"\n"+"Model: "+strModel+"\n"+"SDK Ver: "+strSDKVerInfo+"\nOS Version: "+strOSVerInfo);      
      }
  
      @Override
      protected void onPause() {
          // TODO Auto-generated method stub
          if(myUniMagReader!=null)
          {
              //you should stop swipe card and unregister when the application go to background
              myUniMagReader.stopSwipeCard();         
  //          myUniMagReader.unregisterListen();
  //          myUniMagReader.release();
          }
          super.onPause();
      }
      @Override
      protected void onResume() {
          // TODO Auto-generated method stub
          // you should register to listen the headset event when the application resumed.
  //      if(myUniMagReader!=null)
  //      {
  ////            myUniMagReader.registerListen();
  //          if(_bCheckedSaveLogItem==true)
  //              myUniMagReader.setSaveLogEnable(true);
  //          else
  //              myUniMagReader.setSaveLogEnable(false);
  //      }
  //      if(itemStartSC!=null)
  //          itemStartSC.setEnabled(true); 
  //      waitingCommandResult=false;
          super.onResume();
      }
      @Override
      protected void onDestroy() {
          myUniMagReader.release();
          super.onDestroy();      
          android.os.Process.killProcess(android.os.Process.myPid());
      }    
  
      //********************************************************************************//    
  
      @Override
      public boolean getUserGrant(int arg0, String arg1) {
          // TODO Auto-generated method stub
          return false;
      }
  
      @Override
      public void onReceiveMsgAutoConfigProgress(int arg0) {
          // TODO Auto-generated method stub
  
      }
  
      @Override
      public void onReceiveMsgCardData(byte arg0, byte[] arg1) {
          // TODO Auto-generated method stub
          Log.d("SWIPE", "Card swiped!");
          Toast.makeText(getApplicationContext(), "Card swiped!", Toast.LENGTH_SHORT).show();
      }
  
      @Override
      public void onReceiveMsgCommandResult(int arg0, byte[] arg1) {
          // TODO Auto-generated method stub
  
      }
  
      @Override
      public void onReceiveMsgConnected() {
          Log.d("CONNECTION","Swiper Connected");
          Toast.makeText(getApplicationContext(), "Swiper Connected!", Toast.LENGTH_SHORT).show();
      }
  
      @Override
      public void onReceiveMsgDisconnected() {
          Log.d("CONNECTION","Swiper Disconnected");
          Toast.makeText(getApplicationContext(), "Swiper Disconnected!", Toast.LENGTH_SHORT).show();
      }
  
      @Override
      public void onReceiveMsgFailureInfo(int arg0, String arg1) {
          // TODO Auto-generated method stub
          Log.d("CONNECTION","Swiper Failure");
      }
  
      @Override
      public void onReceiveMsgSDCardDFailed(String arg0) {
          // TODO Auto-generated method stub
  
      }
  
      @Override
      public void onReceiveMsgTimeout(String arg0) {
          Log.d("TIMEOUT","Timed out!");  
          Toast.makeText(getApplicationContext(), "Timed out!", Toast.LENGTH_SHORT).show();   
      }
  
      @Override
      public void onReceiveMsgToConnect() {
          Log.d("CONNECTION","Swiper Powered Up");
          Toast.makeText(getApplicationContext(), "Swiper Powered Up", Toast.LENGTH_SHORT).show();
      }
  
      @Override
      public void onReceiveMsgToSwipeCard() {
          Log.d("SWIPE","Ready to swipe!");
          Toast.makeText(getApplicationContext(), "Ready to swipe!", Toast.LENGTH_SHORT).show();      
      }
  
      //********************************************************************************//
  
      private void InitializeReader()
      {
          if(myUniMagReader==null)
              myUniMagReader =  new uniMagReader(this,this);
  
          myUniMagReader.setVerboseLoggingEnable(true);
          myUniMagReader.registerListen();
          //load the XML configuratin file
          String fileNameWithPath = getXMLFileFromRaw();
          if(!isFileExist(fileNameWithPath)) { fileNameWithPath = null; }        
          myUniMagReader.setXMLFileNameWithPath(fileNameWithPath);
          myUniMagReader.loadingConfigurationXMLFile(true);
          myUniMagReader.setTimeoutOfSwipeCard(5); 
      }
  
      private boolean isFileExist(String path) {
          if(path==null)
              return false;
          File file = new File(path);
          if (!file.exists()) {
            return false ;
          }
          return true;
      }   
  
      private String getXMLFileFromRaw( ){
          //the target filename in the application path
         String fileNameWithPath = null;
         fileNameWithPath = "idt_unimagcfg_default.xml";
  
         try{
             InputStream in = getResources().openRawResource(R.raw.idt_unimagcfg_default);
             int length = in.available();
             byte [] buffer = new byte[length];
             in.read(buffer);        
             in.close();
  
             deleteFile(fileNameWithPath);
  
             FileOutputStream fout = openFileOutput(fileNameWithPath, MODE_PRIVATE);
             fout.write(buffer);
             fout.close();
  
             // to refer to the application path
             File fileDir = this.getFilesDir();
             fileNameWithPath = fileDir.getParent() + java.io.File.separator + fileDir.getName();
             fileNameWithPath = fileNameWithPath+java.io.File.separator+"idt_unimagcfg_default.xml";
  
             }
             catch(Exception e){
             e.printStackTrace();
             fileNameWithPath = null;
             }
  
          return   fileNameWithPath;
  
          }   
  
      public void swipe(View v)
      {
          if(myUniMagReader!=null)
          {
              myUniMagReader.startSwipeCard();
          }
          if(myUniMagReader.isSwipeCardRunning()==true)
          {
              Log.d("SWIPE","Swipe Card Running!");
          }       
      }
  
      private String getHexStringFromBytes(byte []data)
      {
          if(data.length&lt;=0) return null;
          StringBuffer hexString = new StringBuffer();
          String fix = null;
          for (int i = 0; i &lt; data.length; i++) {
              fix = Integer.toHexString(0xFF &amp; data[i]);
              if(fix.length()==1)
                  fix = "0"+fix;
              hexString.append(fix);
         }
         fix = null;
         fix = hexString.toString();
         return fix;
      }
  
      public byte[] getBytesFromHexString(String strHexData)
      {
          if (1==strHexData.length()%2) {
              return null;
          }
          byte[] bytes = new byte[strHexData.length()/2];
          for (int i=0;i&lt;strHexData.length()/2;i++) {
              bytes[i] = (byte) Integer.parseInt(strHexData.substring(i*2, (i+1)*2) , 16);
          }
          return bytes;
      }
  }
  </code></pre>
  
  <p>(There are some unimplemented methods there as well)</p>