zoukankan      html  css  js  c++  java
  • Android NFC读取数据

    1、添加相应的权限和gradle引用
    <uses-feature
    android:name="android.hardware.nfc"
    android:required="true"/>
    <uses-permission android:name="android.permission.NFC"/>
    api 'com.google.guava:guava:25.1-android'
    2、在res下创建xml文件夹,然后新建xml文件nfc_tech_filter

    <?xml version="1.0" encoding="utf-8"?>
    <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
        <tech-list>
            <resources >
                <tech-list>
                    <!--<tech>android.nfc.tech.IsoDep</tech>-->
                    <tech>android.nfc.tech.NfcA</tech>
                    <!--<tech>android.nfc.tech.NfcB</tech>-->
                    <!--<tech>android.nfc.tech.NfcF</tech>-->
                    <!--<tech>android.nfc.tech.NfcV</tech>-->
                    <tech>android.nfc.tech.Ndef</tech>
                    <!--<tech>android.nfc.tech.NdefFormatable</tech>-->
                    <!--<tech>android.nfc.tech.MifareClassic</tech>-->
                    <!--<tech>android.nfc.tech.MifareUltralight</tech>-->
                </tech-list>
            </resources>
        </tech-list>
    </resources>

    3、使用NFC的activity添加设置

    <activity android:name=".activitys.rfid_nfc.NFCActivity"
                      android:launchMode="singleTop">
                <intent-filter>
                    <action android:name="android.nfc.action.NDEF_DISCOVERED" />
                </intent-filter>
     
                <intent-filter>
                    <action android:name="android.nfc.action.TECH_DISCOVERED" />
                </intent-filter>
     
                <intent-filter>
                    <action android:name="android.nfc.action.TAG_DISCOVERED" />
                </intent-filter>
     
                <meta-data
                    android:name="android.nfc.action.TECH_DISCOVERED"
                    android:resource="@xml/nfc_tech_filter" />
     
            </activity>

    4、NFCActivity代码

    package com.sam.more.activitys.rfid_nfc;
     
    import android.annotation.SuppressLint;
    import android.app.PendingIntent;
    import android.content.Intent;
    import android.nfc.NdefMessage;
    import android.nfc.NfcAdapter;
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.util.Log;
    import android.view.View;
    import android.widget.Button;
    import android.widget.TextView;
    import android.widget.Toast;
     
    import com.sam.more.R;
     
    import java.util.Calendar;
    import java.util.List;
     
    import butterknife.BindView;
    import butterknife.ButterKnife;
    import butterknife.OnClick;
    /**
     * Author: Sam
     * Date: 2020/11/25 9:41
     * Describe:NFC读取数据页面
     */
     
    public class NFCActivity extends AppCompatActivity {
     
        private static final String TAG = "NfcActivity";
        @BindView(R.id.tv_show_nfc)
        TextView tvShowNfc;
        @BindView(R.id.btn_clean)
        Button btnClean;
        private PendingIntent mPendingIntent;
        private NfcAdapter mNfcAdapter;
     
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_nfc);
            ButterKnife.bind(this);
            Log.i(TAG, "onCreate: ");
     
            //初始化nfc
            mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
            mPendingIntent = PendingIntent.getActivity(this, 0,
                    new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
            if (mNfcAdapter == null) {
                Toast.makeText(this, "NFC不可用", Toast.LENGTH_SHORT).show();
                finish();
                return;
            }
        }
     
        @Override
        protected void onResume() {
            super.onResume();
            Log.i(TAG, "onResume: ");
            if (mNfcAdapter != null) { //有nfc功能
                if (mNfcAdapter.isEnabled()) {
                    //nfc功能打开了
                    //隐式启动
                    mNfcAdapter.enableForegroundDispatch(this, mPendingIntent, null, null);
                } else {
                    Toast.makeText(this, "请打开NFC功能", Toast.LENGTH_SHORT).show();
                }
            }
        }
     
        @Override
        protected void onNewIntent(Intent intent) {
            super.onNewIntent(intent);
            Log.i(TAG, "onNewIntent: ");
            setIntent(intent);
            if (mNfcAdapter != null) { //有nfc功能
                if (mNfcAdapter.isEnabled()) {//nfc功能打开了
                    resolveIntent(getIntent());
                } else {
                    Toast.makeText(this, "请打开NFC功能", Toast.LENGTH_SHORT).show();
                }
            }
        }
     
     
        @Override
        protected void onPause() {
            super.onPause();
            if (mNfcAdapter != null) {
                mNfcAdapter.disableForegroundDispatch(this);
            }
        }
     
        //初次判断是什么类型的NFC卡
        private void resolveIntent(Intent intent) {
            NdefMessage[] msgs = NfcUtils.getNdefMsg(intent); //重点功能,解析nfc标签中的数据
     
            if (msgs == null) {
                Toast.makeText(this, "非NFC启动", Toast.LENGTH_SHORT).show();
            } else {
                setNFCMsgView(msgs);
            }
     
        }
     
        /**
         * 显示扫描后的信息
         *
         * @param ndefMessages ndef数据
         */
        @SuppressLint("SetTextI18n")
        private void setNFCMsgView(NdefMessage[] ndefMessages) {
            if (ndefMessages == null || ndefMessages.length == 0) {
                return;
            }
     
            Calendar calendar = Calendar.getInstance();
            int hour = calendar.get(Calendar.HOUR_OF_DAY);
            int minute = calendar.get(Calendar.MINUTE);
            tvShowNfc.append(hour + ":" + minute + "
    ");
            List<ParsedNdefRecord> records = NdefMessageParser.parse(ndefMessages[0]);
            final int size = records.size();
            for (int i = 0; i < size; i++) {
                ParsedNdefRecord record = records.get(i);
                tvShowNfc.append(record.getViewText() + "
    ");
            }
        }
     
        @OnClick({R.id.btn_clean})
        public void onViewClicked(View view) {
            switch (view.getId()) {
                case R.id.btn_clean:
                    tvShowNfc.setText("");
                    break;
            }
        }
    }

    NfcUtils工具类

    package com.sam.more.activitys.rfid_nfc;
     
    import android.content.Intent;
    import android.nfc.NdefMessage;
    import android.nfc.NdefRecord;
    import android.nfc.NfcAdapter;
    import android.nfc.Tag;
    import android.nfc.tech.MifareClassic;
    import android.nfc.tech.MifareUltralight;
    import android.os.Parcelable;
    import android.util.Log;
     
    import java.util.Arrays;
     
    /**
     * Auther: Sam
     * Time: 2020/11/24 17:26
     * Describe:
     */
     
    public class NfcUtils {
        private static final String TAG = "NfcUtil";
     
        /**
         * 解析 ndefRecord 文本数据
         *
         * @param ndefRecord
         * @return
         */
        public static String parse(NdefRecord ndefRecord) {
            // verify tnf   得到TNF的值
            if (ndefRecord.getTnf() != NdefRecord.TNF_WELL_KNOWN) {
                return null;
            }
     
            // 得到字节数组进行判断
            if (!Arrays.equals(ndefRecord.getType(), NdefRecord.RTD_TEXT)) {
                return null;
            }
     
            try {
                // 获得一个字节流
                byte[] payload = ndefRecord.getPayload();
                // payload[0]取第一个字节。 0x80:十六进制(最高位是1剩下全是0)
                String textEncoding = ((payload[0] & 0x80) == 0) ? "UTF-8" : "UTF-16";
                // 获得语言编码长度
                int languageCodeLength = payload[0] & 0x3f;
                // 获得语言编码
                String languageCode = new String(payload, 1, languageCodeLength, "US-ASCII");
                //
                String text = new String(payload, languageCodeLength + 1, payload.length - languageCodeLength - 1, textEncoding);
     
                return text;
            } catch (Exception e) {
                throw new IllegalArgumentException();
            }
        }
     
        //初次判断是什么类型的NFC卡
        public static NdefMessage[] getNdefMsg(Intent intent) {
            if (intent == null)
                return null;
     
            //nfc卡支持的格式
            Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
            String[] temp = tag.getTechList();
            for (String s : temp) {
                Log.i(TAG, "resolveIntent tag: " + s);
            }
     
     
            String action = intent.getAction();
     
            if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action) ||
                    NfcAdapter.ACTION_TECH_DISCOVERED.equals(action) ||
                    NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)) {
                Parcelable[] rawMessage = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
                NdefMessage[] ndefMessages;
     
                // 判断是哪种类型的数据 默认为NDEF格式
                if (rawMessage != null) {
                    Log.i(TAG, "getNdefMsg: ndef格式 ");
                    ndefMessages = new NdefMessage[rawMessage.length];
                    for (int i = 0; i < rawMessage.length; i++) {
                        ndefMessages[i] = (NdefMessage) rawMessage[i];
                    }
                } else {
                    //未知类型
                    Log.i(TAG, "getNdefMsg: 未知类型");
                    byte[] empty = new byte[0];
                    byte[] id = intent.getByteArrayExtra(NfcAdapter.EXTRA_ID);
                    Parcelable parcelable = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
                    byte[] payload = dumpTagData(parcelable).getBytes();
                    NdefRecord record = new NdefRecord(NdefRecord.TNF_UNKNOWN, empty, id, payload);
                    NdefMessage msg = new NdefMessage(new NdefRecord[]{record});
                    ndefMessages = new NdefMessage[]{msg};
                }
     
     
                return ndefMessages;
            }
     
            return null;
        }
     
        //一般公交卡,扫描的信息
        private static String dumpTagData(Parcelable p) {
            StringBuilder sb = new StringBuilder();
            Tag tag = (Tag) p;
            byte[] id = tag.getId();
            sb.append("Tag ID (hex): ").append(getHex(id)).append("
    ");
            sb.append("Tag ID (dec): ").append(getDec(id)).append("
    ");
            sb.append("ID (reversed): ").append(getReversed(id)).append("
    ");
     
            String prefix = "android.nfc.tech.";
            sb.append("Technologies: ");
            for (String tech : tag.getTechList()) {
                sb.append(tech.substring(prefix.length()));
                sb.append(", ");
            }
            sb.delete(sb.length() - 2, sb.length());
            for (String tech : tag.getTechList()) {
                if (tech.equals(MifareClassic.class.getName())) {
                    sb.append('
    ');
                    MifareClassic mifareTag = MifareClassic.get(tag);
                    String type = "Unknown";
                    switch (mifareTag.getType()) {
                        case MifareClassic.TYPE_CLASSIC:
                            type = "Classic";
                            break;
                        case MifareClassic.TYPE_PLUS:
                            type = "Plus";
                            break;
                        case MifareClassic.TYPE_PRO:
                            type = "Pro";
                            break;
                    }
                    sb.append("Mifare Classic type: ");
                    sb.append(type);
                    sb.append('
    ');
     
                    sb.append("Mifare size: ");
                    sb.append(mifareTag.getSize() + " bytes");
                    sb.append('
    ');
     
                    sb.append("Mifare sectors: ");
                    sb.append(mifareTag.getSectorCount());
                    sb.append('
    ');
     
                    sb.append("Mifare blocks: ");
                    sb.append(mifareTag.getBlockCount());
                }
     
                if (tech.equals(MifareUltralight.class.getName())) {
                    sb.append('
    ');
                    MifareUltralight mifareUlTag = MifareUltralight.get(tag);
                    String type = "Unknown";
                    switch (mifareUlTag.getType()) {
                        case MifareUltralight.TYPE_ULTRALIGHT:
                            type = "Ultralight";
                            break;
                        case MifareUltralight.TYPE_ULTRALIGHT_C:
                            type = "Ultralight C";
                            break;
                    }
                    sb.append("Mifare Ultralight type: ");
                    sb.append(type);
                }
            }
            return sb.toString();
        }
     
        private static String getHex(byte[] bytes) {
            StringBuilder sb = new StringBuilder();
            for (int i = bytes.length - 1; i >= 0; --i) {
                int b = bytes[i] & 0xff;
                if (b < 0x10)
                    sb.append('0');
                sb.append(Integer.toHexString(b));
                if (i > 0) {
                    sb.append(" ");
                }
            }
            return sb.toString();
        }
     
        private static long getDec(byte[] bytes) {
            long result = 0;
            long factor = 1;
            for (int i = 0; i < bytes.length; ++i) {
                long value = bytes[i] & 0xffl;
                result += value * factor;
                factor *= 256l;
            }
            return result;
        }
     
        private static long getReversed(byte[] bytes) {
            long result = 0;
            long factor = 1;
            for (int i = bytes.length - 1; i >= 0; --i) {
                long value = bytes[i] & 0xffl;
                result += value * factor;
                factor *= 256l;
            }
            return result;
        }
    }

    完整资源地址:https://download.csdn.net/download/Jeyden_827/13187753

  • 相关阅读:
    LOJ #6183 看无可看
    BZOJ 5467 Slay the Spire
    BZOJ 5306 [HAOI2018] 染色
    BZOJ 2784 时间流逝
    BZOJ4911: [Sdoi2017]切树游戏
    min-max 容斥
    BZOJ 5475: [WC 2019] 数树
    BZOJ 2810 [Apio2012]kunai
    Codeforces round 1083
    详解大数据数据仓库分层架构
  • 原文地址:https://www.cnblogs.com/zhydate/p/14716252.html
Copyright © 2011-2022 走看看