顯示具有 NFC 標籤的文章。 顯示所有文章
顯示具有 NFC 標籤的文章。 顯示所有文章

2015年2月10日 星期二

Android NFC Activity disable 關閉 近距離無線通訊

前篇有用到NFC使用方法,在可以使用NFC APP上,我們可能想要在一個頁面(Activity1)可以使用NFC,在下一個頁面(Activity2)不需要用到NFC,但是若沒有設定,仍會感應到tag資料,

所以需加上下列程式碼
/*此頁面關閉NFC感應*/
 @Override
 protected void onResume() {
  super.onResume();
  // creating pending intent:
  PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
    new Intent(this, getClass())
      .addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
  // enabling foreground dispatch for getting intent from NFC event:
  NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
  try {
//   nfcAdapter.enableForegroundDispatch(this, pendingIntent,
//     new IntentFilter[] { filter }, this.techList);  開啟nfc
   nfcAdapter.enableForegroundDispatch(this, pendingIntent,
     new IntentFilter[] {}, null); // 關閉nfc IntentFilter[] {}內設為空值, techList改為null空值
  } catch (NullPointerException e) {
  }
 }
參考資料: http://stackoverflow.com/questions/9748513/reading-nfc-tags-only-from-a-particuar-activity

2014年12月8日 星期一

Android NFC tag writer 寫入 訊息

NFC感應TAG,將訊息寫入TAG中
1.AndroidManifest.xml
加入權限
與最低版本
android:minsdkversion="17" android:targetsdkversion="17"
2.activity_main.xml



    

        

        
    

    

        

        
    

    


3.MainActivity.java
import java.io.IOException;
import nl.paulus.nfctagwriter.R;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.PendingIntent;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.nfc.tech.Ndef;
import android.nfc.tech.NdefFormatable;
import android.os.Bundle;
import android.os.Parcelable;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

/**
 * Activity to write NFC tags with own mimetype and ID Based on the excellent
 * tutorial by Jesse Chen
 * http://www.jessechen.net/blog/how-to-nfc-on-the-android-platform/
 */
public class MainActivity extends Activity {

 boolean mWriteMode = false;
 private NfcAdapter mNfcAdapter;
 private PendingIntent mNfcPendingIntent;

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

  ((Button) findViewById(R.id.button))
    .setOnClickListener(new OnClickListener() {

     @Override
     public void onClick(View v) {
      mNfcAdapter = NfcAdapter
        .getDefaultAdapter(MainActivity.this);
      mNfcPendingIntent = PendingIntent.getActivity(
        MainActivity.this,
        0,
        new Intent(MainActivity.this,
          MainActivity.class)
          .addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP),
        0);
      //開啟寫入
      enableTagWriteMode();

      new AlertDialog.Builder(MainActivity.this)
        .setTitle("感應tag寫入")
        .setOnCancelListener(
          new DialogInterface.OnCancelListener() {
           @Override
           public void onCancel(
             DialogInterface dialog) {
            //關閉寫入
            disableTagWriteMode();
           }

          }).create().show();
     }
    });
 }

 private void enableTagWriteMode() {
  mWriteMode = true;
  IntentFilter tagDetected = new IntentFilter(
    NfcAdapter.ACTION_TAG_DISCOVERED);
  IntentFilter[] mWriteTagFilters = new IntentFilter[] { tagDetected };
  mNfcAdapter.enableForegroundDispatch(this, mNfcPendingIntent,
    mWriteTagFilters, null);
 }

 private void disableTagWriteMode() {
  mWriteMode = false;
  mNfcAdapter.disableForegroundDispatch(this);
 }

 @SuppressLint("NewApi")
 @Override
 protected void onNewIntent(Intent intent) {
  // Tag writing mode
  if (mWriteMode
    && NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())) {
   Tag detectedTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
   NdefRecord record = NdefRecord.createMime( //需要Android 4.1(API Level 16)
     ((TextView) findViewById(R.id.mime)).getText().toString(),
     ((TextView) findViewById(R.id.value)).getText().toString()
       .getBytes());
   NdefMessage message = new NdefMessage(new NdefRecord[] { record });
   if (writeTag(message, detectedTag)) {
    Toast.makeText(this, "成功寫入!",
      Toast.LENGTH_LONG).show();
   }
  }
  
  //讀取寫入訊息 看是否有寫入
  
        try {
         Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
      NdefMessage[] msgs = new NdefMessage[rawMsgs.length];
      for (int i = 0; i < rawMsgs.length; i++) {
                msgs[i] = (NdefMessage) rawMsgs[i];
            }

            NdefMessage msg = msgs[0];
         String msgstring = new String(msg.getRecords()[0].getPayload(), "UTF-8");
         Toast.makeText(getApplicationContext(), msgstring, Toast.LENGTH_LONG).show();
   
        } catch (Exception e) {
            e.printStackTrace();
        }
 }

 /* 檢查訊息 */
 public boolean writeTag(NdefMessage message, Tag tag) {
  int size = message.toByteArray().length;
  try {
   Ndef ndef = Ndef.get(tag);
   if (ndef != null) {
    ndef.connect();
    if (!ndef.isWritable()) {
     Toast.makeText(getApplicationContext(),
       "Error: tag not writable", Toast.LENGTH_SHORT)
       .show();
     return false;
    }
    if (ndef.getMaxSize() < size) {
     Toast.makeText(getApplicationContext(),
       "Error: tag too small", Toast.LENGTH_SHORT).show();
     return false;
    }
    ndef.writeNdefMessage(message);
    return true;
   } else {
    NdefFormatable format = NdefFormatable.get(tag);
    if (format != null) {
     try {
      format.connect();
      format.format(message);
      return true;
     } catch (IOException e) {
      return false;
     }
    } else {
     return false;
    }
   }
  } catch (Exception e) {
   return false;
  }
 }
} 
參考來源:
https://github.com/balloob/Android-NFC-Tag-Writer 
http://stackoverflow.com/questions/7917567/strange-character-on-android-ndef-record-payload 

