安卓开发,NFC读取NFC标签ID,包含Dome和个人见解。

安卓开发,NFC读取NFC标签ID,包含Dome和个人见解。

(第二弹的)链接: 安卓开发,NFC读取NFC标签ID(二)。

首先放上谷歌开发文档对NFC的介绍,刚了解NFC开发的可以去看一下NFC文档

第一步想要实现的肯定是通过NFC标签调用起我们的Dome,这也是我们日常用其他NFC的基础操作。
通过学习文档,我们得知NFC的调用是通过过滤器来实现的在安装软件时就会记录下软件所能过滤的NFC类型。

一共有三种过滤器:
一、ACTION_NDEF_DISCOVERED
二、ACTION_TECH_DISCOVERED
三、ACTION_TAG_DISCOVERED

主要区别可以研究文档,大体上就是设置上的差别,优先级的差别(优先级顺序为一二三),和读写部分代码的差别。

这次我使用的第二种ACTION_TECH_DISCOVERED来实现的Dome。下面教大家配置ACTION_TECH_DISCOVERED

首先在清单文件中配置权限

<uses-permission android:name="android.permission.NFC" />
<uses-feature android:name="android.hardware.nfc" android:required="true" />

然后在想要调起跳转的页面的Activity的清单配置中加入过滤器

<application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.NfcTest">
        <activity android:name=".MainActivity"
            android:launchMode="singleTop">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.nfc.action.TECH_DISCOVERED" />
            </intent-filter>
            <meta-data
                android:name="android.nfc.action.TECH_DISCOVERED"
                android:resource="@xml/nfc_tech_filter" />
        </activity>
    </application>

这里有一个地方需要强调,就是android:launchMode=“singleTop”,虽然后面在创建NFC基类的时候会通过addFlags加上,但不知道为什么不起作用,所以还是直接在清单里加上比较方便,不然软件就会在扫描到一次标签就打开一个新页面放入栈中。

随后就是针对android:resource="@xml/nfc_tech_filter"的配置,在res下创建xml文件夹,有就不用,然后在文件夹里新建File,名称为nfc_tech_filter.xml。然后放入以下代码。

<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
    <tech-list>
        <tech>android.nfc.tech.IsoDep</tech>
    </tech-list>
    <tech-list>
        <tech>android.nfc.tech.NfcA</tech>
    </tech-list>
    <tech-list>
        <tech>android.nfc.tech.NfcB</tech>
    </tech-list>
    <tech-list>
        <tech>android.nfc.tech.NfcF</tech>
    </tech-list>
    <tech-list>
        <tech>android.nfc.tech.NfcV</tech>
    </tech-list>
    <tech-list>
        <tech>android.nfc.tech.Ndef</tech>
    </tech-list>
    <tech-list>
        <tech>android.nfc.tech.NdefFormatable</tech>
    </tech-list>
    <tech-list>
        <tech>android.nfc.tech.MifareUltralight</tech>
    </tech-list>
    <tech-list>
        <tech>android.nfc.tech.MifareClassic</tech>
    </tech-list>
</resources>

这部分比较简单,每个tech-list就是一种类型的过滤,这个包含了tech所能支持的所有类型。基本上正常的标签靠近,都能调起Dome,我自己试了四种都可以。

接下来就是主要的工作代码了,由于是读取Dome所以比较简单,目标是读取到标签上的ID就算成功。

首先创建BaseNfcActivity.java

package com.example.nfctest;

import android.app.PendingIntent;
import android.content.Intent;
import android.nfc.NdefMessage;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.os.Parcelable;
import android.provider.Settings;
import android.util.Log;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;

public class BaseNfcActivity extends AppCompatActivity {

    private NfcAdapter mNfcAdapter;
    private PendingIntent mPendingIntent;
    @Override
    protected void onStart() {
        super.onStart();
        mNfcAdapter= NfcAdapter.getDefaultAdapter(this);//设备的NfcAdapter对象
        if(mNfcAdapter==null){//判断设备是否支持NFC功能
            Toast.makeText(this,"设备不支持NFC功能!",Toast.LENGTH_SHORT);
            finish();
            return;
        }
        if (!mNfcAdapter.isEnabled()){//判断设备NFC功能是否打开
            Toast.makeText(this,"请到系统设置中打开NFC功能!",Toast.LENGTH_SHORT);
            finish();
            return;
        }
        mPendingIntent= PendingIntent.getActivity(this,0,new Intent(this,getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP),0);//创建PendingIntent对象,当检测到一个Tag标签就会执行此Intent
        Log.d("myNFC","NFC is start");
    }

