NFC,什么是NFC?想必大家都听过,就是近场通信,接下来我想给大家展示一个简单的demo, 这个demo是我在公司工作中开发的功能.希望这篇文章对大家有所帮助
目前在市场在见得比较多的电子标签有 1443 和15693 两种类型的卡片(当然还有其它类型的),这两种卡片是什么东东呢?自己百度一下,网上一大把资料有介绍的.
在我实际开发过程中就是主要接触这两种类型的卡片.我需要实现的功能是,利用带有NFC功能的手机,去读取电子标签中的数据(卡片id值这里叫UID),网上可以下载很多可以读取电子标签的app软件,但是,在我的demo里面, 是要屏蔽第三方的NFC扫描软件, 我只想用自己开发的软件去读取这些电子标签(即不使用前台调度,弹出个对话框,让我们选择使用哪个NFC软件去读取)
不多说, 直接上源码比较实在
package com.iotdc.android.app.nfc.activity; import java.io.Serializable; import android.annotation.SuppressLint; import android.app.Activity; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.IntentFilter.MalformedMimeTypeException; import android.graphics.Paint; import android.nfc.NfcAdapter; import android.nfc.NfcManager; import android.nfc.tech.IsoDep; import android.nfc.tech.MifareClassic; import android.nfc.tech.MifareUltralight; import android.nfc.tech.Ndef; import android.nfc.tech.NdefFormatable; import android.nfc.tech.NfcA; import android.nfc.tech.NfcB; import android.nfc.tech.NfcF; import android.nfc.tech.NfcV; import android.os.Bundle; import android.view.KeyEvent; import android.view.View; import android.view.View.OnClickListener; import android.widget.ImageView; import android.widget.TextView; import com.iotdc.android.app.scanner.R; import com.iotdc.android.app.scanresult.activity.TwoDimensionCodeActivity; import com.iotdc.android.app.utils.NFCUtil; import com.iotdc.android.app.utils.NFCUtil.NFCData; @SuppressLint("NewApi") public class NFCActivity extends Activity { // private Intent intent; private TextView tvNfc; private TextView tvOpenNfC; private NfcManager manager; private NfcAdapter adapter; private PendingIntent mNfcPendingIntent; private IntentFilter[] mWriteTagFilters; private String[][] techListsArray; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_nfc); initTitile(); init(); initNFC(); } private void init() { tvNfc = (TextView) findViewById(R.id.tv_nfc); tvOpenNfC = (TextView) findViewById(R.id.tv_open_nfc); tvOpenNfC.getPaint().setFlags(Paint.UNDERLINE_TEXT_FLAG); tvOpenNfC.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(NFCActivity.this, NFCGuidActivity.class); startActivity(intent); overridePendingTransition(R.anim.c_left_1_righttoleft, R.anim.c_left_2_lefttoright); } }); } @SuppressLint("NewApi") public void initNFC() { manager = (NfcManager) this.getSystemService(Context.NFC_SERVICE); adapter = manager.getDefaultAdapter(); if (adapter != null) { if (adapter.isEnabled()) { tvNfc.setVisibility(View.GONE); } else { tvNfc.setVisibility(View.VISIBLE); } } else { tvNfc.setVisibility(View.VISIBLE); } } @Override protected void onResume() { super.onResume(); System.out.println("onResume"); if (adapter != null) { mNfcPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()) .addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0); IntentFilter ndefDetected = new IntentFilter( NfcAdapter.ACTION_NDEF_DISCOVERED); IntentFilter ndefDetected2 = new IntentFilter( NfcAdapter.ACTION_TECH_DISCOVERED); IntentFilter ndefDetected3 = new IntentFilter( NfcAdapter.ACTION_TAG_DISCOVERED); try { ndefDetected.addDataType("*/*"); // } catch (MalformedMimeTypeException e) { throw new RuntimeException("fail", e); } techListsArray = new String[][] { new String[] { NfcA.class.getName(), NfcV.class.getName(), Ndef.class.getName(), NdefFormatable.class.getName(), MifareClassic.class.getName(), MifareUltralight.class.getName(), IsoDep.class.getName(), NfcB.class.getName(), NfcF.class.getName() } }; mWriteTagFilters = new IntentFilter[] { ndefDetected, ndefDetected2, ndefDetected3 }; adapter.enableForegroundDispatch(this, mNfcPendingIntent, mWriteTagFilters, techListsArray); Intent intent = this.getIntent(); resolveIntent(intent); // 这两行代码一定要写 } } @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); System.out.println("onNewIntent"); resolveIntent(intent); } private void resolveIntent(Intent intent) { if (adapter != null) { NFCData nd = NFCUtil.getNFCIntentData(intent); if (nd != null) { String uid = nd.getUid(); if (uid != null && !"".equals(uid)) { intent = new Intent(NFCActivity.this, ResultActivity.class); intent.putExtra("nfcData", (Serializable) nd); startActivity(intent); overridePendingTransition(R.anim.c_left_1_righttoleft, R.anim.c_left_2_lefttoright); } } } } @Override protected void onPause() { super.onPause(); if (adapter != null) { adapter.disableForegroundDispatch(this); } } public void initTitile() { TextView tv_title = (TextView) findViewById(R.id.tv_title); tv_title.setText(R.string.scan_nfc_title); ImageView iv_left = (ImageView) findViewById(R.id.iv_left); iv_left.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { finish(); overridePendingTransition(R.anim.c_right_1_lefttoright, R.anim.c_right_2_righttoleft); } }); ImageView iv_right = (ImageView) findViewById(R.id.iv_right); iv_right.setVisibility(View.INVISIBLE); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { this.finish(); overridePendingTransition(R.anim.c_right_1_lefttoright, R.anim.c_right_2_righttoleft); } return super.onKeyDown(keyCode, event); } }
下面是activity_nfc的布局文件
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <include layout="@layout/title" /> <LinearLayout android:id="@+id/no_info_frag" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <ImageView android:id="@+id/noRecord" android:layout_width="100dp" android:layout_height="100dp" android:layout_gravity="center" android:layout_marginTop="127dp" android:src="@drawable/nfc_bitmap" /> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:layout_marginLeft="20dp" android:layout_marginRight="20dp" android:text="@string/NFCText" android:textColor="@color/golden" android:layout_gravity="center" android:gravity="center" android:textSize="15sp" /> <TextView android:id="@+id/tv_nfc" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:layout_marginLeft="50dp" android:layout_marginRight="50dp" android:text="@string/noNFCText" android:textColor="@color/red" android:layout_gravity="center" android:gravity="center" android:textSize="15sp" /> <TextView android:id="@+id/tv_open_nfc" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="30dp" android:text="@string/openNFCText" android:textColor="#004190" android:layout_gravity="center" android:textSize="18sp" /> </LinearLayout> </LinearLayout>
使用一个ResultActivity来显示NFC读取到电子标签的结果,用一个TextView 显示就是了, 大家都懂的
package com.iotdc.android.app.nfc.activity; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.ImageView; import android.widget.TextView; import com.iotdc.android.app.config.SystemConfig; import com.iotdc.android.app.scanner.R; public class NFCResultActivity extends Activity{ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_nfc_result); initTitleBar(); TextView tvRead = (TextView) findViewById(R.id.tv_nfc_read); Intent data = this.getIntent(); String uid = data.getStringExtra("nfcResult"); String msg = data.getStringExtra("msg"); SystemConfig.error(msg, this); tvRead.setText(uid); } private void initTitleBar(){ TextView tv_title = (TextView) findViewById(R.id.tv_title); tv_title.setText(R.string.scan_nfc_title_result); ImageView iv_left = (ImageView) findViewById(R.id.iv_left); iv_left.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { finish(); overridePendingTransition(R.anim.c_right_1_lefttoright, R.anim.c_right_2_righttoleft); } }); ImageView iv_right = (ImageView) findViewById(R.id.iv_right); iv_right.setVisibility(View.INVISIBLE); } }
其中NFC读取数据的方法我写在了一个工具类中,叫NFCUtil
package com.iotdc.android.app.utils; import java.io.Serializable; import android.annotation.SuppressLint; import android.content.Intent; import android.nfc.NfcAdapter; import android.nfc.Tag; import com.iotdc.android.app.nfc.TagBlockStream; public class NFCUtil { @SuppressLint("NewApi") public static NFCData getNFCIntentData(Intent intent) { NFCData nd = new NFCData(); String uid = ""; String data = ""; String action = intent.getAction(); // 判断nfc的类型,一共有三种 if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(action) || NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)) { Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); TagBlockStream bs = TagBlockStream.getInstance(tagFromIntent); byte[] blockContent = null; // HonestTag hTag = null; uid = HexUtility.byteArrayToString(tagFromIntent.getId()); if (bs != null) { try { bs.connect(); blockContent = bs.readBlock(0); } catch (Exception e) { e.printStackTrace(); } finally { try { bs.close(); } catch (Exception e) { e.printStackTrace(); } } } } nd.setUid(uid); // 03190B0000014BE0 return nd; } public static class NFCData implements Serializable { /** * 标签UID 值 */ private String uid; public String getUid() { return uid; } public void setUid(String uid) { this.uid = uid; } } }
到上面的话,逻辑代码就已经完成了, 注意, 没有完, NFC 一定要手机支持,并且要在Manifest.xml文件中进行权限配置
<uses-permission android:name="android.permission.NFC" />
还要在对activity 进行过滤
<activity android:name="com.iotdc.android.app.nfc.activity.NFCActivity" android:screenOrientation="portrait" > <!-- 这 一句一定是要的--> <intent-filter> <action android:name="android.nfc.action.NDEF_DISCOVERED" /> </intent-filter> </activity>
到这里, 所有的工作就都完成了, 对NFC 我也不是太了解,只是在工作中用到了, 目前在公司的话, 还没有接触过手机与手机之间的通信, 希望大神能够指导,共同进步