2014年11月25日 星期二

Android NFC tag 近距離無線通訊

需有NFC功能手機與感應卡(悠遊卡、學生證之類的)
首先在權限上將minSdkVersion修改為10並加入

1.AndroidManifest.xml



2.layout的activity_main.xml需有一個TextView顯示

3.MainActivity.java
public class Inventory extends Activity {
 
 /* NFC */
 // list of NFC technologies detected:
 private final String[][] techList = new String[][] { new String[] {
   NfcA.class.getName(), NfcB.class.getName(), NfcF.class.getName(),
   NfcV.class.getName(), IsoDep.class.getName(),
   MifareClassic.class.getName(), MifareUltralight.class.getName(),
   Ndef.class.getName() } };

 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.inventory);

 }

 /* NFC */
 @Override
 protected void onResume() {
  super.onResume();
  // creating pending intent:
  PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
    new Intent(this, getClass())
      .addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
  // creating intent receiver for NFC events:
  IntentFilter filter = new IntentFilter();
  filter.addAction(NfcAdapter.ACTION_TAG_DISCOVERED);
  filter.addAction(NfcAdapter.ACTION_NDEF_DISCOVERED);
  filter.addAction(NfcAdapter.ACTION_TECH_DISCOVERED);
  // enabling foreground dispatch for getting intent from NFC event:
  NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
  nfcAdapter.enableForegroundDispatch(this, pendingIntent,
    new IntentFilter[] { filter }, this.techList);
 }

 @Override
 protected void onPause() {
  super.onPause();
  // disabling foreground dispatch:
  NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
  nfcAdapter.disableForegroundDispatch(this);
 }
 //將tag到的ID顯示出來
 @Override
 protected void onNewIntent(Intent intent) {
  if (intent.getAction().equals(NfcAdapter.ACTION_TAG_DISCOVERED)) {
   ((TextView) findViewById(R.id.tag)).setText("Tag ID(16-14):"
     + ByteArrayToHexString(intent
       .getByteArrayExtra(NfcAdapter.EXTRA_ID))
     + "\n Tag ID (16-8):"
     + getHex(intent.getByteArrayExtra(NfcAdapter.EXTRA_ID))
     + "\n Tag ID (dec):"
     + getDec(intent.getByteArrayExtra(NfcAdapter.EXTRA_ID))
     + "\n ID (reversed):"
     + getReversed(intent.getByteArrayExtra(NfcAdapter.EXTRA_ID)));
  }
 }
 //16進位14碼
 private 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;
 }
 //16進位8碼
 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();
 }
 //12進位10碼
 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;
 }
 //12進位10碼反轉
 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;
 }
} 
參考連結
https://gist.github.com/luixal/5768921
https://github.com/nadam/nfc-reader