[置顶] Android应用接收NFC读卡
2018-01-19 16:14
501 查看
最近在看NFC功能,重点就是我在页面上设置了一个按钮,要点击此按钮才会开启NFC读卡功能(并非跳转下个Activity),为了方便使用,为此可以专门设置一个基类Activity作为NFC功能的管理,此处我命名为TestNfcBaseActivity
封装好基类后,首先先分析一下,上面弄了两种方法,一种是重写isOpenNfc()方法,一种是手动开启方法,下面将写出这两种启动方法的区别,我们设计一个布局来显现,一段提示文字和一张图片
然后是使用的Activity:
一、自动开启NFC,不需要点击才开启的
public final static int REQ_READ_CARD = 0x01;
public abstract class TestNfcBaseActivity extends BaseActivity { // private NfcManager mNfc; private boolean mIsWidthLifeCycle = true; public static final int REQ_NFC_OPEN = 0X9000; private boolean isOpenNfcByManual = false; private Activity activity; private NfcAdapter nfcAdapter; private PendingIntent pendingIntent; private static String[][] TECHLISTS; //设置你要处理的tag technologies到String数组中 private static IntentFilter[] TAGFILTERS; private int status; /** 设备不支持NFC */ public static final int NFC_NOT_SUPPORT = -1; /** NFC已关闭 */ public static final int NFC_DISABLED = 0; /** NFC开启了 */ public static final int NFC_ABLED = 1; /** nfc tag */ private Tag mTag; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); initDatas(); } /** * 是否需要开启NFC相关对象,由于nfc 圈存和ble 圈存公用一套UI,ble圈存是不需要初始化NFC,所以需要让子类决定。 * @return true 需要初始化nfc */ public abstract boolean isOpenNfc(); private void initDatas() { setTECHLISTSandTAGFILTERS(); activity = getActivity(); pendingIntent = PendingIntent.getActivity(activity, 0, new Intent(activity, activity.getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0); // pendingIntent = PendingIntent.getActivity(activity, 0, // new Intent(activity, getClass()), 0); if(isOpenNfc()){ initNfcManagerByManual(false); } if(isOpenNfcByManual){ initNfcManagerByManual(true); } } public BaseNfcNewActivity getActivity(){ return this; } public void initNfcManagerByManual(boolean isOpenNfcByManual){ this.isOpenNfcByManual = isOpenNfcByManual; if(nfcAdapter != null){ ReaderManager.destory(); nfcAdapter = null; } nfcAdapter = NfcAdapter.getDefaultAdapter(activity); status = getNfcStatus(); LogUtils.LogError("lenita","nfc status = "+status); if(isOpenNfcByManual){ onResume(); //在生成Adapte后执行,否则无法进入 } } public Tag getNfcTag() { return mTag; } public void setNfcTag(Tag mTag) { this.mTag = mTag; } private void setTECHLISTSandTAGFILTERS(){ try { TECHLISTS = new String[][] { { IsoDep.class.getName() } }; TAGFILTERS = new IntentFilter[] { new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED, "*/*") }; } catch (Exception e) { } } public boolean updateNfcStatus() { int sta = getNfcStatus(); if (sta != status) { status = sta; return true; } return false; } /** 获取设备NFC状态 */ public int getNfcStatus() { return (nfcAdapter == null) ? NFC_NOT_SUPPORT : nfcAdapter.isEnabled() ? NFC_ABLED : NFC_DISABLED; } /** * 读卡信息并初始化android.nfc.Tag * * @param intent * @param requesetCode * 请求码,回调使用 * @param listener * 回调监听 * @return 是否执行成功 */ public boolean readCard(Intent intent, int requesetCode, ReaderListener listener) { final Tag tag = (Tag) intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); this.mTag = tag; if (tag != null) { ReaderManager.readCardExecute(requesetCode, tag, listener); return true; } return false; } /** * 已经初始化tag,可直接调用读取方法 * * @param requesetCode * @param listener * @return */ public boolean readCard(int requesetCode, ReaderListener listener) { if (mTag != null) { ReaderManager.readCardExecute(requesetCode, mTag, listener); return true; } return false; } /** * 发送tlv格式指令,执行出错根据tlv解析 * * @param requesetCode * @param instructions * tlv指令集 * @param listener * @return 是否执行成功 */ public boolean sendTlvCmd(int requesetCode, String instructions, ReaderListener listener) { if (mTag != null) { ReaderManager.sendTlvCmdExecute(requesetCode, mTag, instructions, listener); return true; } return false; } public boolean sendCmd(int requesetCode, String cmd, ReaderListener listener) { return sendCmds(requesetCode, new String[] { cmd }, listener); } /** * 发送数组指令集,执行当条出错时,仍然继续执行 * * @param requesetCode * @param cmds * 数组指令集 * @param listener * @return 是否执行成功 */ public boolean sendCmds(int requesetCode, String[] cmds, ReaderListener listener) { if (mTag != null) { ReaderManager.sendArrayCmdExecute(requesetCode, mTag, cmds, listener); return true; } return false; } public void destory() { ReaderManager.destory(); } /* public final NfcManager getNfc() { return mNfc; }*/ @Override protected void onResume() { super.onResume(); LogUtils.LogError("lenita","onResume() - isOpenNfcByManual = " +isOpenNfcByManual); if(isOpenNfc() || isOpenNfcByManual){ if (mIsWidthLifeCycle) { //设置处理优于所有其他NFC的处理 if (nfcAdapter != null){ nfcAdapter.enableForegroundDispatch(activity, pendingIntent, TAGFILTERS, TECHLISTS); } } } } @Override protected void onPause() { super.onPause(); LogUtils.LogError("lenita","onPause()"); if(isOpenNfc() || isOpenNfcByManual){ if (mIsWidthLifeCycle) { if (nfcAdapter != null){ nfcAdapter.disableForegroundDispatch(activity); } } } } /** * Nfc 是否根据生命开启关闭 * * @param enable */ public void setNfcWidthLifeCycle(boolean enable) { mIsWidthLifeCycle = enable; } /** * 如果nfc 不支持,或未开启。打开对话提示 * @return 如果已经开启,返回true 不做任何对话框提示 */ public final boolean showNfcProblemDialog() { /*if(mNfc == null){ showLongToastCenter("NFC管理器为空,无法初始化NFC功能"); }*/ int nfcStatus = getNfcStatus(); if (!isFinishing()) { if (nfcStatus == NfcManager.NFC_NOT_SUPPORT) { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setCancelable(false); builder.setTitle("提示").setMessage(com.uroad.nfc.R.string.info_nfc_not_support).setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { onNfcNotSupportClick(); } }); builder.create().show(); } else if (nfcStatus == NfcManager.NFC_DISABLED) { DialogHelper.showComfirmDialog(this, getString(android.R.string.cancel), "去开启", getString(com.uroad.nfc.R.string.info_nfc_tips_open), new ComfirmDialog.DialogOnclick() { @Override public void PerDialogclick(ComfirmDialog dialog) {//取消 onNfcDisabledCancelClick(dialog); } }, new ComfirmDialog.DialogOnclick() { @Override public void PerDialogclick(ComfirmDialog dialog) {//确定 onNfcDisabledGoOpenClick(dialog); } }); } } if(nfcStatus == NfcManager.NFC_ABLED){ return true; } return false; } /** * 设备不支持NFC功能 */ public void onNfcNotSupportClick() { }; /** * NFC 未开启,前往开启 */ public void onNfcDisabledGoOpenClick(ComfirmDialog dialog) { startNfcSettingsActivity(); dialog.dismiss(); } /** * NFC 未开启,前往开启 */ public void onNfcDisabledCancelClick(ComfirmDialog dialog) { dialog.dismiss(); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { LogUtils.i("onActivityResult requestCode:"+requestCode); LogUtils.i("onActivityResult resultCode:"+resultCode); } private void startNfcSettingsActivity() { try { startActivityForResult(new Intent("android.settings.NFC_SETTINGS"), REQ_NFC_OPEN); } catch (Exception e) { startActivityForResult(new Intent(ACTION_SETTINGS), REQ_NFC_OPEN); } } @Override protected void onDestroy() { super.onDestroy(); if(isOpenNfc() || isOpenNfcByManual){ destory(); } } }
封装好基类后,首先先分析一下,上面弄了两种方法,一种是重写isOpenNfc()方法,一种是手动开启方法,下面将写出这两种启动方法的区别,我们设计一个布局来显现,一段提示文字和一张图片
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:orientation="vertical" android:layout_marginTop="40dp"> <TextView android:layout_width="match_parent" android:layout_height="40dp" android:text = "点击图片开启NFC读卡功能" android:textColor="@color/red" android:gravity="center" android:textSize="20dp"/> <ImageView android:id="@+id/iv_nfc_click" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="10dp" android:src="@drawable/bg_quancun_connect_nfc" /> </LinearLayout> </LinearLayout>
然后是使用的Activity:
一、自动开启NFC,不需要点击才开启的
/** *@date 创建时间:2018/01/15 *@author lan.zheng */ public class PhotographActivity extends TestNfcBaseActivity{ ImageView imageView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //初始化 setBaseContentLayout(R.layout.test_nfc_activity); // initView(); } /** * 是否是自动进入该页面初始化Nfc功能,false:不启动,true:初始化 * @return */ @Override public boolean isOpenNfc() { return true; } } 二、手动开启的,假设点击图片可以开启Nfc功能 /** *@date 创建时间:2018/01/15 *@author lan.zheng */ public class PhotographActivity extends TestNfcBaseActivity{ ImageView imageView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //初始化 setBaseContentLayout(R.layout.test_nfc_activity); initView(); } private void initView() { imageView = (ImageView) findViewById(R.id.iv_nfc_click); imageView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { //TODO 手动开启Nfc initNfcManagerByManual(true); } }); } /** * 是否是自动进入该页面初始化Nfc功能,false:不启动,true:初始化 * @return */ @Override public boolean isOpenNfc() { return false; } }开启了Nfc功能,接下来就是要进行贴卡后数据的监听回调和处理,此处需要实现implements ReaderListener接口,然后重写onReadEvent方法,首先我们先写用于监听读卡的,在Activity中:
public final static int REQ_READ_CARD = 0x01;
@Override protected void onNewIntent(final Intent intent) { super.onNewIntent(intent); LogUtils.i("onNewIntent Thread ID:" + Thread.currentThread().getId()); runOnUiThread(new Runnable() { @Override public void run() { readCard(intent, REQ_READ_CARD, PhotographActivity.this); } }); }
当贴卡后,onReadEvent就会拦截到读到的卡片:@Override public void onReadEvent(int requestCode, SPEC.EVENT event, Object... obj) { if (requestCode == REQ_READ_CARD) { if (event == SPEC.EVENT.SUCCESS) { PCard pCard = (PCard) obj[0]; LogUtils.e(pCard.toString()); if (XXX) { //是否为满足条件的卡 final String cardno = pCard.getSn()+pCard.getCardNumber(); showLongToastCenter("卡号为:"+cardno); } } else if (event == SPEC.EVENT.ERROR) { Integer resultCode = (Integer) obj[0]; LogUtils.e("onReadEvent - error - code :" + resultCode); showLongToastCenter(getString(R.string.info_nfc_read_card_error)); } }
来手动启动NFC读卡的图片,首先需要你赋予应用NFC权限:
开启后拿卡片进行读卡,此处模拟读到卡号:
好了,以上就是NFC读卡的功能,网上面的参考资料很多,由于没有太多注解,所以还是给个参考文章吧:
http://blog.csdn.net/zhuangxiaotang/article/details/45248093
相关文章推荐
- [置顶] Android如何监听第三方应用的启动
- android应用无法接收到广播?
- Android中第三方短信应用接收短信并保存到系统的数据库
- Android4.2中应用接收开机广播(android.intent.action.BOOT_COMPLETED)失败的原因
- [置顶] Java API学习(三)java和javax在Android中的应用
- [置顶] Android仿人人客户端(v5.7.1)——应用主界面之左侧面板UI实现
- Can I Use this Intent? Android中不要发送没有接收应用的Intent.
- [置顶] android应用中去android市场去评分的功能实现(吐槽一波个人应用上线...)
- [置顶] android应用开发之intent的妙用一
- Android 上 NFC 应用
- [置顶] Android 修改应用包名
- [置顶] python 自动化测试Android应用
- 【Android Developers Training】 33. 接收来自其它应用的简单数据
- [置顶] Android上传文件到Web服务器,PHP接收文件(二)
- Android官方开发文档Training系列课程中文版:通过NFC共享文件之从其它设备接收文件
- android应用NFC(3)---TECH_DISCOVERED的tech筛选规则
- [置顶] Android上传文件到Web服务器,PHP接收文件(一)
- [置顶] React-Native修改应用名称(Android)
- [置顶] Android应用开发之版本更新你莫愁
- [置顶] Android应用内展示word、excel、pdf、ppt等文件