Quantcast
Channel: CSDN博客移动开发推荐文章
Viewing all articles
Browse latest Browse all 5930

Android NFC_P2P 开发

$
0
0
# Android NFC开发 #

----------

**我参照了NFC实战详解(赵波的一本书),没有NFC基本知识了解的推荐去看这本书的前3章,1-2小时就看完了**


**NFC的介绍啥的,我也不说了,一百度一大片,我就只上我对NFC以及代码的理解了,对了(我用的Mark编辑的,可能会有点符号,请勿见怪- -)**

----------

## 这里要说的是采用setNdefPushMessage的方式,手动发送一个NFC信息,属于NFC设备对NFC设备(p2p)的方式 ##
**PS:在这里我要吐槽一下,对于这个p2p方式的NFC数据传送,也是没谁了,要求手机的NFC传送点和点对上才能和平发送,就是手机后背有个NFC点,碰上,屏幕上才会弹出 "触摸发送" 选项,估计是塑料壳的原因吧,金属壳的不知道会不会更容易些,不吐了,上货!**


----------
**步骤1. 检查手机是否有NFC功能①,以及NFC和NFC_Beam功能②是否开启;**

**①:有NFC功能才能进行NFC的相关操作**

**②:NFC_Beam指的是设备和设备之间传输必须要开的(本人是这么理解的),不开仅仅可以设备扫卡(比如公交卡等NFC卡)**

**步骤2. 发送消息setNdefPushMessage**

**步骤3. 拦截(姑且称之为拦截)消息并处理**

**步骤4. 在MainFest文件中添加相应权限和activity-action**


----------


## 下面上代码,具体细节在注释中都能看见 ##

**对了,对NFC进行操作需要NfcAdapter这个类,是Android自带的**

**步骤1. 我定义了一个方法,进行了NFC是否开启的判断**

private void checkNFCFunction() {
    //  获取NFCAdapter(这个是全局的,参数是一个Context)
    mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
    //  mNfcAdapter为Null表示机器没有NFC功能
    if (mNfcAdapter == null) {
        //  提示      (这里是自定义的Log日志类,没有定义过可以用Log.I进行替换或者直接吐司,我也会上传代码)
        DebugUtils.LogI("没有NFC功能", getClass());
    } else {
        //  表示NFC功能未打开,就要弹出Dialog提示用户打开了
        if (!mNfcAdapter.isEnabled()) {
            Dialog dialog = null;
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setTitle("警告!");
            builder.setMessage("NFC功能未开启,是否前往开启(不开启将无法继续)");
            builder.setPositiveButton("开启", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();
                    //  ACTION_WIRELESS_SETTINGS(即跳入NFC功能开启界面)
                    Intent setnfc = new Intent(Settings.ACTION_WIRELESS_SETTINGS);
                    startActivity(setnfc);

                }
            }).setNegativeButton("不开启", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();
                    finish();
                }
            });
            dialog = builder.create();
            dialog.setCancelable(false);
            dialog.setCanceledOnTouchOutside(false);
            setDialogWidth(dialog).show();
            return;
        //  NFC功能开启之后 判断NFC_Beam功能是否开启
        } else if (!mNfcAdapter.isNdefPushEnabled()) {
            Dialog dialog = null;
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setTitle("警告!");
            builder.setMessage("NFC_Beam功能未开启,是否前往开启(不开启将无法继续)");
            builder.setPositiveButton("开启", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();
                    //  同理 ACTION_NFCSHARING_SETTINGS跳入NFC_Beam设置界面
                    Intent setnfc = new Intent(Settings.ACTION_NFCSHARING_SETTINGS);
                    startActivity(setnfc);

                }
            }).setNegativeButton("不开启", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();
                    finish();
                }
            });
            dialog = builder.create();
            dialog.setCancelable(false);
            dialog.show();
            return;
        }
    }

}