    //页面获取焦点
    @Override
    protected void onResume() {
        super.onResume();
        if (mNfcAdapter!=null){
            mNfcAdapter.enableForegroundDispatch(this,mPendingIntent,null,null);//打开前台发布系统,使页面优于其它nfc处理.当检测到一个Tag标签就会执行mPendingItent
            Log.d("myNFC","onResume");
        }
    }

    //页面失去焦点
    @Override
    protected void onPause() {
        super.onPause();
        if(mNfcAdapter!=null){
            mNfcAdapter.disableForegroundDispatch(this);//关闭前台发布系统
        }
    }
    
	//也是工具不过我没用上。
    public static String flipHexStr(String s) {
        StringBuilder result = new StringBuilder();
        for (int i = 0; i <= s.length() - 2; i = i + 2) {
            result.append(new StringBuilder(s.substring(i, i + 2)).reverse());
        }
        return result.reverse().toString();
    }
    
	//工具,十六进制转十进制用的
    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;
    }
}

然后就是MainActivity.java,让它继承刚刚写的BaseNfcActivity。

package com.example.nfctest;

import android.content.Intent;
import android.nfc.NdefMessage;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.Log;
import android.widget.TextView;

public class MainActivity extends BaseNfcActivity {
    TextView content;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        content = findViewById(R.id.content);
    }


    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        if(NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())){
            Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
//            Long cardId = Long.parseLong(flipHexStr(ByteArrayToHexString(tag.getId())), 16);
//            Long cardId = Long.parseLong(ByteArrayToHexString(tag.getId()), 16);
            String cardId = ByteArrayToHexString(tag.getId());
            content.setText(cardId.toString());
        }
        Log.d("myNFC",intent.toString());
    }
}

可以看到比较短,如果之前已经看了写NFC文章的,应该知道NFC被扫描到之后不关是从桌面还是其他地方或者此应用,都会执行onNewIntent方法,而且传过来的intent中包含了标签中的数据。通过Tag获取再从Tag中获取ID。

layout代码虽然简单,但也放一下,方便大家!

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">


    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/content"
        />

</androidx.constraintlayout.widget.ConstraintLayout>

完成上述步骤,运行起来,即可验证手边的标签ID了,ID都是出厂赋予好的,不需要自己写。好了我该去研究如何写入了。一起加油吧。

不做过多的解释,因为大部分网上都有,只是上传一个简单完整的技术验证。,如果不是开发网上这种现成的工具很多,主要是考虑到包括我自己,需要开发,把这部分技术融入到项目中去!

展示一下吧,ID不是进去就获取到的,而是要调起软件后把标签拿开再放上去才能获取到,毕竟不是一开始就打开,从桌面打开只会执行onStart和onResume,之后在软件界面每次贴都会马上获取到。
在这里插入图片描述

(免费)Demo地址:https://download.csdn.net/download/weixin_45920642/19886770

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
您好!要使用Java读取Modbus TCP协议通信的数据,您可以使用Java Modbus Library。以下是一个简单的示例: 首先,您需要从以下网址下载Java Modbus Library:https://sourceforge.net/projects/jamod/files/jamod/1.2.1/ 然后,您可以使用以下代码示例读取Modbus TCP服务器上的数据: ```java import net.wimpi.modbus.Modbus; import net.wimpi.modbus.ModbusException; import net.wimpi.modbus.facade.ModbusTCPMaster; import net.wimpi.modbus.msg.ReadInputRegistersRequest; import net.wimpi.modbus.msg.ReadInputRegistersResponse; public class ModbusTCPReader { public static void main(String[] args) { try { // Create Modbus TCP master ModbusTCPMaster modbusMaster = new ModbusTCPMaster("192.168.1.1", Modbus.DEFAULT_PORT); // Connect to Modbus TCP server modbusMaster.connect(); // Read input register data from Modbus TCP server ReadInputRegistersRequest request = new ReadInputRegistersRequest(0, 10); ReadInputRegistersResponse response = (ReadInputRegistersResponse) modbusMaster.send(request); // Print input register data int[] data = response.getRegisters(); for (int i = 0; i < data.length; i++) { System.out.println("Input Register " + i + ": " + data[i]); } // Disconnect from Modbus TCP server modbusMaster.disconnect(); } catch (ModbusException e) { e.printStackTrace(); } } } ``` 请注意,上述代码中的IP地址和端口号应该根据您的Modbus TCP服务器进行更改。 希望这可以帮助您开始使用Java读取Modbus TCP协议通信的数据!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值