2016-03-19 18 views
0

Ich erstelle eine App, ich möchte die NFC-Seriennummer lesen, speichern (vielleicht in einer gemeinsamen Präferenz) und dann die SN verwenden, um eine Aktion auszulösen, wenn es wahr ist.NFC-Seriennummer (UID) zu String

Ich habe mein Projekt auf GitHub hochgeladen in der Hoffnung es besser erklärt, was ich versuche zu tun. https://github.com/soboapps/PunchCard

Ich fand etwas Code, der das NFC-Tag liest und es funktioniert großartig. Ich habe es in meine App integriert, aber mein Kampf versucht, die einzelnen Teile des Tags zu extrahieren.

Könnte jemand bitte sagen Sie mir, wie zu bekommen, was ich glaube, ist in

resolveIntent(Intent intent) 
    byte[] id = intent.getByteArrayExtra(NfcAdapter.EXTRA_ID); 

Aber ich kann einfach nicht herausfinden, wie es in einen String zu konvertieren, damit ich es speichern.

Hier ist die gesamte Klasse. Es gibt andere Klassen, die mit diesem Code kommen, aber ich denke, was ich brauche, ist hier irgendwo.

package com.soboapps.compare; 

import android.app.AlertDialog; 
import android.app.PendingIntent; 
import android.content.DialogInterface; 
import android.content.Intent; 
import android.content.res.Configuration; 
import android.nfc.NdefMessage; 
import android.nfc.NdefRecord; 
import android.nfc.NfcAdapter; 
import android.nfc.Tag; 
import android.nfc.tech.MifareClassic; 
import android.nfc.tech.MifareUltralight; 
import android.os.Bundle; 
import android.os.Parcelable; 
import android.provider.Settings; 
import android.support.v4.view.GravityCompat; 
import android.support.v4.widget.DrawerLayout; 
import android.support.v7.app.ActionBarDrawerToggle; 
import android.support.v7.widget.Toolbar; 
import android.view.LayoutInflater; 
import android.view.MenuItem; 
import android.support.v7.app.AppCompatActivity; 
import android.support.design.widget.NavigationView; 
import android.os.Handler; 
import android.widget.LinearLayout; 
import android.widget.TextView; 

import java.nio.charset.Charset; 
import java.text.DateFormat; 
import java.text.SimpleDateFormat; 
import java.util.Date; 
import java.util.List; 
import java.util.Locale; 

import com.soboapps.compare.record.ParsedNdefRecord; 