注意: 在Activity被加载的时候 需要首先调用这个方法,就是说需要放在onCreate中,当然 在onStart之前就可以

步骤2. 创建信息并且发送,NFC消息需要通过NdefMessage来装(就类似四大组件之间的消息需要用Intent来装一样)需要用到NdefMessage类,Android自带的- -,还需要一个BobNdefMessage类,不自带,一百度一大把,我这里也上传- -在下面

mButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //  步骤1 : 创建NDEF Msg (三个参数,源码在,请自查)
            NdefMessage message = BobNdefMessage.getNdefMsg_from_RTD_TEXT("我是要发送的消息", false, false);
            //  步骤2 : 发送信息
            mNfcAdapter.setNdefPushMessage(message, ActNfc2.this);
        }
    });

**步骤3. 接收消息,并处理!处理!处理!这个才是重点,弱弱的说一下,有些地方都没搞懂- -也没去搞- -当然,没搞懂的地方我会标注/(ㄒoㄒ)/~~的**
    **接收..步骤1. 需要重写这个方法,具体原因不是很清楚,反正是能接收到数据到Intent- -**

@Override
    protected void onNewIntent(Intent intent) {
        setIntent(intent);
    }

**接收..步骤2. 重写onResume() 在接收完数据的时候会回调这个方法,然后数据就通过onNewIntent传过来了,然后就能解析了/(ㄒoㄒ)/~~**

@Override
    	protected void onResume() {
    	    super.onResume();
    	    //   消息判别(判别是不是NDEF类型的消息)
    	    if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {
    	        //  处理接受到的数据(同样定义了方法)
    	        resolveIntent(getIntent());
    	    }
    	}

**重点来了,我们来处理,其实步骤就那样,一层一层的把数据取出来 intent中取出Message,Message中取出Record,Record中取出数据- -包的有够到紧的-_-**

    **首先,我们从intent中取出Message**

private void resolveIntent(Intent intent) {
        String action = intent.getAction();
		//	程序的严谨性,再判断一遍
        if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {

            NdefMessage[] messages = null;
			//	通过EXTRA_NDEF_MESSAGES_Key就能得到NFC发过来的Message数组了  -_-  就是数据转移- -
            Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
            if (rawMsgs != null) {
                messages = new NdefMessage[rawMsgs.length];
                for (int i = 0; i < rawMsgs.length; i++) {
                    messages[i] = (NdefMessage) rawMsgs[i];
                }
            } else {
                //  未知TagType
                byte[] empty = new byte[]{};
                NdefRecord record = new NdefRecord(NdefRecord.TNF_UNKNOWN, empty, empty, empty);
                NdefMessage msg = new NdefMessage(new NdefRecord[]{record});
                messages = new NdefMessage[]{msg};
            }
            //  从Message中取出Record(又定义了一个方法,)
            progressNDEFMsg(messages);
        } else if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)) {
            DebugUtils.LogI(Tag_ASSIST + "ACTION_TECH_DISCOVERED", getClass());
        } else if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)) {
            DebugUtils.LogI(Tag_ASSIST + "ACTION_TAG_DISCOVERED", getClass());
        } else {
            DebugUtils.LogI(Tag_ASSIST + "UnKnown TAG", getClass());
            finish();
            return;
        }

    }

**从Message中取出Record**
private void progressNDEFMsg(NdefMessage[] messages) {
		//	非空
        if (messages == null || messages.length == 0) {
            return;
        }
        for (int i = 0; i < messages.length; i++) {
            int length = messages[i].getRecords().length;
            NdefRecord[] records = messages[i].getRecords();
            //  几个记录(书上这里有点问题,我改了改- -具体可以看书)
            for (NdefRecord record : records) {
				//	首先需要确定是文字
                if (isTextRecord(record)) {
					//	然后 取出最后的数据
                    parseRTD_TEXTRecord(record);
                }
            }
        }
    }

**取出最后的数据**

