1.首先要在AndroidManifest.xml中声明如下配置信息:

为了能够使用Android手机的NFC功能,需要在Manifest文件中添加相应的权限:

详细配置请参考-->Android NFC标签读写配置过滤器总结

2.NFC TAG的发布系统:

当android设备扫描到一个NFC标签时,会自动寻找最适合的Activity来处理这个TAG,如果有多个Activity满足条件的话,会让用户来选择到底使用哪一个Activity来处理,可以理解为就是简单的事件响应与事件处理。

那么如何让一个Activity监听 ”当扫描到NFC标签时” 的这一个事件呢?使用intent filter。

可以理解为当检测到一个NFC标签时,系统自动创建一个相关Intent对象,含有响应intent-filter的Activity将处理这个Intent。

其中,intent filter声明如下:(在AndroidManifest.xml中声明在你需要捕获这个Intent的Activity里)(如下是识别公交卡的TECH格式过滤标签)即ACTION_TECH_DISCOVERED类型的过滤器:

                                                

配置android:name=".NFCActivity"是为了当退出app时只要扫描卡片能直接打开app并定位到NFC扫描界面。

在res文件夹下新建一个xml的文件夹,里面放的是Android支持的NFC类型的配置数据。nfc_tech_filter.xml如下:

            android.nfc.tech.IsoDep            android.nfc.tech.NfcA            android.nfc.tech.NfcB            android.nfc.tech.NfcF            android.nfc.tech.NfcV            android.nfc.tech.Ndef            android.nfc.tech.NdefFormatable            android.nfc.tech.MifareUltralight            android.nfc.tech.MifareClassic    

另外还有ACTION_NDEF_DISCOVERED类型的过滤器

                                                

ACTION_TAG_DISCOVERED类型的过滤器

              

3.详细代码如下:

res/layout/nfc_info.xml

<?xml version="1.0" encoding="utf-8"?>                                                     

NFCActivity.java

