下面列出了怎么用android.nfc.NdefRecord的API类实例代码及写法,或者点击链接到github查看源代码。
@Override
public NdefRecord getNdefRecord() {
byte[] payload = null;
if (hasAction() && hasActionRecord()) {
throw new IllegalArgumentException("Expected action or action record, not both.");
}
if (hasAction()) {
payload = new byte[2];
payload[0] = GcActionRecord.NUMERIC_CODE;
payload[1] = (byte)action.getValue();
}
else if (hasActionRecord()) {
byte[] subPayload = actionRecord.toByteArray();
payload = new byte[subPayload.length + 1];
payload[0] = 0;
System.arraycopy(subPayload, 0, payload, 1, subPayload.length);
} else {
throw new IllegalArgumentException("Expected action or action record.");
}
return new NdefRecord(NdefRecord.TNF_WELL_KNOWN, type, id != null ? id : EMPTY, payload);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_beam);
// Listing 18-24: Extracting the Android Beam payload
Parcelable[] messages
= getIntent().getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
if (messages != null) {
NdefMessage message = (NdefMessage) messages[0];
if (message != null) {
NdefRecord record = message.getRecords()[0];
String payload = new String(record.getPayload());
Log.d(TAG, "Payload: " + payload);
}
}
}
private void processIntent(Intent intent) {
// Listing 18-18: Extracting NFC tag payloads
String action = intent.getAction();
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {
Parcelable[] messages = getIntent().getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
if (messages != null) {
for (Parcelable eachMessage : messages) {
NdefMessage message = (NdefMessage) eachMessage;
NdefRecord[] records = message.getRecords();
if (records != null) {
for (NdefRecord record : records) {
String payload = new String(record.getPayload());
Log.d(TAG, payload);
}
}
}
}
}
}
/**
* 创建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;
}
@Override
public NdefRecord getNdefRecord() {
Message message = new Message();
if (hasTitle()) {
message.add(title);
}
if (hasUri()) {
message.add(uri);
}
if (hasAction()) {
message.add(action);
}
return new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_SMART_POSTER, id != null ? id : EMPTY, message.getNdefMessage().toByteArray());
}
@Override
public NdefRecord getNdefRecord() {
if(!hasTarget()) {
throw new IllegalArgumentException("Expected target");
}
List<NdefRecord> records = new ArrayList<NdefRecord>();
records.add(target.getNdefRecord());
if (hasAction()) {
records.add(action.getNdefRecord());
}
if (hasData()) {
records.add(data.getNdefRecord());
}
byte[] array = new NdefMessage(records.toArray(new NdefRecord[records.size()])).toByteArray();
byte[] payload = new byte[array.length + 1];
payload[0] = configurationByte;
System.arraycopy(array, 0, payload, 1, array.length);
return new NdefRecord(NdefRecord.TNF_WELL_KNOWN, type, id != null ? id : EMPTY, payload);
}
/**
* Parse an NDEF message and return the corresponding Wi-Fi configuration
*
* Source: http://androidxref.com/6.0.1_r10/xref/packages/apps/Nfc/src/com/android/nfc/NfcWifiProtectedSetup.java
*
* @param message the NDEF message to parse
* @return a WifiConfiguration extracted from the NDEF message
*/
private static WifiConfiguration parse(NdefMessage message) {
NdefRecord[] records = message.getRecords();
for (NdefRecord record : records) {
if (new String(record.getType()).equals(NFC_TOKEN_MIME_TYPE)) {
ByteBuffer payload = ByteBuffer.wrap(record.getPayload());
while (payload.hasRemaining()) {
short fieldId = payload.getShort();
short fieldSize = payload.getShort();
if (fieldId == CREDENTIAL_FIELD_ID) {
return parseCredential(payload, fieldSize);
} else {
payload.position(payload.position() + fieldSize);
}
}
}
}
return null;
}
private void setupNFC(String url) {
if (nfcAdapter != null) { // in case there is no NFC
try {
// create an NDEF message containing the current URL:
NdefRecord rec = NdefRecord.createUri(url); // url: current URL (String or Uri)
NdefMessage ndef = new NdefMessage(rec);
// make it available via Android Beam:
nfcAdapter.setNdefPushMessage(ndef, this, this);
} catch (IllegalStateException e) {
e.printStackTrace();
}
}
}
private void writeToNfc(Ndef ndef, String message){
mTvMessage.setText(getString(R.string.message_write_progress));
if (ndef != null) {
try {
ndef.connect();
NdefRecord mimeRecord = NdefRecord.createMime("text/plain", message.getBytes(Charset.forName("US-ASCII")));
ndef.writeNdefMessage(new NdefMessage(mimeRecord));
ndef.close();
//Write Successful
mTvMessage.setText(getString(R.string.message_write_success));
} catch (IOException | FormatException e) {
e.printStackTrace();
mTvMessage.setText(getString(R.string.message_write_error));
} finally {
mProgress.setVisibility(View.GONE);
}
}
}
/**
* Converts mojo NfcMessage to android.nfc.NdefMessage
*/
public static NdefMessage toNdefMessage(NfcMessage message) throws InvalidNfcMessageException {
try {
List<NdefRecord> records = new ArrayList<NdefRecord>();
for (int i = 0; i < message.data.length; ++i) {
records.add(toNdefRecord(message.data[i]));
}
records.add(NdefRecord.createExternal(DOMAIN, TYPE, message.url.getBytes("UTF-8")));
NdefRecord[] ndefRecords = new NdefRecord[records.size()];
records.toArray(ndefRecords);
return new NdefMessage(ndefRecords);
} catch (UnsupportedEncodingException | InvalidNfcMessageException
| IllegalArgumentException e) {
throw new InvalidNfcMessageException();
}
}
/**
* Converts android.nfc.NdefMessage to mojo NfcMessage
*/
public static NfcMessage toNfcMessage(NdefMessage ndefMessage)
throws UnsupportedEncodingException {
NdefRecord[] ndefRecords = ndefMessage.getRecords();
NfcMessage nfcMessage = new NfcMessage();
List<NfcRecord> nfcRecords = new ArrayList<NfcRecord>();
for (int i = 0; i < ndefRecords.length; i++) {
if ((ndefRecords[i].getTnf() == NdefRecord.TNF_EXTERNAL_TYPE)
&& (Arrays.equals(ndefRecords[i].getType(), WEBNFC_URN.getBytes("UTF-8")))) {
nfcMessage.url = new String(ndefRecords[i].getPayload(), "UTF-8");
continue;
}
NfcRecord nfcRecord = toNfcRecord(ndefRecords[i]);
if (nfcRecord != null) nfcRecords.add(nfcRecord);
}
nfcMessage.data = new NfcRecord[nfcRecords.size()];
nfcRecords.toArray(nfcMessage.data);
return nfcMessage;
}
/**
* Converts mojo NfcRecord to android.nfc.NdefRecord
*/
private static NdefRecord toNdefRecord(NfcRecord record) throws InvalidNfcMessageException,
IllegalArgumentException,
UnsupportedEncodingException {
switch (record.recordType) {
case NfcRecordType.URL:
return NdefRecord.createUri(new String(record.data, getCharset(record)));
case NfcRecordType.TEXT:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
return NdefRecord.createTextRecord(
"en-US", new String(record.data, getCharset(record)));
} else {
return NdefRecord.createMime(TEXT_MIME, record.data);
}
case NfcRecordType.JSON:
case NfcRecordType.OPAQUE_RECORD:
return NdefRecord.createMime(record.mediaType, record.data);
default:
throw new InvalidNfcMessageException();
}
}
private boolean parseNfcUri(NdefRecord record) {
Uri uri = record.toUri();
if (uri == null) {
return false;
}
if (uri.getHost().equals("v1.0.0")) {
this.mVendor = "com.google";
this.mModel = "cardboard";
this.mVersion = "1.0";
return true;
}
List<String> segments = uri.getPathSegments();
if (segments.size() != 2) {
return false;
}
this.mVendor = uri.getHost();
this.mModel = ((String) segments.get(0));
this.mVersion = ((String) segments.get(1));
return true;
}
/**
* {@inheritDoc}
*/
@Override
public SparseArray<String> readFromTagWithSparseArray(Intent nfcDataIntent) {
Parcelable[] messages = nfcDataIntent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
SparseArray<String> resultMap = messages != null ? new SparseArray<String>(messages.length) : new SparseArray<String>();
if (messages == null) {
return resultMap;
}
for (Parcelable message : messages) {
for (NdefRecord record : ((NdefMessage) message).getRecords()) {
byte type = retrieveTypeByte(record.getPayload());
String i = resultMap.get(type);
if (i == null) {
resultMap.put(type, parseAccordingToType(record));
}
}
}
return resultMap;
}
public static Record parse(NdefRecord ndefRecord) {
/**
The value 0x05 (Unknown) SHOULD be used to indicate that the type of the payload is
unknown. This is similar to the "application/octet-stream" media type defined by MIME [RFC
2046]. When used, the TYPE_LENGTH field MUST be zero and thus the TYPE field is omitted
from the NDEF record. Regarding implementation, it is RECOMMENDED that an NDEF parser
receiving an NDEF record of this type, without further context to its use, provides a mechanism
for storing but not processing the payload (see section 4.2).
*/
// check that type is zero length
byte[] type = ndefRecord.getType();
if(type != null && type.length > 0) {
throw new IllegalArgumentException("Record type not expected");
}
return new UnknownRecord(ndefRecord.getPayload());
}
@TargetApi(14)
private Lyrics getBeamedLyrics(Intent intent) {
Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
// only one message sent during the beam
if (rawMsgs != null && rawMsgs.length > 0) {
NdefMessage msg = (NdefMessage) rawMsgs[0];
// record 0 contains the MIME type, record 1 is the AAR, if present
NdefRecord[] records = msg.getRecords();
if (records.length > 0) {
try {
return Lyrics.fromBytes(records[0].getPayload());
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
return null;
}
public static NdefRecord newTextRecord(String text, Locale locale, boolean encodeInUtf8) {
byte[] langBytes = locale.getLanguage().getBytes(Charset.forName("US-ASCII"));
Charset utfEncoding = encodeInUtf8 ? Charset.forName("UTF-8") : Charset.forName("UTF-16");
byte[] textBytes = text.getBytes(utfEncoding);
int utfBit = encodeInUtf8 ? 0 : (1 << 7);
char status = (char) (utfBit + langBytes.length);
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);
return new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, new byte[0], data);
}
@SuppressLint("NewApi")
@Deprecated
protected static android.nfc.NdefRecord createUri(Uri uri) {
if (uri == null) throw new NullPointerException("Uri is null");
uri = normalizeScheme(uri);
String uriString = uri.toString();
if (uriString.length() == 0) throw new IllegalArgumentException("Uri is empty");
byte prefix = 0;
for (int i = 1; i < URI_PREFIX_MAP.length; i++) {
if (uriString.startsWith(URI_PREFIX_MAP[i])) {
prefix = (byte) i;
uriString = uriString.substring(URI_PREFIX_MAP[i].length());
break;
}
}
byte[] uriBytes = uriString.getBytes(Charset.forName("UTF-8"));
byte[] recordBytes = new byte[uriBytes.length + 1];
recordBytes[0] = prefix;
System.arraycopy(uriBytes, 0, recordBytes, 1, uriBytes.length);
return new android.nfc.NdefRecord(TNF_WELL_KNOWN, RTD_URI, new byte[]{}, recordBytes);
}
@Override
public NdefMessage createNdefMessage(NfcEvent event) {
try {
String payload = Json.toJson(Data.getInstance().getSelf().mPublicIdentity);
return new NdefMessage(
new NdefRecord[] {
NdefRecord.createMime(NFC_MIME_TYPE, payload.getBytes()),
NdefRecord.createApplicationRecord(NFC_AAR_PACKAGE_NAME) });
} catch (Utils.ApplicationError e) {
Log.addEntry(LOG_TAG, "failed to create outbound NFC message");
}
return null;
}
public static AlternativeCarrierRecord parseNdefRecord(NdefRecord ndefRecord) {
byte[] payload = ndefRecord.getPayload();
AlternativeCarrierRecord alternativeCarrierRecord = new AlternativeCarrierRecord();
// cps
alternativeCarrierRecord.setCarrierPowerState(CarrierPowerState.toCarrierPowerState(payload[0]));
// carrier data reference
short carrierDataReferenceLength = (short)payload[1];
alternativeCarrierRecord.setCarrierDataReference(new String(payload, 2, carrierDataReferenceLength,
Charset.forName("US-ASCII")));
// auxiliary data reference
short auxiliaryDataReferenceCount = (short)payload[2 + carrierDataReferenceLength];
int index = 2 + carrierDataReferenceLength + 1;
for (int i = 0; i < auxiliaryDataReferenceCount; i++) {
short auxiliaryDataReferenceLength = (short)payload[index];
alternativeCarrierRecord.addAuxiliaryDataReference(new String(payload, index + 1,
auxiliaryDataReferenceLength, Charset.forName("US-ASCII")));
index += 1 + auxiliaryDataReferenceLength;
}
// reserved end byte not checked
return alternativeCarrierRecord;
}
/**
* {@link NdefMessage} constructor.
*
* @param ndefMessage
* @throws FormatException if known record type cannot be parsed
*/
public Message(NdefMessage ndefMessage) throws FormatException {
for(NdefRecord record : ndefMessage.getRecords()) {
add(Record.parse(record));
}
}
@Override
public NdefRecord getNdefRecord() {
if(!hasLocale()) {
throw new IllegalArgumentException("Expected locale");
}
if(!hasEncoding()) {
throw new IllegalArgumentException("Expected encoding");
}
if(!hasText()) {
throw new IllegalArgumentException("Expected text");
}
byte[] languageData = (locale.getLanguage() + (locale.getCountry() == null || locale.getCountry().length() == 0 ? ""
: ("-" + locale.getCountry()))).getBytes();
if (languageData.length > TextRecord.LANGUAGE_CODE_MASK) {
throw new IllegalArgumentException("Expected language code length <= 32 bytes, not " + languageData.length + " bytes");
}
byte[] textData = text.getBytes(encoding);
byte[] payload = new byte[1 + languageData.length + textData.length];
byte status = (byte)(languageData.length | (TextRecord.UTF16.equals(encoding) ? 0x80 : 0x00));
payload[0] = status;
System.arraycopy(languageData, 0, payload, 1, languageData.length);
System.arraycopy(textData, 0, payload, 1 + languageData.length, textData.length);
return new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, id != null ? id : EMPTY, payload);
}
@Override
public NdefMessage createNdefMessage(NfcEvent event) {
try {
List<LogMapItem> logsList = DaoGpsLog.getGpslogs();
SerializableLogs logs = new SerializableLogs();
for (int i = 0; i < logsList.size(); i++) {
LogMapItem logMapItem = logsList.get(i);
if (logMapItem.isVisible()) {
Line line = DaoGpsLog.getGpslogAsLine(logMapItem.getLogID(), -1);
logs.addLog(logMapItem, line);
}
}
byte[] logBytes = Utilities.serializeObject(logs);
NdefMessage msg = new NdefMessage(NdefRecord.createMime(
logSendingMimeType, logBytes)
/**
* The Android Application Record (AAR) is commented out. When a device
* receives a push with an AAR in it, the application specified in the AAR
* is guaranteed to run. The AAR overrides the tag dispatch system.
* You can add it back in to guarantee that this
* activity starts when receiving a beamed message. For now, this code
* uses the tag dispatch system.
*/
//,NdefRecord.createApplicationRecord("com.examples.nfcbeam")
);
return msg;
} catch (IOException e) {
GPLog.error(this, "Error in sending logs.", e);//NON-NLS
}
return null;
}
@Override
public void onNewIntent(Intent intent) {
if (mText == null)
return;
//获取Tag对象
Tag detectedTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
NdefMessage ndefMessage = new NdefMessage(
new NdefRecord[]{createTextRecord(mText)});
boolean result = writeTag(ndefMessage, detectedTag);
if (result) {
Toast.makeText(this, "写入成功", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "写入失败", Toast.LENGTH_SHORT).show();
}
}
/**
* 解析NdefRecord中Uri数据
*
* @param record
* @return
*/
public static Uri parse(NdefRecord record) {
short tnf = record.getTnf();
if (tnf == NdefRecord.TNF_WELL_KNOWN) {
return parseWellKnown(record);
} else if (tnf == NdefRecord.TNF_ABSOLUTE_URI) {
return parseAbsolute(record);
}
throw new IllegalArgumentException("Unknown TNF " + tnf);
}
/**
* 处理已知类型的Uri
*
* @param ndefRecord
* @return
*/
private static Uri parseWellKnown(NdefRecord ndefRecord) {
//判断数据是否是Uri类型的
if (!Arrays.equals(ndefRecord.getType(), NdefRecord.RTD_URI))
return null;
//获取所有的字节数据
byte[] payload = ndefRecord.getPayload();
String prefix = UriPrefix.URI_PREFIX_MAP.get(payload[0]);
byte[] prefixBytes = prefix.getBytes(Charset.forName("UTF-8"));
byte[] fullUri = new byte[prefixBytes.length + payload.length - 1];
System.arraycopy(prefixBytes, 0, fullUri, 0, prefixBytes.length);
System.arraycopy(payload, 1, fullUri, prefixBytes.length, payload.length - 1);
Uri uri = Uri.parse(new String(fullUri, Charset.forName("UTF-8")));
return uri;
}
@Override
public NdefRecord getNdefRecord() {
if (!hasTargetIdentifier()) {
throw new IllegalArgumentException("Expected target identifier");
}
return new NdefRecord(NdefRecord.TNF_WELL_KNOWN, type, id != null ? id : EMPTY, targetIdentifier.toByteArray());
}
/**
* 解析NDEF文本数据,从第三个字节开始,后面的文本数据
*
* @param ndefRecord
* @return
*/
public static String parseTextRecord(NdefRecord ndefRecord) {
/**
* 判断数据是否为NDEF格式
*/
//判断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();
//下面开始NDEF文本数据第一个字节,状态字节
//判断文本是基于UTF-8还是UTF-16的,取第一个字节"位与"上16进制的80,16进制的80也就是最高位是1,
//其他位都是0,所以进行"位与"运算后就会保留最高位
String textEncoding = ((payload[0] & 0x80) == 0) ? "UTF-8" : "UTF-16";
//3f最高两位是0,第六位是1,所以进行"位与"运算后获得第六位
int languageCodeLength = payload[0] & 0x3f;
//下面开始NDEF文本数据第二个字节,语言编码
//获得语言编码
String languageCode = new String(payload, 1, languageCodeLength, "US-ASCII");
//下面开始NDEF文本数据后面的字节,解析出文本
String textRecord = new String(payload, languageCodeLength + 1,
payload.length - languageCodeLength - 1, textEncoding);
return textRecord;
} catch (Exception e) {
throw new IllegalArgumentException();
}
}
public void onNewIntent(Intent intent) {
Tag detectedTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
NdefMessage ndefMessage = new NdefMessage(new NdefRecord[]{createUriRecord(mUri)});
boolean result = writeTag(ndefMessage, detectedTag);
if (result) {
Toast.makeText(this, "写入成功", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "写入失败", Toast.LENGTH_SHORT).show();
}
}
public static ExternalTypeRecord parse(NdefRecord ndefRecord) {
String domainType = new String(ndefRecord.getType(), Charset.forName("UTF-8"));
int colon = domainType.lastIndexOf(':');
String type;
String domain;
if(colon == -1) {
domain = domainType;
type = null;
} else {
domain = domainType.substring(0, colon);
if(colon + 1 < domainType.length()) {
type = domainType.substring(colon + 1);
} else {
type = "";
}
}
if(domain.equals(AndroidApplicationRecord.DOMAIN) && type.equals(AndroidApplicationRecord.TYPE)) {
return new AndroidApplicationRecord(ndefRecord.getPayload());
}
// see if there is a custom parser
if(pluginExternalTypeParser != null) {
if(pluginExternalTypeParser.canParse(domain, type)) {
ExternalTypeRecord record = pluginExternalTypeParser.parse(domain, type, ndefRecord.getPayload());
if(record == null) {
throw new IllegalArgumentException("External Type record " + domainType + " cannot be null");
}
return record;
}
}
return new GenericExternalTypeRecord(domain, type, ndefRecord.getPayload());
}