**注:Preconditions是一个格式验证的类,要是不懂可以用if_else替代,需要Jar包,如果不想百度 我也会在后面提供下载**

private void parseRTD_TEXTRecord(NdefRecord record) {
        //  记录格式验证
        Preconditions.checkArgument(record.getTnf() == NdefRecord.TNF_WELL_KNOWN);
        //  记录类型验证
        Preconditions.checkArgument(Arrays.equals(record.getType(), NdefRecord.RTD_TEXT));

        String payloadStr = "";
        byte[] payload = record.getPayload();
        Byte statusByte = record.getPayload()[0];
		//	这一块我就不懂了 start-----
        String textEncoding = ((statusByte & 0200) == 0) ? "UTF-8" : "UTF-16";
        //  0x80=0200 ,获取状态字节编码
        //  获取语言码长度
        int languageCodeLength = statusByte & 0077;//   & 0x3F=0077(bit 5 to 0)
		//	不懂 end -----
        String languageCode = new String(payload, 1, languageCodeLength, Charset.forName("UTF-8"));
        try {
            payloadStr = new String(payload, languageCodeLength + 1, payload.length - languageCodeLength - 1, textEncoding);
        } catch (UnsupportedEncodingException e) {
            DebugUtils.LogI("异常信息" + e.getMessage(), getClass());
        }
    }


**最后的languageCode就是在另一个手机上得到的信息了,可以是Json等任何类型的String 转成实体啦,图片啦,都可以- - 后面附上部分工具类以及Jar包地址**

**哦哦 还有几个方法**

**判断是不是文字**