public class MainActivity extends AppCompatActivity implements 
     NavigationView.OnNavigationItemSelectedListener { 

    public static final String TAG = "NfcDemo"; 

    //Declaration 
    private static final String NAV_ITEM_ID = "navItemId" ; 
    private static final long DRAWER_CLOSE_DELAY_MS = 300 ; 
    private DrawerLayout mDrawerLayout; 
    private int mNavItemId; 
    private ActionBarDrawerToggle mDrawerToggle; 

    private final CofFragment mCofFragment= new CofFragment(); 
    private final SandFragment mSandFragment = new SandFragment(); 
    private final Handler mDrawerActionHandler = new Handler(); 

    private static final DateFormat TIME_FORMAT = SimpleDateFormat.getDateTimeInstance(); 
    private LinearLayout mTagContent; 

    private NfcAdapter mAdapter; 
    private PendingIntent mPendingIntent; 
    private NdefMessage mNdefPushMessage; 

    private AlertDialog mDialog; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     // Initialize Drawer layout -> activity_main 
     mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); 

     //Initialize Toolbar android.support.v7.widget.Toolbar 
     Toolbar mToolbar = (Toolbar) findViewById(R.id.toolbar); 
     setSupportActionBar(mToolbar); 

     //Load saved navigation state if present 
     if (null==savedInstanceState){ 
      mNavItemId = R.id.drawer_item_1; 
     }else{ 
      mNavItemId = savedInstanceState.getInt(NAV_ITEM_ID); 
     } 

     // Listen to navigation events 
     NavigationView navigationView = (NavigationView) findViewById(R.id.navigation); 
     navigationView.setNavigationItemSelectedListener(this); 

     //Select the Correct nav menu item 
     navigationView.getMenu().findItem(mNavItemId).setChecked(true); 

     // Setup the humberger icon to open and close drawer 
     mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, mToolbar, R.string.open, R.string.close); 
     mDrawerLayout.setDrawerListener(mDrawerToggle); 
     mDrawerToggle.syncState(); 

     // navigate function to swich between items id 
     // parameter item id 
     navigate(mNavItemId); 

     mTagContent = (LinearLayout) findViewById(R.id.list); 
     resolveIntent(getIntent()); 

     mDialog = new AlertDialog.Builder(this).setNeutralButton("Ok", null).create(); 

     mAdapter = NfcAdapter.getDefaultAdapter(this); 
     if (mAdapter == null) { 
      showMessage(R.string.error, R.string.no_nfc); 
      finish(); 
      return; 
     } 

     mPendingIntent = PendingIntent.getActivity(this, 0, 
       new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0); 
     mNdefPushMessage = new NdefMessage(new NdefRecord[] { newTextRecord(
       "Message from NFC Reader :-)", Locale.ENGLISH, true) }); 


    } 

    private void navigate(final int itemId) { 
     switch (itemId){ 
      case R.id.drawer_item_1: 
       //start about fragment 
       getFragmentManager().beginTransaction().replace(R.id.content,mCofFragment).commit(); 
       break; 
      case R.id.drawer_item_2: 
       //start project fragment 
       getFragmentManager().beginTransaction().replace(R.id.content, mSandFragment).commit(); 
       break; 
     } 
    } 


    private void showMessage(int title, int message) { 
     mDialog.setTitle(title); 
     mDialog.setMessage(getText(message)); 
     mDialog.show(); 
    } 

    private NdefRecord newTextRecord(String text, Locale locale, boolean encodeInUtf8) { 
     byte[] langBytes = locale.getLanguage().getBytes(Charset.forName("US-ASCII")); 

     Charset utfEncoding = encodeInUtf8 ? Charset.forName("UTF-8") : Charset.forName("UTF-16"); 
     byte[] textBytes = text.getBytes(utfEncoding); 

     int utfBit = encodeInUtf8 ? 0 : (1 << 7); 
     char status = (char) (utfBit + langBytes.length); 

     byte[] data = new byte[1 + langBytes.length + textBytes.length]; 
     data[0] = (byte) status; 
     System.arraycopy(langBytes, 0, data, 1, langBytes.length); 
     System.arraycopy(textBytes, 0, data, 1 + langBytes.length, textBytes.length); 

     return new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, new byte[0], data); 
    } 

    @Override 
    protected void onResume() { 
     super.onResume(); 
     if (mAdapter != null) { 
      if (!mAdapter.isEnabled()) { 
       showWirelessSettingsDialog(); 
      } 
      mAdapter.enableForegroundDispatch(this, mPendingIntent, null, null); 
      mAdapter.enableForegroundNdefPush(this, mNdefPushMessage); 
     } 
    } 

    @Override 
    protected void onPause() { 
     super.onPause(); 
     if (mAdapter != null) { 
      mAdapter.disableForegroundDispatch(this); 
      mAdapter.disableForegroundNdefPush(this); 
     } 
    } 

    private void showWirelessSettingsDialog() { 
     AlertDialog.Builder builder = new AlertDialog.Builder(this); 
     builder.setMessage(R.string.nfc_disabled); 
     builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { 
      public void onClick(DialogInterface dialogInterface, int i) { 
       Intent intent = new Intent(Settings.ACTION_WIRELESS_SETTINGS); 
       startActivity(intent); 
      } 
     }); 
     builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { 
      public void onClick(DialogInterface dialogInterface, int i) { 
       finish(); 
      } 
     }); 
     builder.create().show(); 
     return; 
    } 

    private void resolveIntent(Intent intent) { 
     String action = intent.getAction(); 
     if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action) 
       || NfcAdapter.ACTION_TECH_DISCOVERED.equals(action) 
       || NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) { 
      Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES); 
      NdefMessage[] msgs; 
      if (rawMsgs != null) { 
       msgs = new NdefMessage[rawMsgs.length]; 
       for (int i = 0; i < rawMsgs.length; i++) { 
        msgs[i] = (NdefMessage) rawMsgs[i]; 
       } 
      } else { 
       // Unknown tag type 
       byte[] empty = new byte[0]; 
       byte[] id = intent.getByteArrayExtra(NfcAdapter.EXTRA_ID); 

       Parcelable tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); 


       byte[] payload = dumpTagData(tag).getBytes(); 
       NdefRecord record = new NdefRecord(NdefRecord.TNF_UNKNOWN, empty, id, payload); 
       NdefMessage msg = new NdefMessage(new NdefRecord[] { record }); 
       msgs = new NdefMessage[] { msg } ; 



      } 
      // Setup the views 

      buildTagViews(msgs); 


     } 



     //To display the UID 

    } 



    private String dumpTagData(Parcelable p) { 
     StringBuilder sb = new StringBuilder(); 
     Tag tag = (Tag) p; 
     byte[] id = tag.getId(); 
     sb.append("Tag ID (hex): ").append(getHex(id)).append("\n"); 
     sb.append("Tag ID (dec): ").append(getDec(id)).append("\n"); 
     sb.append("ID (reversed): ").append(getReversed(id)).append("\n"); 

     String prefix = "android.nfc.tech."; 
     sb.append("Technologies: "); 
     for (String tech : tag.getTechList()) { 
      sb.append(tech.substring(prefix.length())); 
      sb.append(", "); 
     } 
     sb.delete(sb.length() - 2, sb.length()); 
     for (String tech : tag.getTechList()) { 
      if (tech.equals(MifareClassic.class.getName())) { 
       sb.append('\n'); 
       MifareClassic mifareTag = MifareClassic.get(tag); 
       String type = "Unknown"; 
       switch (mifareTag.getType()) { 
        case MifareClassic.TYPE_CLASSIC: 
         type = "Classic"; 
         break; 
        case MifareClassic.TYPE_PLUS: 
         type = "Plus"; 
         break; 
        case MifareClassic.TYPE_PRO: 
         type = "Pro"; 
         break; 
       } 
       sb.append("Mifare Classic type: "); 
       sb.append(type); 
       sb.append('\n'); 

       sb.append("Mifare size: "); 
       sb.append(mifareTag.getSize() + " bytes"); 
       sb.append('\n'); 

       sb.append("Mifare sectors: "); 
       sb.append(mifareTag.getSectorCount()); 
       sb.append('\n'); 

       sb.append("Mifare blocks: "); 
       sb.append(mifareTag.getBlockCount()); 
      } 

      if (tech.equals(MifareUltralight.class.getName())) { 
       sb.append('\n'); 
       MifareUltralight mifareUlTag = MifareUltralight.get(tag); 
       String type = "Unknown"; 
       switch (mifareUlTag.getType()) { 
        case MifareUltralight.TYPE_ULTRALIGHT: 
         type = "Ultralight"; 
         break; 
        case MifareUltralight.TYPE_ULTRALIGHT_C: 
         type = "Ultralight C"; 
         break; 
       } 
       sb.append("Mifare Ultralight type: "); 
       sb.append(type); 
      } 
     } 

     return sb.toString(); 
    } 

    private String getHex(byte[] bytes) { 
     StringBuilder sb = new StringBuilder(); 
     for (int i = bytes.length - 1; i >= 0; --i) { 
      int b = bytes[i] & 0xff; 
      if (b < 0x10) 
       sb.append('0'); 
      sb.append(Integer.toHexString(b)); 
      if (i > 0) { 
       sb.append(" "); 
      } 
     } 
     return sb.toString(); 

    } 

    private long getDec(byte[] bytes) { 
     long result = 0; 
     long factor = 1; 
     for (int i = 0; i < bytes.length; ++i) { 
      long value = bytes[i] & 0xffl; 
      result += value * factor; 
      factor *= 256l; 
     } 
     return result; 
    } 

    private long getReversed(byte[] bytes) { 
     long result = 0; 
     long factor = 1; 
     for (int i = bytes.length - 1; i >= 0; --i) { 
      long value = bytes[i] & 0xffl; 
      result += value * factor; 
      factor *= 256l; 
     } 
     return result; 
    } 

    void buildTagViews(NdefMessage[] msgs) { 
     if (msgs == null || msgs.length == 0) { 
      return; 
     } 
     LayoutInflater inflater = LayoutInflater.from(this); 
     LinearLayout content = mTagContent; 

     // Parse the first message in the list 
     // Build views for all of the sub records 
     Date now = new Date(); 
     List<ParsedNdefRecord> records = NdefMessageParser.parse(msgs[0]); 
     final int size = records.size(); 
     for (int i = 0; i < size; i++) { 
      TextView timeView = new TextView(this); 
      timeView.setText(TIME_FORMAT.format(now)); 
      content.addView(timeView, 0); 
      ParsedNdefRecord record = records.get(i); 

      content.addView(record.getView(this, inflater, content, i), 1 + i); 
      content.addView(inflater.inflate(R.layout.tag_divider, content, false), 2 + i); 
     } 
    } 
    @Override 
    public void onConfigurationChanged(final Configuration newConfig){ 
     super.onConfigurationChanged(newConfig); 
     mDrawerToggle.onConfigurationChanged(newConfig); 
    } 
    @Override 
    public void onBackPressed(){ 
     if(mDrawerLayout.isDrawerOpen(GravityCompat.START)){ 
      mDrawerLayout.closeDrawer(GravityCompat.START); 
     }else{ 
      super.onBackPressed(); 
     } 
    } 
    @Override 
    public void onSaveInstanceState(final Bundle outState){ 
     super.onSaveInstanceState(outState); 
     outState.putInt(NAV_ITEM_ID, mNavItemId); 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     // Handle action bar item clicks here. The action bar will 
     // automatically handle clicks on the Home/Up button, so long 
     // as you specify a parent activity in AndroidManifest.xml. 
     final int id = item.getItemId(); 

     if(id== android.support.v7.appcompat.R.id.home){ 
      return mDrawerToggle.onOptionsItemSelected(item); 
     } 
     return super.onOptionsItemSelected(item); 
    } 

    /** 
    * -Handles clicks on the navigation menu 
    * @param menuItem 
    * @return 
    */ 
    @Override 
    public boolean onNavigationItemSelected(final MenuItem menuItem) { 
     //Update highlighted item in the navigation menu 
     menuItem.setChecked(true); 
     mNavItemId = menuItem.getItemId(); 

     // Time gap after closing the navigation to see animation 
     mDrawerLayout.closeDrawer(GravityCompat.START); 
     mDrawerActionHandler.postDelayed(new Runnable() { 
      @Override 
      public void run() { 
       navigate(menuItem.getItemId()); 
      } 
     }, DRAWER_CLOSE_DELAY_MS); 
     return true; 
    } 



    @Override 
    public void onNewIntent(Intent intent) { 
     setIntent(intent); 
     resolveIntent(intent); 
    } 
} 

