Android NFC读取电子标签

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 我也不是太了解,只是在工作中用到了, 目前在公司的话, 还没有接触过手机与手机之间的通信, 希望大神能够指导,共同进步

你可能感兴趣的:(Android NFC读取电子标签)