private boolean isTextUri(NdefRecord record) {
        if (NdefRecord.TNF_WELL_KNOWN == record.getTnf()) {
            if (Arrays.equals(NdefRecord.RTD_TEXT, record.getType())) {
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }
## 工具类 ##

**Log日志类--DebugUtils**

/**
    	* 提供打印日志的功能
    	*/
	public class DebugUtils {
	    private static boolean logIsOpen = true;     //  是否开启Log日志打印
	
    	public static void LogI(Object obj, Class clazz) {
    	    if (logIsOpen) {
    	        Log.i("RedWolf", "["+clazz.getSimpleName() + "]- " + obj);
    	    }
    	}
	}


**BobNdefMessage 直接拷贝的- -**


public class BobNdefMessage {

    /**
     * @About:create a TNF_WELL_KNOW NDEF record as RTD_URI
     * @param uriFiledStr , The rest of the URI, or the entire URI (if
     *            identifier code is 0x00).
     * @param identifierCode = prefixes(URI identifier code), 0x01=http://www.
     *            ,0x02=https://www. , 0x03=http://
     * @param flagAddAAR, true means add AAR
     * @return NdefMessage
     * @Ref: NFCForum-TS-RTD_URI_1.0
     * @By SkySeraph-2013
     */
    public static NdefMessage getNdefMsg_from_RTD_URI(String uriFiledStr, byte identifierCode,
                                                      boolean flagAddAAR) {
        byte[] uriField = uriFiledStr.getBytes(Charset.forName("US-ASCII"));
        byte[] payLoad = new byte[uriField.length + 1]; // add 1 for the URI
        // Prefix
        payLoad[0] = identifierCode; // 0x01 = prefixes http://www. to the URI
        // appends URI to payload
        System.arraycopy(uriField, 0, payLoad, 1, uriField.length);

        // Method1:
        NdefRecord rtdUriRecord1 = new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_URI,
                new byte[0], payLoad);

        // Method2:only in API 14
        String prefix = URI_PREFIX_MAP.get(identifierCode);
        NdefRecord rtdUriRecord2 = NdefRecord.createUri(prefix + uriFiledStr);

        // Method3:only in API 14
        NdefRecord rtdUriRecord3 = NdefRecord.createUri(Uri.parse(prefix + uriFiledStr));

        if (flagAddAAR) {
            // note: returns AAR for different app (nfcreadtag)
            return new NdefMessage(new NdefRecord[] {
                    rtdUriRecord1, NdefRecord.createApplicationRecord("skyseraph.nfc_demo")
            }); // packageName
        } else {
            return new NdefMessage(new NdefRecord[] {
                    rtdUriRecord1
            });
        }
    }

    /**
     * @About:create a TNF_WELL_KNOW NDEF record as RTD_TEXT
     * @param text , the really text data
     * @param encodeInUtf8 , false means TEXT encoded by UTF-8
     * @param flagAddAAR , true means add AAR
     * @return NdefMessage
     * @Ref: NFCForum-TS-RTD_Text_1.0
     * @By SkySeraph-2013
     */
    public static NdefMessage getNdefMsg_from_RTD_TEXT(String text, boolean encodeInUtf8,
                                                       boolean flagAddAAR) {

        Locale locale = new Locale("en", "US"); // a new Locale is created with
        // US English.
        byte[] langBytes = locale.getLanguage().getBytes(Charset.forName("US-ASCII"));
        // boolean encodeInUtf8 = false;
        Charset utfEncoding = encodeInUtf8 ? Charset.forName("UTF-8") : Charset.forName("UTF-16");
        int utfBit = encodeInUtf8 ? 0 : (1 << 7);
        char status = (char)(utfBit + langBytes.length);
        // String text = "This is an RTD_TEXT exp";
        byte[] textBytes = text.getBytes(utfEncoding);
        byte[] data = new byte[1 + langBytes.length + textBytes.length];
        data[0] = (byte)status;
        System.arraycopy(langBytes, 0, data, 1, langBytes.length);
        System.arraycopy(textBytes, 0, data, 1 + langBytes.length, textBytes.length);
        NdefRecord textRecord = new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT,
                new byte[0], data);

        if (flagAddAAR) {
            // note: returns AAR for different app (nfcreadtag)
            return new NdefMessage(new NdefRecord[] {
                    textRecord, NdefRecord.createApplicationRecord("skyseraph.nfc_demo")
            });
        } else {
            return new NdefMessage(new NdefRecord[] {
                    textRecord
            });
        }
    }

    /**
     * @About: create a TNF_ABSOLUTE_URI NDEF record
     * @param absoluteUri ,the absolute Uri
     * @param flagAddAAR , true means add AAR
     * @return NdefMessage
     * @Note: TNF_ABSOLUTE_URI indicates the absolute form of a URI that follows
     *        the absolute-URI rule defined by RFC 3986
     * @Note: Recommend that you use the RTD_URI type instead of
     *        TNF_ABSOLUTE_URI, because it is more efficient
     * @By SkySeraph-2013
     */
    public static NdefMessage getNdefMsg_from_ABSOLUTE_URI(String absoluteUri, boolean flagAddAAR) {
        // String absoluteUri = "http://developer.android.com/index.html";
        byte[] absoluteUriBytes = absoluteUri.getBytes(Charset.forName("US-ASCII"));
        NdefRecord uriRecord = new NdefRecord(NdefRecord.TNF_ABSOLUTE_URI, new byte[0],
                new byte[0], absoluteUriBytes);
        if (flagAddAAR) {
            // note: returns AAR for different app (nfcreadtag)
            return new NdefMessage(new NdefRecord[] {
                    uriRecord, NdefRecord.createApplicationRecord("skyseraph.nfc_demo")
            });
        } else {
            return new NdefMessage(new NdefRecord[] {
                    uriRecord
            });
        }
    }

    /**
     * @About:create a TNF_MIME_MEDIA NDEF record
     * @param payLoad,the MIME data
     * @param mimeType,the MIME Type
     * @param flagAddAAR, true means add AAR
     * @return NdefMessage
     * @By SkySeraph-2013
     */
    @SuppressLint("NewApi")
    public static NdefMessage getNdefMsg_from_MIME_MEDIA(String payLoad, String mimeType,
                                                         boolean flagAddAAR) {
        byte[] payLoadBytes = payLoad.getBytes(Charset.forName("US-ASCII"));
        // String mimeType = "application/skyseraph.nfc_demo";

        // method1:Creating the NdefRecord manually
        NdefRecord mimeRecord1 = new NdefRecord(NdefRecord.TNF_MIME_MEDIA,
                mimeType.getBytes(Charset.forName("US-ASCII")), new byte[0], payLoadBytes);
        // the identfier of the record is given as 0, since it will be the first
        // record in the NdefMessage

        // method2:Using the createMime() method, in API-16
        NdefRecord mimeRecord2 = NdefRecord.createMime(mimeType, payLoadBytes);

        if (flagAddAAR) {
            // note: returns AAR for different app (nfcreadtag)
            return new NdefMessage(new NdefRecord[] {
                    mimeRecord1, NdefRecord.createApplicationRecord("skyseraph.nfc_demo")
            });
        } else {
            return new NdefMessage(new NdefRecord[] {
                    mimeRecord1
            });
        }
    }

    /**
     * @About:create a TNF_EXTERNAL_TYPE NDEF record
     * @param payLoad,the EXTERNAL data
     * @param flagAddAAR, true means add AAR
     * @return NdefMessage
     * @By SkySeraph-2013
     */
    @SuppressLint("NewApi")
    public static NdefMessage getNdefMsg_from_EXTERNAL_TYPE(String payLoad, boolean flagAddAAR) {
        byte[] payLoadBytes = payLoad.getBytes();
        String domain = "skyseraph.nfc_demo"; // usually your app's package name
        String type = "externalType";
        String externalType = domain + ":" + type;

        // method1:Creating the NdefRecord manually
        NdefRecord exteralRecord1 = new NdefRecord(NdefRecord.TNF_EXTERNAL_TYPE,
                externalType.getBytes(), new byte[0], payLoadBytes);

        // method2:Using the createExternal() method, in API-16
        NdefRecord exteralRecord2 = NdefRecord.createExternal(domain, type, payLoadBytes);

        if (flagAddAAR) {
            // note: returns AAR for different app (nfcreadtag)
            return new NdefMessage(new NdefRecord[] {
                    exteralRecord1, NdefRecord.createApplicationRecord("skyseraph.nfc_demo")
            });
        } else {
            return new NdefMessage(new NdefRecord[] {
                    exteralRecord1
            });
        }
    }

    /**
     * checkSystemVersion()
     */
    private boolean flagVersion = false;

    private void checkSystemVersion() {
        // TODO Auto-generated method stub
        // if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)

        String systemModel;
        String releaseVersion;
        String sdkVersion;
        systemModel = android.os.Build.MODEL;
        sdkVersion = android.os.Build.VERSION.SDK;
        releaseVersion = android.os.Build.VERSION.RELEASE;
        if (Integer.parseInt(sdkVersion) > 15) {
            flagVersion = true;
        } else {
            flagVersion = false;
        }
    }

    /**
     * NFC Forum "URI Record Type Definition" This is a mapping of
     * "URI Identifier Codes" to URI string prefixes, per section 3.2.2 of the
     * NFC Forum URI Record Type Definition document.
     */
    private static final BiMap<Byte, String> URI_PREFIX_MAP = ImmutableBiMap
            .<Byte, String> builder().put((byte)0x00, "").put((byte)0x01, "http://www.")
            .put((byte)0x02, "https://www.").put((byte)0x03, "http://").put((byte)0x04, "https://")
            .put((byte)0x05, "tel:").put((byte)0x06, "mailto:")
            .put((byte)0x07, "ftp://anonymous:anonymous@").put((byte)0x08, "ftp://ftp.")
            .put((byte)0x09, "ftps://").put((byte)0x0A, "sftp://").put((byte)0x0B, "smb://")
            .put((byte)0x0C, "nfs://").put((byte)0x0D, "ftp://").put((byte)0x0E, "dav://")
            .put((byte)0x0F, "news:").put((byte)0x10, "telnet://").put((byte)0x11, "imap:")
            .put((byte)0x12, "rtsp://").put((byte)0x13, "urn:").put((byte)0x14, "pop:")
            .put((byte)0x15, "sip:").put((byte)0x16, "sips:").put((byte)0x17, "tftp:")
            .put((byte)0x18, "btspp://").put((byte)0x19, "btl2cap://").put((byte)0x1A, "btgoep://")
            .put((byte)0x1B, "tcpobex://").put((byte)0x1C, "irdaobex://")
            .put((byte)0x1D, "file://").put((byte)0x1E, "urn:epc:id:")
            .put((byte)0x1F, "urn:epc:tag:").put((byte)0x20, "urn:epc:pat:")
            .put((byte)0x21, "urn:epc:raw:").put((byte)0x22, "urn:epc:")
            .put((byte)0x23, "urn:nfc:").build();
	}


