赞
踩
目录
NFC的全称是“Near Field Communication”,意思是近场通信、与邻近的区域通信。该功能由NfcAdapter(NFC适配器)控制。
- <!-- NFC权限,无需动态申请 -->
- <uses-permission android:name="android.permission.NFC" />
在清单文件(AndroidManifests)中为Activity设置意图过滤器(IntentFilter);在程序检测到NFC操作时将跳转至该界面。
本部分操作用于从外部直接打开指定Activity。
- <!--AndroidManifests-->
- <activity
- android:name=".NFCActivity"
- android:exported="true" >
-
- <intent-filter>
- <action android:name="android.nfc.action.NDEF_DISCOVERED"/>
- <category android:name="android.intent.category.DEFAULT"/>
- </intent-filter>
-
- <intent-filter>
- <action android:name="android.nfc.action.TAG_DISCOVERED"/>
- <category android:name="android.intent.category.DEFAULT"/>
- </intent-filter>
-
- <intent-filter>
- <action android:name="android.nfc.action.TECH_DISCOVERED"/>
- <category android:name="android.intent.category.DEFAULT"/>
- </intent-filter>
-
- <!--定义了android.nfc.action.TECH_DISCOVERED的具体NFC技术-->
- <!--资源文件位于xml/nfc_tech_filter.xml中-->
- <meta-data android:name="android.nfc.action.TECH_DISCOVERED"
- android:resource="@xml/nfc_tech_filter"/>
-
- </activity>
- <!--xml/nfc_tech_filter.xml文件内容如下-->
- <!--该文件为Android所有能支持的NFC类型-->
- <resource>
- <tech-list>
- <tech>android.nfc.tech.NfcA</tech>
- <tech>android.nfc.tech.NfcB</tech>
- <tech>android.nfc.tech.NfcF</tech>
- <tech>android.nfc.tech.NfcV</tech>
- <tech>android.nfc.tech.IsoDep</tech>
- <tech>android.nfc.tech.Ndef</tech>
- <tech>android.nfc.tech.NdefFormatable</tech>
- <tech>android.nfc.tech.MifareClassic</tech>
- <tech>android.nfc.tech.MifareUltralight</tech>
- </tech-list>
- </resource>
可使用NfcAdapter(NFC适配器)进行判断,未开启时跳转至NFC设置界面;NfcAdapter常用方法如下:
- //获取NFC适配器
- NfcAdapter nfcAdapter=NfcAdapter.getDefaultAdapter(MainActivity.this);
- //判断设备是否有NFC功能
- if(nfcAdapter==null){
- textView.setText("设备无NFC功能");
- }
- //判断设备是否开启NFC功能
- else if (!nfcAdapter.isEnabled()) {
- textView.setText("设备未开启NFC功能");
- //跳转至设置NFC界面
- Intent intent=new Intent(Settings.ACTION_NFC_SETTINGS);
- startActivity(intent);
- }
- else {
- textView.setText("设备已开启NFC功能");
- }
建议在页面暂停时禁用NFC感应,在页面运行时启用NFC感应。
用于触发的待定意图(PendingIntent)为读取NFC信息通常为跳转至当前界面(即会触发onNewIntent方法);请注意需将Activity设置为仅有一个,可在清单文件将launchMode设置为singleTop,或为Intent使用.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)。
- //准备NFC感应启动参数
- //用于触发的待定意图
- Intent intent=new Intent(MainActivity.this,MainActivity.class);
- //intent=intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
- PendingIntent pendingIntent=PendingIntent.getActivity(MainActivity.this,12345,intent,PendingIntent.FLAG_UPDATE_CURRENT|PendingIntent.FLAG_IMMUTABLE);
- //过滤器数组(会触发待定意图的NFC事件类型)
- IntentFilter[] intentFilter=new IntentFilter[]{new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED)};
- //指定NFC技术类型的二维数组
- String[][] techList=new String[][]{new String[]{NfcA.class.getName()},{IsoDep.class.getName()}};
-
-
- protected void onResume() {
- super.onResume();
- if(nfcAdapter!=null&&nfcAdapter.isEnabled()){
- //启用NFC感应
- nfcAdapter.enableForegroundDispatch(MainActivity.this,pendingIntent,intentFilter,techList);
- }
- }
-
- protected void onPause() {
- super.onPause();
- if(nfcAdapter!=null&&nfcAdapter.isEnabled()){
- //禁用NFC感应
- nfcAdapter.disableForegroundDispatch(MainActivity.this);
- }
- }
用于触发的待定意图(PendingIntent)为读取NFC信息通常为跳转至当前界面(即会触发onNewIntent方法);请注意需将Activity设置为仅有一个。
可以通过重写onNewIntent方法,获取NFC数据并解码:
MifareClassic类常用方法:
- protected void onNewIntent(Intent intent) {
- super.onNewIntent(intent);
- //读取NFC信息
- Tag tag=intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
- if(tag!=null){
- //获取序列号
- byte[] id_bytes=tag.getId();
- String id="";
- for(int i=0;i<id_bytes.length;i++){
- id=id+id_bytes[i];
- }
- //创建MifareClassic对象
- MifareClassic classic=MifareClassic.get(tag);
- try {
- //连接卡片
- classic.connect();
- //获取类型
- int typeI=classic.getType();
- String type=null;
- if(typeI==MifareClassic.TYPE_CLASSIC){
- type="传统类型";
- }
- else if(typeI==MifareClassic.TYPE_PLUS) {
- type="增强类型";
- }
- else if (typeI==MifareClassic.TYPE_PRO) {
- type="专业类型";
- }
- else {
- type="未知类型";
- }
- //获取其他数据
- int i1=classic.getSectorCount();//扇形区域
- int i2=classic.getBlockCount();//分块个数
- int i3=classic.getSize();//内存大小
- } catch (IOException e) {
- throw new RuntimeException(e);
- }finally {
- try {
- //无论是否发生异常都要释放卡片数据(关闭连接)
- classic.close();
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
- }
- }
以下为MainActivity(界面只有一个TextView)的全部代码,请在清单文件声明(静态申请)NFC权限后使用。
- public class MainActivity extends AppCompatActivity {
- private NfcAdapter nfcAdapter=null;
- private PendingIntent pendingIntent=null;
- private IntentFilter[] intentFilter=null;
- private String[][] techList=null;
- private TextView textView=null;
- @SuppressLint("MissingInflatedId")
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- //获取控件
- textView=findViewById(R.id.textView);
- //获取NFC适配器
- nfcAdapter=NfcAdapter.getDefaultAdapter(MainActivity.this);
- //判断设备是否有NFC功能
- if(nfcAdapter==null){
- textView.setText("设备无NFC功能");
- }
- //判断设备是否开启NFC功能
- else if (!nfcAdapter.isEnabled()) {
- textView.setText("设备未开启NFC功能");
- //跳转至NFC设置界面
- Intent intent=new Intent(Settings.ACTION_NFC_SETTINGS);
- startActivity(intent);
- }
- else {
- textView.setText("设备已开启NFC功能");
- }
-
- //准备NFC感应启动参数
- //用于触发的待定意图
- Intent intent=new Intent(MainActivity.this,MainActivity.class);
- //intent=intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
- pendingIntent=PendingIntent.getActivity(MainActivity.this,12345,intent,PendingIntent.FLAG_UPDATE_CURRENT|PendingIntent.FLAG_IMMUTABLE);
- //过滤器(会触发待定意图的NFC事件类型)
- intentFilter=new IntentFilter[]{new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED)};
- //指定NFC技术类型
- techList=new String[][]{new String[]{NfcA.class.getName()},{IsoDep.class.getName()}};
-
-
- }
-
- protected void onResume() {
- super.onResume();
- if(nfcAdapter!=null&&nfcAdapter.isEnabled()){
- //启用NFC感应
- nfcAdapter.enableForegroundDispatch(MainActivity.this,pendingIntent,intentFilter,techList);
- }
- }
-
- protected void onPause() {
- super.onPause();
- if(nfcAdapter!=null&&nfcAdapter.isEnabled()){
- //禁用NFC感应
- nfcAdapter.disableForegroundDispatch(MainActivity.this);
- }
- }
-
- //该界面触发NFC自动调用该方法
- protected void onNewIntent(Intent intent) {
- super.onNewIntent(intent);
- String outString="NFC卡无数据";
- //读取NFC信息
- Tag tag=intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
- if(tag!=null){
- //获取序列号
- byte[] id_bytes=tag.getId();
- String id="";
- for(int i=0;i<id_bytes.length;i++){
- id=id+id_bytes[i];
- }
- outString="序列号为:"+id+"\n";
- //创建MifareClassic对象
- MifareClassic classic=MifareClassic.get(tag);
- try {
- //连接卡片
- classic.connect();
- //获取类型
- int typeI=classic.getType();
- String type=null;
- if(typeI==MifareClassic.TYPE_CLASSIC){
- type="传统类型";
- }
- else if(typeI==MifareClassic.TYPE_PLUS) {
- type="增强类型";
- }
- else if (typeI==MifareClassic.TYPE_PRO) {
- type="专业类型";
- }
- else {
- type="未知类型";
- }
- //获取其他数据
- int i1=classic.getSectorCount();//扇形区域
- int i2=classic.getBlockCount();//分块个数
- int i3=classic.getSize();//内存大小
- outString=outString+type+"\n"+"扇形区域:"+i1+"\n分块个数:"+i2+"\n内存大小:"+i3;
- } catch (IOException e) {
- throw new RuntimeException(e);
- }finally {
- try {
- //无论是否发生异常都要关闭连接
- classic.close();
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
- }
- textView.setText(outString);
- if(outString.equals("NFC卡无数据")){
- Handler handler=new Handler(new Handler.Callback() {
- public boolean handleMessage(@NonNull Message message) {
- textView.setText("设备已开启NFC功能");
- return true;
- }
- });
- new Thread(new Runnable() {
- public void run() {
- try {
- Thread.sleep(3000);
- } catch (InterruptedException e) {
- throw new RuntimeException(e);
- }
- handler.sendEmptyMessage(123);
- }
- }).start();
- }
- }
- }
tag:NFC,nfc,芯片,磁卡,近距通信
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。