Android设备与nfc设备创建连接 写入和读取一次扫描完成

最近在做Android扫描nfc设备的项目  发现只有一次扫描读取数据 一次扫描写入数据的情况  而没有一次扫描写入数据之后直接读取出来的需求  在这里记录一下

1.获取nfc设备支持的类型   有Nfca,Nfcv,Ndef,Isodep,MifareUltralight等  我们客户端需要知道nfc芯片支持的类型然后去做读写操作

以ndef为例下面为示例代码
@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    // 为了保证getIntent获取的是最新的
    setIntent(intent);
    if (startScan) {
        //1.获取Tag对象
        String action = intent.getAction();
        if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action) ||
                NfcAdapter.ACTION_TECH_DISCOVERED.equals(action) ||
                NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)) {
            tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
            boolean result = writeTag(tag, intent);
            Log.e("yanwei", "写标签标签成功..............................." + result);
        }
    }
}
/**
 * 写数据
 *
 * @param tag 标签
 * @return
 */
public boolean writeTag(Tag tag, Intent intent) {
    String str[] = tag.getTechList();
    if (str != null) {
        if (str.length > 0) {
            boolean supportNdef = false;
            for (int i = 0; i < str.length; i++) {
                if ("android.nfc.tech.Ndef".equals(str[i])) {
                    supportNdef = true;
                }
                Log.e("yanwei", "detectedTag = " + str[i]);
            }
            if (!supportNdef) {
                Log.e("yanwei", "不支持ndef");
                Toast.makeText(mContext, "芯片不支持ndef格式", Toast.LENGTH_SHORT).show();
            } else {
            }
        }
    }
    NdefMessage ndefMessage = new NdefMessage(new NdefRecord[]{createRecord()});
    try {
        Ndef ndef = Ndef.get(tag);
        if (ndef != null) {
            int size = ndefMessage.toByteArray().length;
            if (size > ndef.getMaxSize()) {
                Log.e("yanwei ", "写不下  --  size = " + size + " , maxSize = " + ndef.getMaxSize());
            }
            ndef.connect();
            if (!ndef.isWritable()) {
                Log.e("yanwei ", "标签不可写入");
                return false;
            }
            ndef.writeNdefMessage(ndefMessage);

            Message msg = new Message();
            msg.obj = intent;
            mHandler.sendMessageDelayed(msg, 350);
            return true;
        } else {
            NdefFormatable ndefFormatable = NdefFormatable.get(tag);
            if (ndefFormatable != null) {
                ndefFormatable.connect();
                ndefFormatable.format(ndefMessage);
                Log.e("yanwei", "type = " + "ndefFormatable");
                return true;
            } else {
                Log.e("yanwei", "ndefFormatable不支持");
                return false;
            }
        }
    } catch (Exception e) {
        startScan = false;
        popWindow.dismiss();
        Toast.makeText(mContext, "写入设备数据失败", Toast.LENGTH_LONG).show();
        Log.e("yanwei", "Exception = " + e.getMessage() + " ,, " + e.getLocalizedMessage() + " ,, ");
    }
    return false;
}

 

private Handler mHandler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        Log.e("yanwei", "3.5ms");
        Intent intent = (Intent) msg.obj;
        Parcelable[] rawMessage = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
        NdefMessage[] ndefMessages = null;
        // 判断是哪种类型的数据 默认为NDEF格式
        if (rawMessage != null) {
            ndefMessages = new NdefMessage[rawMessage.length];
            for (int i = 0; i < rawMessage.length; i++) {
                ndefMessages[i] = (NdefMessage) rawMessage[i];
            }
        }
        NdefMessage ndefMessage = null;
        if (ndefMessages.length > 0) {
            ndefMessage = ndefMessages[0];
        }
        if (ndefMessage != null) {
            NdefRecord record = ndefMessage.getRecords()[0];
            parseTextRecord(record);
        } else {
            Log.e("yanwei", "ndefMessage == null");
            startScan = false;
            popWindow.dismiss();
            Toast.makeText(mContext, "读取设备数据失败", Toast.LENGTH_LONG).show();
        }
    }
};

实际上我们通过onNewIntent方法回调接收到nfc相关的intent之后  Android设备就与nfc芯片创建了链接  不管你用哪种格式的数据(nfca,nfcv,ndef....)

他们都有一个创建链接的方法 例如:ndef.connect();  创建链接之后 调用写入的方法开始写入  本例为350ms之后去intent中读取数据,也可以通过msg传值ndef来进行读取

msg.obg = ndef;   Ndef ndef = (Ndef)msg.obg; NdefMessage message = ndef.getNdefMessage();这样读取  具体看你自己的需求  这样就可以写入数据之后 马上读取出数据了