**最后附上Jar包地址,顺便带上触碰自动发送信息的源码,供大家参考(PS:- -Jar包地址明日加上- -可先自行百度- -)**


/**
 * 触屏发送订单信息
 */
//  NfcAdapter.CreateNdefMessageCallBack 接口 应该是在两个Nfc设备接触的时候 被调用的..
public class ActNfc3 extends BaseActivity implements BaseInterface, NfcAdapter.CreateNdefMessageCallback {
    //  NfcAdapter
    private NfcAdapter mNfcAdapter;
    //  EditText 发送
    private EditText etSend;
    //  TextView 接收
    private TextView tvReceive;

    private Context mContext;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.act_nfc3);
        mContext = this;
        checkNFCFunction();
        initViews();
        initDatas();
        initEvent();
    }

    @Override
    public void initViews() {
        etSend = (EditText) findViewById(R.id.et_send);
        tvReceive = (TextView) findViewById(R.id.tv_receive);
    }

    @Override
    public void initDatas() {
        mNfcAdapter.setNdefPushMessageCallback(this, this);
    }

    @Override
    public void initEvent() {

    }


    private void checkNFCFunction() {
        mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
        //  机器不支持Nfc功能
        if (mNfcAdapter == null) {
            ToastUtils.showToastFroce(mContext, "抱歉,本机不支持NFC功能");
            return;
        } else {
            //  检查机器NFC是否开启
            if (!mNfcAdapter.isEnabled()) {
                //  机器Nfc未开启 提示用户开启 这里采用对话框的方式<PS:这个开启了  可以进行对NFC的信息读写>
                AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
                builder.setTitle("警告").setMessage("本机NFC功能未开启,是否开启(不开启将无法继续)").setNegativeButton("开启", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        Intent setNfc = new Intent(Settings.ACTION_NFC_SETTINGS);
                        startActivity(setNfc);
                    }
                }).setPositiveButton("不开启", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        finish();
                    }
                }).setCancelable(false).create().show();
                return;
            } else {
                //  NFC 已开启  检查NFC_Beam是否开启  只有这个开启了  才能进行p2p的传输
                if (!mNfcAdapter.isNdefPushEnabled()) {
                    // NFC_Beam未开启  点击开启
                    new AlertDialog.Builder(mContext).setTitle("警告!").setMessage("NFC_Beam功能未开启,是否开启(不开启将无法继续)").setNegativeButton("开启", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            Intent setNfc = new Intent(Settings.ACTION_NFCSHARING_SETTINGS);
                            startActivity(setNfc);
                        }
                    }).setPositiveButton("不开启", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            finish();
                        }
                    }).setCancelable(false).create().show();
                    return;
                }
            }
        }
    }

    //  在Nfc设备相互接触的时候 调用这个方法  进行消息的发送
    @Override
    public NdefMessage createNdefMessage(NfcEvent event) {
        DebugUtils.LogI("createNdefMessage", getClass());
        //  1.创建NdefMessage
        NdefMessage message = BobNdefMessage.getNdefMsg_from_RTD_TEXT(etSend.getText().toString(), false, false);
        return message;
    }

    @Override
    protected void onNewIntent(Intent intent) {
        //  接收到消息的第一步
        setIntent(intent);
    }

    @Override
    protected void onResume() {
        super.onResume();
        //  需要从Intent中读出信息
        //  消息判别
        if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {
            resolveIntent(getIntent());
        }
    }

    private void resolveIntent(Intent intent) {
        String action = intent.getAction();
        if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {
            NdefMessage[] messages = null;
            Parcelable[] rawMsg = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
            if (rawMsg != null) {
                messages = new NdefMessage[rawMsg.length];
                for (int i = 0; i < messages.length; i++) {
                    messages[i] = (NdefMessage) rawMsg[i];
                }
            } else {
                //  未知Action
                byte[] empty = new byte[]{};
                NdefRecord ndefRecord = new NdefRecord(NdefRecord.TNF_UNKNOWN, empty, empty, empty);
                NdefMessage ndefMessage = new NdefMessage(ndefRecord);
                messages = new NdefMessage[]{ndefMessage};
            }
            //  将Message中的Record解析出来
            progressNdefMessage(messages);
        } else if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)) {

        } else if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)) {

        } else {
            return;
        }
    }

    private void progressNdefMessage(NdefMessage[] messages) {
        if (messages == null || messages.length == 0) {
            DebugUtils.LogI("progressNdefMessage-message==null", getClass());
            return;
        }
        for (int i = 0; i < messages.length; i++) {
            NdefRecord records[] = messages[i].getRecords();
            for (NdefRecord record : records) {
                DebugUtils.LogI("progressNdefMessage - record", getClass());
                if (isTextUri(record)) {
                    parseTextUri(record);
                }
            }
        }
    }

    private void parseTextUri(NdefRecord record) {
        DebugUtils.LogI("isTextUri", getClass());
        //  记录格式验证
        Preconditions.checkArgument(record.getTnf() == NdefRecord.TNF_WELL_KNOWN);
        //  记录类型验证
        Preconditions.checkArgument(Arrays.equals(record.getType(), NdefRecord.RTD_TEXT));
        //  读出所有的PayLoad
        String payLoadStr = "";
        byte[] payloads = record.getPayload();
        byte statusByte = payloads[0];
        //  得到编码方式
        String textEncoding = ((statusByte & 0200) == 0) ? "UTF-8" : "UTF-16";
        //  获取语言码的长度
        int languageCodeLength = statusByte & 0077;
        String languageCode = new String(payloads, 1, languageCodeLength, Charset.forName("UTF-8"));
        //  payloadStr = new String(payload, languageCodeLength + 1, payload.length - languageCodeLength - 1, textEncoding);

        //  真正的解析??
        payLoadStr = new String(payloads, languageCodeLength + 1, payloads.length - languageCodeLength - 1, Charset.forName(textEncoding));
        //  解析完毕,加载
        tvReceive.setText("接收完毕!-->" + payLoadStr);
    }

    private boolean isTextUri(NdefRecord record) {
        if (NdefRecord.TNF_WELL_KNOWN == record.getTnf()) {
            if (Arrays.equals(NdefRecord.RTD_TEXT, record.getType())) {
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }
	}


Android NFC开发实战详解 赵波

http://download.csdn.net/detail/redwolfchao/9663033   

http://download.csdn.net/detail/redwolfchao/9663054



作者:RedWolfChao 发表于2016/11/7 21:26:53 原文链接
阅读:6 评论:0 查看评论

Viewing all articles
Browse latest Browse all 5930

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>