EDIT:
Ich habe, was ich denke, wird vorgeschlagen. IO bekomme jetzt einen Fehler im "Kontext", aber ich möchte wirklich nur wissen, ob dies vorgeschlagen wird?

private String getHex(byte[] bytes) { 
    StringBuilder sb = new StringBuilder(); 
    for (int i = bytes.length - 1; i >= 0; --i) { 
     int b = bytes[i] & 0xff; 
     if (b < 0x10) 
      sb.append('0'); 
     sb.append(Integer.toHexString(b)); 
     if (i > 0) { 
      sb.append(" "); 
     } 
    } 

    return sb.toString(); 

    final SharedPreferences prefs = context.getSharedPreferences("CHECK_POINT_NAME",Context.MODE_PRIVATE); 
    SharedPreferences.Editor editor = prefs.edit(); 
    editor.putString("CHECK_POINT", String.valueOf(sb)); 
    editor.apply(); 

} 
+0

Was möchten Sie damit machen, nachdem Sie es gespeichert haben? Erwarten Sie eine bestimmte Formatierung? –

+0

Also, wenn ich das Tag scanne, kann ich überprüfen, dass es dasselbe Tag ist und dann diesen Scan "registrieren". Ein "Check-in" grundsätzlich. – Sobo

Antwort

