Android NFC读卡以及NFC的三种模式

第一步添加权限:

 

第二步:在需要读取卡内容的地方写下面的内容

@SuppressLint("NewApi")
@Override
protected void onResume() {
    super.onResume();
    NfcUtils.init(this);
    if (NfcUtils.mNfcAdapter != null)
        //监听NFC设备
        NfcUtils.mNfcAdapter.enableForegroundDispatch(this, NfcUtils.mPendingIntent, NfcUtils.mIntentFilter, NfcUtils.mTechList);
}

@SuppressLint("NewApi")
@Override
protected void onPause() {
    super.onPause();
    if (NfcUtils.mNfcAdapter != null)
        NfcUtils.mNfcAdapter.disableForegroundDispatch(this);
}

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    try {
        //hyl 2019.3.1 NFC 添加使用数据区数据 此数据为二维码数据
        String data = NfcUtils.readNFCFromTag(intent);
        Log.e(TAG, "onNewIntent: " + data);
        if (data == null&&data.isEmpty()) {
            Toast.makeText(this,"扫码失败",Toast.LENGTH_SHORT).show();
            return;
        } else {
          //获取卡里的数据的逻辑处理
            String[] split = DesUtils.decrypt(data).split(",");
            mUpLoad.setText(split[0]);
        }

    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

public class NfcUtils {
    //nfc
    public static NfcAdapter mNfcAdapter;
    public static IntentFilter[] mIntentFilter = null;
    public static PendingIntent mPendingIntent = null;
    public static String[][] mTechList = null;

    public static void init(Activity activity) {
        mNfcAdapter = NfcCheck(activity);
        NfcInit(activity);
    }

    /**
     * 检查NFC是否打开
     */
    public static NfcAdapter NfcCheck(Activity activity) {
        NfcAdapter mNfcAdapter = NfcAdapter.getDefaultAdapter(activity);
        if (mNfcAdapter == null) {
            return null;//说明当前设备不具备nfc的功能,
        } else {//nfc功能具备之后判断NFC的功能是否打开
            if (!mNfcAdapter.isEnabled()) {//在设备中启用NFC通信。
                Intent setNfc = new Intent(Settings.ACTION_NFC_SETTINGS);
                activity.startActivity(setNfc);
            }
        }
        return mNfcAdapter;
    }

    /**
     * 初始化nfc设置
     */
    public static void NfcInit(Activity activity) {
        mPendingIntent = PendingIntent.getActivity(activity, 0, new Intent(activity, activity.getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
        IntentFilter filter = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
        IntentFilter filter2 = new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED);
        try {
            filter.addDataType("*/*");
        } catch (IntentFilter.MalformedMimeTypeException e) {
            e.printStackTrace();
        }
        mIntentFilter = new IntentFilter[]{filter, filter2};
        mTechList = null;
    }

    /**
     * 读取NFC的数据
     * 接下来要详细的介绍Android是如何处理NDEF格式的标签的。当Android设备扫描到包含NDEF格式数据的NFC标签时,
     * 它会解析该消息,并尝试搞清楚数据的MIME类型或URI标识。首先系统会读取消息(NdefMessage)中的第一条NdefRecord,来判断如何解释整个NDEF消息(一个NDEF消息能够有多条NDEF记录)。 
     * 在格式良好的NDEF消息中,第一条NdefRecord包含以下字段信息:
     * 1)3-bit TNF(类型名称格式)  指示如何解释可变长度类型字段,在下表1中介绍有效值。
     */
    public static String readNFCFromTag(Intent intent) throws UnsupportedEncodingException {
        Parcelable[] rawArray = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
        if (rawArray != null) {
            NdefMessage mNdefMsg = (NdefMessage) rawArray[0];
            NdefRecord mNdefRecord = mNdefMsg.getRecords()[0];
            if (mNdefRecord != null) {
                String readResult = new String(mNdefRecord.getPayload(), "UTF-8");
                readResult = readResult.substring(3);
                return readResult;
            }
        }
        return "";
    }


    /**
     * 往nfc写入数据
     */
    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public static void writeNFCToTag(String data, Intent intent) throws IOException, FormatException {
        Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
        Ndef ndef = Ndef.get(tag);
        ndef.connect();
        NdefRecord ndefRecord = NdefRecord.createTextRecord(null, data);
        NdefRecord[] records = {ndefRecord};
        NdefMessage ndefMessage = new NdefMessage(records);
        ndef.writeNdefMessage(ndefMessage);
    }

    /**
     * 读取nfcID
     */
    public static String readNFCId(Intent intent) throws UnsupportedEncodingException {
        Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
        String id = ByteArrayToHexString(tag.getId());
        return id;
    }

    /**
     * 将字节数组转换为字符串
     */
    private static 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;
    }

}

第三步设置过滤器:


    
        

        
    
    
        

        

        
    

过滤器的设置(三种模式):

第一种模式:优先级最高。先判断是不是NDEF_DISCOVERED格式的数据,再判断NDEF_DISCOVERED数据的类型,只有与过滤器中两个条件都要求的一致,才会选择满足的activity 来处理。


    

    

    

第二种模式:优先级次于第一种模式。满足TECH_DISCOVERED的设置,才会选择满足的activity 来处理。

    

第二种模式:优先级最低。只要满足NFC规范中的任一种则都就会响应。


    

 

你可能感兴趣的:(Android NFC读卡以及NFC的三种模式)