2016-03-19 24 views
0

NFCシリアル番号を読み込み、保存しておきたい(共有環境設定で)可能性がある場合は、SNを使用してアクションをトリガーするアプリを作成しています。NFCシリアル番号(UID)から文字列へ

GitHubに自分のプロジェクトをアップロードして、自分が何をしようとしているのかを詳しく説明したいと考えています。 https://github.com/soboapps/PunchCard

NFCタグを読み取るコードが見つかりました。うまくいきました。私はそれを私のアプリケーションに統合しましたが、私の苦労はタグの個々の部分を抽出しようとしています。

誰かがどのように私は

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

である。しかし、私はちょうど私がそれを保存できるように文字列に変換する方法を見つけ出すことができないと考えているものを手に入れる方法を教えてもらえます。

ここはクラス全体です。このコードには他にもクラスがありますが、必要なものはどこかにあると思います。

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:
私は私が提案していると思うものを追加しました。 IOは現在「コンテキスト」にエラーを表示していますが、実際にはこれが示唆されているかどうかを知りたいだけですか?

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

保管後に何をしたいですか?あなたはある意味でフォーマットされることを期待していますか? –

+0

私はタグをスキャンするときに、それが同じタグであることを確認してから、そのスキャンを「登録する」ことができます。基本的に「チェックイン」。 – Sobo

答えて

1

あなたはあなたが実際にバイトを変換し、あなたのコード内で右が方法を持っているだけで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

これは、バイト配列がシステムのデフォルトの文字セットで記述された一連のバイトであることを期待しているので機能しません。 NFC IDは、このように変換できる文字列ではありません。 –

+0

彼は1バイトずつバイトしたいですか? –

+0

String s = new String(id)を追加しました。トーストt = Toast.makeText(this.getApplicationContext()、s、Toastst.LENGTH_SHORT); t.setGravity(Gravity.TOP | Gravity.CENTER_HORIZONTAL、0、0); t.show();しかし、それは何も表示されませんでした – Sobo

1

から

String s = new String(id); 

EDIT を書くStringbyte[]を変換したい場合配列を16進文字列に変換します。それはgetHex()と呼ばれています。 NFC IDのバイト配列を渡して、他のIDと比較して別のシリアル番号と一致するかどうかを確認することができます。

+0

私はあなたが示唆していると思うものでgetHex()を含めるために私の質問を編集しました。あなたは確認していただけますか?ありがとう – Sobo

+0

私の質問は、どのように私はSharedPreferenceとしてその番号を格納するためにそのメソッドを使用すると思いますか? – Sobo

+0

getHex()からStringを取得しているので、他のStringと同じように格納し、他のStringと同じように比較します。 –

0

私のプロジェクトでより良い答えが見つかりました。私が欲しかったところはどこでも私は、文字列「nfcTagSerialNum」を使用することができました

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); 

(インターネット意図)私は公共の静的な文字列としてnfcTagSerialNumを加えた後、私は私のresolveIntentに以下を追加しました。

関連する問題