1

Wenn Sie byte[] zu String konvertieren möchten schreiben Sie einfach

String s = new String(id); 

EDIT von here

String ByteArrayToHexString(byte [] inarray) 
    { 
    int i, j, in; 
    String [] hex = {"0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"}; 
    String out= ""; 

    for(j = 0 ; j < inarray.length ; ++j) 
     { 
     in = (int) inarray[j] & 0xff; 
     i = (in >> 4) & 0x0f; 
     out += hex[i]; 
     i = in & 0x0f; 
     out += hex[i]; 
     } 
    return out; 
} 
+1

Dies funktioniert nicht, da erwartet wird, dass das Bytearray eine Reihe von Bytes ist, die vom Standardzeichensatz des Systems beschrieben werden. NFC-IDs sind keine Zeichenfolgen, die wie folgt konvertiert werden können. –

+0

also will er eins nach dem anderen die Bytes? –

+0

Ich habe String s = new String (id) hinzugefügt; und dann dieser Toast ... Toast t = Toast.makeText (this.getApplicationContext(), s, Toastst.LENGTH_SHORT); t.setGravity (Gravity.TOP | Gravity.CENTER_HORIZONTAL, 0, 0); t.show(); Aber es zeigte nichts – Sobo

1

Sie tatsächlich eine Methode direkt in Ihrem Code, wandelt Byte Arrays, um Strings zu hexen. Es heißt getHex(). Sie können das NFC-ID-Byte-Array an es übergeben, um eine Hexadezimalzeichenfolge zu erhalten, die Sie speichern und mit anderen IDs vergleichen können, um festzustellen, ob sie mit einer anderen Seriennummer übereinstimmt.

+0

Ich bearbeitete meine Frage, um die getHex() mit, was ich "denke" Sie vorschlagen. Kannst du bitte bestätigen. Danke – Sobo

+0

Ich denke meine Frage ist Wie benutze ich diese Methode, um diese Nummer als SharedPreference zu speichern? – Sobo

+0

Sie erhalten einen String von getHex(), also speichern Sie ihn wie jeden anderen String und vergleichen ihn wie jeden anderen String. –

0

Ich fand die bessere Antwort für mein Projekt. Ich habe nfcTagSerialNum als public static String und dann habe ich die folgenden meiner resolveIntent (Internet Intent)

Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); 
byte[] extraID = tagFromIntent.getId(); 

StringBuilder sb = new StringBuilder(); 
for (byte b : extraID) { 
    sb.append(String.format("%02X", b)); 
}; 

nfcTagSerialNum = sb.toString(); 
Log.e("nfc ID", nfcTagSerialNum); 

Ich war dann in der Lage den String „nfcTagSerialNum“ zu verwenden, wo immer ich wollte.

Verwandte Themen