下面列出了怎么用android.nfc.NdefMessage的API类实例代码及写法,或者点击链接到github查看源代码。
@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);
}
}
}
}
}
}
/**
* 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;
}
/**
* Writes an NdefMessage to a NFC tag
*/
public static void writeTag(NdefMessage message, Tag tag) throws Exception {
int size = message.toByteArray().length;
Ndef ndef = Ndef.get(tag);
if (ndef != null) {
ndef.connect();
if (!ndef.isWritable()) {
throw new NfcTagNotWritableException();
}
if (ndef.getMaxSize() < size) {
throw new NfcTagInsufficientMemoryException(ndef.getMaxSize(), size);
}
ndef.writeNdefMessage(message);
} else {
NdefFormatable format = NdefFormatable.get(tag);
if (format != null) {
format.connect();
format.format(message);
} else {
throw new IllegalArgumentException("Ndef format is NULL");
}
}
}
/**
* 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;
}
/**
* {@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;
}
@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);
}
/**
* {@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));
}
}
/**
* Overwrite the {@link NdefMessage} on this tag.
*
* <p>This is an I/O operation and will block until complete. It must
* not be called from the main application thread. A blocked call will be canceled with
* {@link IOException} if {@link #close} is called from another thread.
*
* <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
*
* @param msg the NDEF Message to write, must not be null
* @throws TagLostException if the tag leaves the field
* @throws IOException if there is an I/O failure, or the operation is canceled
* @throws FormatException if the NDEF Message to write is malformed
*/
public void writeNdefMessage(NdefMessage msg) throws IOException, FormatException {
checkConnected();
try {
INfcTag tagService = mTag.getTagService();
if (tagService == null) {
throw new IOException("Mock tags don't support this operation.");
}
int serviceHandle = mTag.getServiceHandle();
if (tagService.isNdef(serviceHandle)) {
int errorCode = tagService.ndefWrite(serviceHandle, msg);
switch (errorCode) {
case ErrorCodes.SUCCESS:
break;
case ErrorCodes.ERROR_IO:
throw new IOException();
case ErrorCodes.ERROR_INVALID_PARAM:
throw new FormatException();
default:
// Should not happen
throw new IOException();
}
}
else {
throw new IOException("Tag is not ndef");
}
} catch (RemoteException e) {
Log.e(TAG, "NFC service dead", e);
}
}
/**
* Parses nfc tag and extracts otp credential from it
* @param tag an NDEF compatible tag
* @return OTP data
* @throws ParseTagException if tag has no NDEF Tag Technology or there is no YK OTP payload
*/
public static @NonNull String parseTag(Tag tag) throws ParseTagException {
Ndef ndef = Ndef.get(tag);
if (ndef == null) {
throw new ParseTagException("Tag is not NDEF formatted");
}
NdefMessage message;
try {
ndef.connect();
message = ndef.getNdefMessage();
} catch (FormatException | IOException e) {
message = ndef.getCachedNdefMessage();
} finally {
try {
ndef.close();
} catch (IOException ignore) {
}
}
if (message == null) {
throw new ParseTagException("Couldn't read ndef message");
}
String parsedData = parseNdefMessage(message);
if (parsedData != null) {
return parsedData;
}
throw new ParseTagException("Tag doesn't have YK OTP payload");
}
/**
* Parses nfc tag and extracts otp credential from it
* @param ndefMessage an NDEF message from tag
* @return OTP data
*/
public static @Nullable String parseNdefMessage(NdefMessage ndefMessage) {
for (NdefRecord record : ndefMessage.getRecords()) {
String parsedData = parseNdefRecord(record);
if (parsedData != null) {
return parsedData;
}
}
return null;
}
@Override
protected void onResume() {
super.onResume();
// Listing 18-21: Creating an Android Beam NDEF message
String payload = "Two to beam across";
String mimeType = "application/com.professionalandroid.apps.nfcbeam";
byte[] tagId = new byte[0];
NdefMessage nfcMessage = new NdefMessage(new NdefRecord[] {
// Create the NFC payload.
new NdefRecord(NdefRecord.TNF_MIME_MEDIA,
mimeType.getBytes(Charset.forName("US-ASCII")),
tagId,
payload.getBytes(Charset.forName("US-ASCII"))),
// Add the AAR (Android Application Record)
NdefRecord.createApplicationRecord("com.professionalandroid.apps.nfcbeam")
});
// Set static beam message
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
nfcAdapter.setNdefPushMessage(nfcMessage, this);
// Set dynamic beam message
setBeamMessage();
}
@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;
}
/**
* {@inheritDoc}
*/
@Override
public boolean writeBluetoothAddressToTagFromIntent(@NotNull String macAddress, Intent intent) throws InsufficientCapacityException, FormatException, ReadOnlyTagException, TagNotPresentException {
final NdefMessage ndefMessage = mNfcMessageUtility.createBluetoothAddress(macAddress);
final Tag tag = retrieveTagFromIntent(intent);
return writeToTag(ndefMessage, tag);
}
@Override
public void nfcIntentDetected(Intent intent, String action) {
Log.d(TAG, "nfcIntentDetected: " + action);
Parcelable[] messages = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
if (messages != null) {
NdefMessage[] ndefMessages = new NdefMessage[messages.length];
for (int i = 0; i < messages.length; i++) {
ndefMessages[i] = (NdefMessage) messages[i];
}
if(ndefMessages.length > 0) {
// read as much as possible
Message message = new Message();
for (int i = 0; i < messages.length; i++) {
NdefMessage ndefMessage = (NdefMessage) messages[i];
for(NdefRecord ndefRecord : ndefMessage.getRecords()) {
try {
message.add(Record.parse(ndefRecord));
} catch (FormatException e) {
// if the record is unsupported or corrupted, keep as unsupported record
message.add(UnsupportedRecord.parse(ndefRecord));
}
}
}
readNdefMessage(message);
} else {
readEmptyNdefMessage();
}
} else {
readNonNdefMessage();
}
}
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();
}
}
@Override
protected void onResume() {
super.onResume();
mResumed = true;
// Sticky notes received from Android
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {
NdefMessage[] messages = getNdefMessages(getIntent());
byte[] payload = messages[0].getRecords()[0].getPayload();
setNoteBody(new String(payload));
setIntent(new Intent()); // Consume this intent.
}
enableNdefExchangeMode();
}
/**
* {@inheritDoc}
* Precondition : lat- and longitude, max 6 decimals
*/
@Override
public NdefMessage createGeolocation(Double latitude, Double longitude) throws FormatException {
latitude = Math.round(latitude * Math.pow(10, 6)) / Math.pow(10, 6);
longitude = Math.round(longitude * Math.pow(10, 6)) / Math.pow(10, 6);
String address = "geo:" + latitude.floatValue() + "," + longitude.floatValue();
String externalType = "nfclab.com:geoService";
return createUriMessage(address, NfcPayloadHeader.CUSTOM_SCHEME);
}
/**
* Generate an NDEF message containing the given Wi-Fi configuration
*
* @param wifiNetwork the Wi-Fi configuration to convert
* @return an NDEF message containing the given Wi-Fi configuration
*/
public static NdefMessage generateNdefMessage(WifiNetwork wifiNetwork) {
byte[] payload = generateNdefPayload(wifiNetwork);
NdefRecord mimeRecord = new NdefRecord(
NdefRecord.TNF_MIME_MEDIA,
NfcUtils.NFC_TOKEN_MIME_TYPE.getBytes(Charset.forName("US-ASCII")),
new byte[0],
payload);
NdefRecord aarRecord = NdefRecord.createApplicationRecord(PACKAGE_NAME);
return new NdefMessage(new NdefRecord[] {mimeRecord, aarRecord});
}
@Override
public NdefMessage createNdefMessage(NfcEvent event) {
if (mInvoice != null && mInvoice.getPaymentUrls() != null && mInvoice.getPaymentUrls().getBIP72b() != null) {
return new NdefMessage(new NdefRecord[]{
NdefRecord.createUri(mInvoice.getPaymentUrls().getBIP72())
});
}
return null;
}
private void readFromNFC(Ndef ndef) {
try {
ndef.connect();
NdefMessage ndefMessage = ndef.getNdefMessage();
String message = new String(ndefMessage.getRecords()[0].getPayload());
Log.d(TAG, "readFromNFC: "+message);
mTvMessage.setText(message);
ndef.close();
} catch (IOException | FormatException e) {
e.printStackTrace();
}
}
/**
* NdefMessage の情報を指定したリストに格納します.
*
* @param message NFCに格納されたメッセージ
* @param tagList 情報を格納するリスト
*/
private void readNdefMessage(final NdefMessage message, final List<Map<String, Object>> tagList) {
if (message != null && message.getRecords() != null) {
for (NdefRecord record : message.getRecords()) {
tagList.add(readRecord(record));
}
}
}
/**
* {@inheritDoc}
*/
@Override
public boolean writeEmailToTagFromIntent(@NotNull String recipient, String subject, String message, @NotNull Intent intent) throws FormatException, ReadOnlyTagException, InsufficientCapacityException, TagNotPresentException {
final NdefMessage ndefMessage = mNfcMessageUtility.createEmail(recipient, subject, message);
final Tag tag = retrieveTagFromIntent(intent);
return writeToTag(ndefMessage, tag);
}
private String readNfcTagPayload(Intent intent) {
Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
if (rawMsgs != null) {
NdefMessage[] msgs = new NdefMessage[rawMsgs.length];
for (int i = 0; i < rawMsgs.length; i++) {
msgs[i] = (NdefMessage) rawMsgs[i];
}
return new String(msgs[0].getRecords()[0].getPayload());
}
return null;
}
/**
* Converts a Long into a NdefMessage in application/vnd.facebook.places MIMEtype.
* <p/>
* for writing Places
*/
public static NdefMessage getAsNdef(String content) {
byte[] textBytes = content.getBytes();
NdefRecord textRecord = new NdefRecord(
NdefRecord.TNF_MIME_MEDIA,
"application/eu.power_switch".getBytes(),
new byte[]{},
textBytes);
return new NdefMessage(new NdefRecord[]{
textRecord,
NdefRecord.createApplicationRecord("eu.power_switch")});
}
/**
* {@inheritDoc}
*/
@Override
public boolean writeToNdefAndMakeReadonly(NdefMessage message, Ndef ndef) throws ReadOnlyTagException, InsufficientCapacityException, FormatException {
setReadOnly(true);
boolean result = writeToNdef(message, ndef);
setReadOnly(false);
return result;
}
/**
* {@inheritDoc}
*/
@Override
public boolean writeGeolocationToTagFromIntent(Double latitude, Double longitude, @NotNull Intent intent) throws FormatException, ReadOnlyTagException, InsufficientCapacityException, TagNotPresentException {
final NdefMessage ndefMessage = mNfcMessageUtility.createGeolocation(latitude, longitude);
final Tag tag = retrieveTagFromIntent(intent);
return writeToTag(ndefMessage, tag);
}
private NdefMessage getNoteAsNdef() {
String dummy = "dummy";
byte[] textBytes = dummy.toString().getBytes();
NdefRecord textRecord = new NdefRecord(NdefRecord.TNF_MIME_MEDIA, "text/plain".getBytes(),
new byte[] {}, textBytes);
return new NdefMessage(new NdefRecord[] {
textRecord
});
}
@Override
public NdefRecord getNdefRecord() {
// implementation note: write alternative carriers and error record together
List<NdefRecord> records = new ArrayList<NdefRecord>();
if (hasAlternativeCarriers()) {
// n alternative carrier records
for(Record record : alternativeCarriers) {
records.add(record.getNdefRecord());
}
}
if (hasError()) {
// an error message
records.add(error.getNdefRecord());
}
byte[] subPayload = new NdefMessage(records.toArray(new NdefRecord[records.size()])).toByteArray();
byte[] payload = new byte[subPayload.length + 1];
// major version, minor version
payload[0] = (byte)((majorVersion << 4) | minorVersion);
System.arraycopy(subPayload, 0, payload, 1, subPayload.length);
return new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_HANDOVER_SELECT, id != null ? id : EMPTY, payload);
}
/**
* {@inheritDoc}
*/
@Override
public Iterator<Byte> retrieveMessageTypes(NdefMessage record) {
Collection<Byte> list = new ArrayList<Byte>();
for (NdefRecord ndefRecord : record.getRecords()) {
list.add(retrieveTypeByte(ndefRecord.getPayload()));
}
return list.iterator();
}