而不用再次扫描设备   希望能帮到你

 

 

经过一番修改   发现了很多需要优化的地方

1.ndef读写数据的时候 需要在子线程中操作

2.在写入数据 350ms后(这个延时是用来给硬件接收我们写入数据之后操作的时长),判断ndef的链接状态,ndef.isConnect();如果返回false

说明当前链接已经中断,继续调用读取方法会报android.nfc.TagLostException异常 Android系统会默认开启第二次扫描

 

  @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        //1.获取Tag对象
        String action = intent.getAction();
        Log.e(TAG, "onNewIntent = " + action);
        if (startScan) {
            mIntent = intent;
            startScan = false;
            if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action) ||
                    NfcAdapter.ACTION_TECH_DISCOVERED.equals(action) ||
                    NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)) {
                tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
                boolean result = writeTag();
                Log.e(TAG, "写标签标签成功..............................." + result);
            }
        }
    }
/**
     * 写数据
     *
     * @return
     */
    public boolean writeTag() {
        String str[] = tag.getTechList();
        if (str != null) {
            if (str.length > 0) {
                boolean supportNdef = false;
                for (int i = 0; i < str.length; i++) {
                    if ("android.nfc.tech.Ndef".equals(str[i])) {
                        supportNdef = true;
                    }
                    Log.e(TAG, "detectedTag = " + str[i]);
                }
                if (!supportNdef) {
                    Log.e(TAG, "不支持ndef");
                    Toast.makeText(mContext, "芯片不支持ndef格式", Toast.LENGTH_SHORT).show();
                } else {
                }
            }
        }
        final NdefMessage ndefMessage = new NdefMessage(new NdefRecord[]{createRecord()});
        try {
            final Ndef ndef = Ndef.get(tag);
            if (ndef != null) {
                int size = ndefMessage.toByteArray().length;
                if (size > ndef.getMaxSize()) {
                    Log.e(TAG, "写不下  --  size = " + size + " , maxSize = " + ndef.getMaxSize());
                }
                ndef.connect();
                if (!ndef.isWritable()) {
                    Log.e(TAG, "标签不可写入");
                    return false;
                }

                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            ndef.writeNdefMessage(ndefMessage);
                            Thread.sleep(350);

                            boolean isConnect = ndef.isConnected();
                            Log.e(TAG, "isConnect = " + isConnect);

                            NdefMessage ndefMsg = ndef.getNdefMessage();
                            Message msg = new Message();
                            msg.obj = ndefMsg;
                            msg.what = 0;
                            mHandler.sendMessage(msg);
                            ndef.close();
                        } catch (FormatException e) {
                            e.printStackTrace();
                            Log.e(TAG, "FormatException = " + e);
                            mHandler.sendEmptyMessage(1);
                            return;
                        } catch (IOException e) {
                            e.printStackTrace();
                            Log.e(TAG, "IOException = " + e);
                            mHandler.sendEmptyMessage(1);
                            return;
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                            Log.e(TAG, "InterruptedException = " + e);
                            mHandler.sendEmptyMessage(1);
                            return;
                        }
                    }
                }).start();


                return true;
            } else {
                NdefFormatable ndefFormatable = NdefFormatable.get(tag);
                if (ndefFormatable != null) {
                    ndefFormatable.connect();
                    ndefFormatable.format(ndefMessage);
                    Log.e(TAG, "type = " + "ndefFormatable");
                    return true;
                } else {
                    Log.e(TAG, "ndefFormatable不支持");
                    return false;
                }
            }
        } catch (Exception e) {
            startScan = false;
            popWindow.dismiss();
            Toast.makeText(mContext, "写入设备数据失败", Toast.LENGTH_LONG).show();
            Log.e(TAG, "Exception = " + e.getMessage() + " ,, " + e.getLocalizedMessage() + " ,, ");
        }
        return false;
    }
private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            Log.e(TAG, "350ms");
            if (msg.what == 0) {
                NdefMessage ndefMessage = (NdefMessage) msg.obj;
                if (ndefMessage != null) {
                    NdefRecord record = ndefMessage.getRecords()[0];
                    parseTextRecord(record);
                } else {
                    Log.e(TAG, "ndefMessage == null");
                    startScan = false;
                    popWindow.dismiss();
                    Toast.makeText(mContext, "读取设备数据失败", Toast.LENGTH_LONG).show();
                }
            } else {
                startScan = false;
                popWindow.dismiss();
                Toast.makeText(mContext, "通讯失败", Toast.LENGTH_LONG).show();
            }
        }
    };

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值