import android.app.Activity;import android.app.PendingIntent;import android.content.Intent;import android.nfc.NfcAdapter;import android.nfc.Tag;import android.nfc.tech.MifareClassic;import android.os.Bundle;import android.view.View;import android.widget.TextView;import android.widget.Toast;public class NFCActivity extends Activity {NfcAdapter nfcAdapter;TextView promt;private PendingIntent pi;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.nfc_info);promt = (TextView) findViewById(R.id.promt);// 获取默认的NFC控制器nfcAdapter = NfcAdapter.getDefaultAdapter(this);pi = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);if (nfcAdapter == null) {Toast.makeText(this, "对不起,您的设备不支持nfc功能!", Toast.LENGTH_SHORT).show();//promt.setText("设备不支持NFC!");finish();return;}if (!nfcAdapter.isEnabled()) {Toast.makeText(this, "请在系统设置中开启NFC功能!", Toast.LENGTH_SHORT).show();//promt.setText("请在系统设置中先启用NFC功能!");finish();return;}}public void btn_back(View view){this.finish();}@Override  protected void onNewIntent(Intent intent) {    super.onNewIntent(intent);    // 当前app正在前端界面运行,这个时候有intent发送过来,那么系统就会调用onNewIntent回调方法,将intent传送过来    // 我们只需要在这里检验这个intent是否是NFC相关的intent,如果是,就调用处理方法    if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())) {      processIntent(intent);    }  }  //页面获取焦点  @Override  protected void onResume() {    super.onResume();    nfcAdapter.enableForegroundDispatch(this, pi, null, null);  }//页面失去焦点  @Override      protected void onPause() {          super.onPause();          if(nfcAdapter!=null){          nfcAdapter.disableForegroundDispatch(this);//关闭前台发布系统          }   }/*@Overrideprotected void onResume() {super.onResume();//得到是否检测到ACTION_TECH_DISCOVERED触发if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(getIntent().getAction())) {//处理该intentprocessIntent(getIntent());}}*///字符序列转换为16进制字符串private String bytesToHexString(byte[] src) {StringBuilder stringBuilder = new StringBuilder("0x");if (src == null || src.length <= 0) {return null;}char[] buffer = new char[2];for (int i = 0; i < src.length; i++) {buffer[0] = Character.forDigit((src[i] >>> 4) & 0x0F, 16);buffer[1] = Character.forDigit(src[i] & 0x0F, 16);System.out.println(buffer);stringBuilder.append(buffer);}return stringBuilder.toString();}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;  }/** * Parses the NDEF Message from the intent and prints to the TextView */private void processIntent(Intent intent) {//取出封装在intent中的TAGTag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);String CardId =ByteArrayToHexString(tagFromIntent.getId());String metaInfo = "";metaInfo+="卡片ID:"+CardId;for (String tech : tagFromIntent.getTechList()) {System.out.println(tech);}boolean auth = false;//读取TAGMifareClassic mfc = MifareClassic.get(tagFromIntent);try {//Enable I/O operations to the tag from this TagTechnology object.mfc.connect();int type = mfc.getType();//获取TAG的类型int sectorCount = mfc.getSectorCount();//获取TAG中包含的扇区数String typeS = "";switch (type) {case MifareClassic.TYPE_CLASSIC:typeS = "TYPE_CLASSIC";break;case MifareClassic.TYPE_PLUS:typeS = "TYPE_PLUS";break;case MifareClassic.TYPE_PRO:typeS = "TYPE_PRO";break;case MifareClassic.TYPE_UNKNOWN:typeS = "TYPE_UNKNOWN";break;}metaInfo += "\n卡片类型:" + typeS + "\n共" + sectorCount + "个扇区\n共"+ mfc.getBlockCount() + "个块\n存储空间: " + mfc.getSize() + "B\n";for (int j = 0; j < sectorCount; j++) {//Authenticate a sector with key A.auth = mfc.authenticateSectorWithKeyA(j,MifareClassic.KEY_DEFAULT);int bCount;int bIndex;if (auth) {metaInfo += "Sector " + j + ":验证成功\n";// 读取扇区中的块bCount = mfc.getBlockCountInSector(j);bIndex = mfc.sectorToBlock(j);for (int i = 0; i < bCount; i++) {byte[] data = mfc.readBlock(bIndex);metaInfo += "Block " + bIndex + " : "+ bytesToHexString(data) + "\n";bIndex++;}} else {metaInfo += "Sector " + j + ":验证失败\n";}}promt.setText(metaInfo);//Toast.makeText(this, metaInfo, Toast.LENGTH_SHORT).show();} catch (Exception e) {e.printStackTrace();}}}

4.运行效果图如下:

 

 

本人NFC扫描卡片功能就是参考模仿下面源码完成的。

详细请参考下载源码Eclipse版本-->Android NFC读MifareClassic卡获取卡片ID类型

如果想研究Android NFC源码读取公交卡信息余额和交易记录的

请参考另一篇文章-->Android NFC源码读取公交卡信息余额和交易记录

 

 

更多相关文章

  1. Android中Java根据文件头获取文件类型的方法
  2. Android配置build.gradle的buildTypes动态自动维护debug和releas
  3. android videoView 按不同比例缩放
  4. Android系统使用MediaFile类判断音频文件类型
  5. RxJava用法简单整理(Android)
  6. Android使用me.dm7.barcodescanner:zxing扫描二维码乱码问题处理
  7. ANDROID JNI的使用简介
  8. BLE 扫描及连接 android程序开发(一)
  9. Android(安卓)NDK数据类型转换详解

随机推荐

  1. Android系统移植技术详解
  2. Android(安卓)AES Encryption and Decryp
  3. The type Contacts is deprecated
  4. Android(安卓)exception
  5. android开启Wifi AP
  6. Android(安卓)listview--checkbox
  7. Activity相关工具类
  8. Android(安卓)中的 AndroidManifest.xml
  9. debian linux android ndk compile env s
  10. Android中使用shape定义空心圆和实心圆