2015-04-21 2 views
-1

Я новичок в технологии NFC и думал начать с чтения и записи тега. Для чтения я использую смарт-карту MIRFARE 1K, и для записи я использую NTAG203. Все, что я хочу, это получить TagID в процессе чтения и отправить метку TagID и datetime в NTAG203.Получение NFC TagID смарт-карты NTAG и MIFARE

Вопросы:

  1. Мое приложение испытывает трудности при составлении. Он продолжает давать мне ошибку при создании окончательного архива: не удалось создать «C: \ Android WS \ TabletApp \ bin \ TabletApp.apks»: доступ запрещен. Я очищаю проект и перезапускаю Eclipse, но напрасно. Он только уходит, когда я перезагружаю свой ноутбук. Любые предложения для этого?

  2. Когда приложение работает, оно все еще не дает мне идентификатор. Я сканирую свою карточку/тег, и MainActivity (ScanningActivity здесь) загружается снова и снова. Контроль не идет дальше этого. Любые предложения о том, как работать над этим?

public class ScanningActivity extends Activity { 
    private NfcAdapter sNfcAdapter; 
    Locale locale = new Locale("en", "US"); 
    byte[] langBytes = locale.getLanguage().getBytes(Charset.forName("US-ASCII")); 
    boolean encodeInUtf8 = false; 
    Charset utfEncoding = encodeInUtf8 ? Charset.forName("UTF-8") : Charset.forName("UTF-16"); 
    int utfBit = encodeInUtf8 ? 0 : (1 << 7); 
    char status = (char)(utfBit + langBytes.length); 

    static String bin2hex(byte[] data) { 
     return String.format("%0" + (data.length * 2) + "X", new BigInteger(1, data)); 
    } 
    /* write to tag */ 

    boolean writeNdefMessageToTag(NdefMessage message, Tag detectedTag) throws FormatException { 
     int size = message.toByteArray().length; 
     try { 
      Ndef ndef = Ndef.get(detectedTag); 
      if (ndef != null) { 
       ndef.connect(); 
       if (!ndef.isWritable()) { 
        Toast.makeText(this, "Tag is read-only.", Toast.LENGTH_SHORT).show(); 
        return false; 
       } 
       if (ndef.getMaxSize() < size) { 
        Toast.makeText(this, 
            "The data cannot be written since the tag capacity is" + ndef.getMaxSize() + 
            " bytes and the data to be transferred is " + size + " bytes", 
            Toast.LENGTH_LONG).show(); 
        return false; 
       } 

       ndef.writeNdefMessage(message); 
       ndef.close(); 
       Toast.makeText(this, "Data sent to the Tag", Toast.LENGTH_LONG).show(); 
       return true; 

      } else { 
       NdefFormatable ndefFormat = NdefFormatable.get(detectedTag); 
       if (ndefFormat != null) { 
        try { 
         ndefFormat.connect(); 
         ndefFormat.format(message); 
         ndefFormat.close(); 
         Toast.makeText(this, "Data sent", Toast.LENGTH_LONG).show(); 
         return true; 
        } catch (IOException e) { 
         Toast.makeText(this, "Unable to format tag", Toast.LENGTH_LONG).show(); 
         return false; 
        } 
       } else { 
        Toast.makeText(this, "Not supported tag", Toast.LENGTH_LONG).show(); 
        return false; 
       } 

      } 
     } catch (IOException e) { 
      Toast.makeText(this, "Sending failed", Toast.LENGTH_LONG).show(); 
     } 
     return false; 

    } 

    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_scanning); 

     TextView tg = (TextView)findViewById(R.id.tagid); 
     final TextView tvtime = (TextView)findViewById(R.id.datetime); 
     SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss a"); 
     String currentTimeStamp = dateFormat.format(new Date()); // Find todays date 
     tvtime.setText(currentTimeStamp); 

     sNfcAdapter = NfcAdapter.getDefaultAdapter(this); 

     IntentFilter tagDetected = new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED); 
     tagDetected.addCategory(Intent.CATEGORY_DEFAULT); 
     if (sNfcAdapter == null) { 
      Toast.makeText(this, "This device does not support NFC or you have not scanned the card properly", 
          Toast.LENGTH_LONG).show(); 
      return; 
     } 

     if (!sNfcAdapter.isEnabled()) { 
      Toast.makeText(this, "Looks like the NFC is not enabled on your device", Toast.LENGTH_LONG).show(); 
      new AlertDialog.Builder(this).setTitle("NFC disabled").setMessage(
        "Looks like the NFC is not enabled on your device. Please enable it.").setPositiveButton(
        "Ok", null).show(); 
     } 
     if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(getIntent().getAction())) { 
      Tag tag = getIntent().getParcelableExtra(NfcAdapter.EXTRA_TAG); 
      try { 
       String TagID = tag.getId().toString(); 
       tg.setText(bin2hex(tag.getId())); 
       Toast.makeText(getApplicationContext(), bin2hex(tag.getId()), Toast.LENGTH_LONG).show(); 
       Toast.makeText(this, TagID, Toast.LENGTH_LONG).show(); 
      } catch (Exception ex) { 
       new AlertDialog.Builder(this).setTitle("Error!").setPositiveButton("Ok", 
                        new DialogInterface.OnClickListener() { 
        public void onClick(DialogInterface dialog, int which) { 
         Intent i = new Intent(ScanningActivity.this, ScanningActivity.class); 
         startActivity(i); 
        } 
       }).setMessage(ex.getMessage() + "\n\nPlease click Ok. This will restart the application").create().show(); 

       new AlertDialog.Builder(this).setTitle("Transferring the data").setPositiveButton("Ok", 
                            new DialogInterface.OnClickListener() { 
        @Override 
        public void onClick(DialogInterface dialog, int which) { 
         // TODO Auto-generated method stub 
         TextView tvData = (TextView)findViewById(R.id.Data); 
         if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) { 
          Tag tag1 = getIntent().getParcelableExtra(NfcAdapter.EXTRA_TAG); 
          String DataToSend = tvtime.getText().toString() + tag1.getId().toString(); 
          //String DataToSend = "Data"; 
          //tvData.setText(tvtime.getText().toString()+tag.getId().toString()); 
          byte[] textBytes = DataToSend.getBytes(utfEncoding); 
          byte[] dataa = new byte[1 + langBytes.length + textBytes.length]; 
          dataa[0] = (byte)status; 
          System.arraycopy(langBytes, 0, dataa, 1, langBytes.length); 
          System.arraycopy(textBytes, 0, dataa, 1 + langBytes.length, textBytes.length);; 
          NdefRecord textRecord = new NdefRecord(NdefRecord.TNF_WELL_KNOWN, 
                    NdefRecord.RTD_TEXT, new byte[0], dataa); 
          NdefMessage newMessage = new NdefMessage(new NdefRecord[] { textRecord }); 

          try { 
           writeNdefMessageToTag(newMessage, tag1); 
          } catch (FormatException e) { 

           e.printStackTrace(); 
          } 
         } 
        } 
       }).setMessage(
         "Place this tablet on the RFID Tag on the Microbiology Form. Keep it there until you get to the next screen").create().show(); 

      } 
     } 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 

     getMenuInflater().inflate(R.menu.scanning, menu); 
     return true; 
    } 
} 

