Android NFC开发之写入NDEF格式数据

首先在AndroidManifest.xml文件中添加如下配置

<!-- SDK版本至少为14 -->
<uses-sdk android:minSdkVersion="14"/>
<!-- 添加NFC权限 -->
<uses-permission android:name="android.permission.NFC" />
<!-- 要求当前设备必须要有NFC芯片 -->
<uses-feature android:name="android.hardware.nfc" android:required="true" />

创建一个NFC处理的基类

public class BaseNfcActivity extends AppCompatActivity {
    private NfcAdapter mNfcAdapter;
    private PendingIntent mPendingIntent;

    @Override
    protected void onStart() {
        super.onStart();
        mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
        // 用于感应到NFC时启动该Activity
        // 这里建议将处理NFC的子类的launchMode设置成singleTop模式,这样感应到标签时就会回调onNewIntent,而不会重复打开页面
        mPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()), 0);
    }
    /**
     * 获得焦点,按钮可以点击
     */
    @Override
    public void onResume() {
        super.onResume();
        // 设置当该页面处于前台时,NFC标签会直接交给该页面处理
        if (mNfcAdapter != null) {
            mNfcAdapter.enableForegroundDispatch(this, mPendingIntent, null, null);
        }
    }
    /**
     * 暂停Activity,界面获取焦点,按钮可以点击
     */
    @Override
    public void onPause() {
        super.onPause();
        // 当页面不可见时,NFC标签不交给当前页面处理
        if (mNfcAdapter != null) {
            mNfcAdapter.disableForegroundDispatch(this);
        }
    }
}

然后创建一个NFC写标的类WriteTagActivity,继承BaseNfcActivity

public class WriteTagActivity extends BaseNfcActivity {

    private TextView mContent;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_write_tag);

        mContent = findViewById(R.id.content);
    }
    @Override
    public void onNewIntent(Intent intent) {
        String content = mContent.getText().toString().trim();
        if (TextUtils.isEmpty(content)) {
            Toast.makeText(this, "请输入待写入的数据", Toast.LENGTH_SHORT).show();
            return;
        }
        //获取Tag对象
        Tag detectedTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
        NdefMessage ndefMessage = new NdefMessage(
                new NdefRecord[] {createTextRecord(content)});
        boolean result = writeTag(ndefMessage, detectedTag);
        if (result){
            Toast.makeText(this, "写入成功", Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(this, "写入失败", Toast.LENGTH_SHORT).show();
        }
    }
    /**
     * 创建NDEF文本数据
     * @param text
     * @return
     */
    public static NdefRecord createTextRecord(String text) {
        byte[] langBytes = Locale.CHINA.getLanguage().getBytes(Charset.forName("US-ASCII"));
        Charset utfEncoding = Charset.forName("UTF-8");
        //将文本转换为UTF-8格式
        byte[] textBytes = text.getBytes(utfEncoding);
        //设置状态字节编码最高位数为0
        int utfBit = 0;
        //定义状态字节
        char status = (char) (utfBit + langBytes.length);
        byte[] data = new byte[1 + langBytes.length + textBytes.length];
        //设置第一个状态字节,先将状态码转换成字节
        data[0] = (byte) status;
        //设置语言编码,使用数组拷贝方法,从0开始拷贝到data中,拷贝到data的1到langBytes.length的位置
        System.arraycopy(langBytes, 0, data, 1, langBytes.length);
        //设置文本字节,使用数组拷贝方法,从0开始拷贝到data中,拷贝到data的1 + langBytes.length
        //到textBytes.length的位置
        System.arraycopy(textBytes, 0, data, 1 + langBytes.length, textBytes.length);
        //通过字节传入NdefRecord对象
        //NdefRecord.RTD_TEXT:传入类型 读写
        NdefRecord ndefRecord = new NdefRecord(NdefRecord.TNF_WELL_KNOWN,
                NdefRecord.RTD_TEXT, new byte[0], data);
        return ndefRecord;
    }
    /**
     * 写数据
     * @param ndefMessage 创建好的NDEF文本数据
     * @param tag 标签
     * @return
     */
    public static boolean writeTag(NdefMessage ndefMessage, Tag tag) {
        try {
            Ndef ndef = Ndef.get(tag);
            ndef.connect();
            ndef.writeNdefMessage(ndefMessage);
            return true;
        } catch (Exception e) {
        }
        return false;
    }
}

布局文件很简单,就一个输入框输入自定义写入的内容

<?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">
    <EditText
        android:id="@+id/content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
</LinearLayout>

最后记得把MainActivity的启动模式设置成singleTop

<activity
    android:name=".WriteTagActivity"
    android:launchMode="singleTop">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

测试

  1. 首先准备一台支持NFC功能的手机,打开我们写好的应用,在输入框中输入要写入的内容
  2. 准备一张NFC标签,靠近手机NFC读取区域(一般在背部)
  3. 写标成功后会提示“写入成功”

 

posted @ 2019-08-15 16:27  野猿新一  阅读(213)  评论(0编辑  收藏  举报