и Manifest является

<uses-permission android:name="android.permission.NFC"/> 

<uses-sdk 
    android:minSdkVersion="13" 
    android:targetSdkVersion="17" /> 

<application 
    android:allowBackup="true" 
    android:icon="@drawable/ic_launcher" 
    android:label="@string/app_name" 
    android:theme="@style/AppTheme" > 
    <activity 
     android:name="com.example.tabletapp.ScanningActivity" 
     android:label="@string/app_name" > 
     <intent-filter> 
      <action android:name="android.intent.action.MAIN" /> 
      <category android:name="android.intent.category.LAUNCHER" /> 
     </intent-filter> 
     <intent-filter> 
      <action android:name="android.nfc.action.NDEF_DISCOVERED" /> 
      <category android:name="android.intent.category.DEFAULT"/> 
      <data android:mimeType="text/plain" /> 
     </intent-filter> 
    </activity> 
</application> 

Update:

  1. Приложение не показывает никаких тостов. Когда я кладу карточку/бирку на устройство, я спрашиваю, какое приложение мне нравится использовать. Я выбираю тот, о котором мы говорим, и снова загружается «ScanningActivity» (MainActivity). Я также не показываю идентификатор и не прохожу мимо сканирования.

  2. Я хочу прочитать идентификатор с карты, а затем записать его вместе с меткой времени в другой тег.

+0

Я не понимаю, почему кто-то отказался от этого вопроса. Если вы считаете, что это не подходящий вопрос, или если ему что-то не хватает, прокомментируйте также. – CSA

+0

Какова фактическая проблема, которая у вас есть? Отображает ли ваше приложение тост (один с идентификатором тега или любым сообщением об ошибке)? Вы хотите прочитать идентификатор из тега, а затем записать его в тот же тег или в другой тег? Ваше приложение читает идентификатор в 'R.id.tagid', и ваша проблема заключается в том, что вы не можете написать второй тег или даже не справиться с этим? –

+0

@MichaelRoland Вот ответы. Извинения за то, что они не были ясны раньше. 1. Приложение не показывает тостов. Когда я кладу карточку/бирку на устройство, я спрашиваю, какое приложение мне нравится использовать. Я выбираю тот, о котором мы говорим, и снова загружается «ScanningActivity» (MainActivity). Я также не показываю идентификатор и не прохожу мимо сканирования. 2. Я хочу прочитать идентификатор с карты, а затем записать его вместе с меткой времени в другой тег. – CSA

ответ

1

Там довольно много проблем в вашем коде, так что я буду просто сосредоточиться на наиболее очевидные из них:

  1. Вы зарегистрировались на NDEF_DISCOVERED в вашем AndroidManifest.xml. Однако в onCreate() вы будете читать только удостоверение личности, когда получите намерение TAG_DISCOVERED. Вы должны изменить это, чтобы соответствовать намерению NDEF_DISCOVERED. (Я тем самым предполагаю, что ваш тег содержит текстовую запись, соответствующую вашему целевому фильтру.)

  2. tag.getId().toString() не даст вам много полезной информации, так как tag.getId() возвращает массив байтов. Вы всегда можете использовать свой метод bin2hex() для преобразования идентификатора в удобочитаемую строку.

  3. Вы должны избегать взаимодействия с тегами NFC при нажатии кнопки. (Например, то, что вы сейчас делаете в onClick(DialogInterface dialog, int which).) И щелчок кнопки, и взаимодействие с NFC следует рассматривать как человеческие входы, и вы должны избегать одновременного ввода двух человеческих входов. (Кроме того, в базе данных есть событие, и вы не можете напрямую их комбинировать.) Вместо этого вы можете установить флаг в методе onClick(), который указывает, что данные должны быть записаны в тег при следующем событии обнаружения NFC.

  4. Если вы хотите отсканировать первый тег, запустите его из-за этого события и откройте его, пока вы сканируете второй тег, вы должны использовать foreground dispatch system (также см. this answer). Таким образом, вы на переднем плане можете обрабатывать повторное сканирование тегов без перезапуска (и не давая контроль над другими действиями, которые иначе срабатывали бы тегом).