1590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly/* 2590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * Copyright (C) 2010 The Android Open Source Project 3590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * 4590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * Licensed under the Apache License, Version 2.0 (the "License"); 5590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * you may not use this file except in compliance with the License. 6590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * You may obtain a copy of the License at 7590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * 8590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * http://www.apache.org/licenses/LICENSE-2.0 9590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * 10590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * Unless required by applicable law or agreed to in writing, software 11590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * distributed under the License is distributed on an "AS IS" BASIS, 12590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * See the License for the specific language governing permissions and 14590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * limitations under the License. 15590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly */ 16590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly 174e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamiltonpackage android.nfc.tech; 18590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly 196be655c768a82716612c00fdd156254d8dc00f42Jeff Hamiltonimport android.nfc.ErrorCodes; 206be655c768a82716612c00fdd156254d8dc00f42Jeff Hamiltonimport android.nfc.FormatException; 214e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamiltonimport android.nfc.INfcTag; 226be655c768a82716612c00fdd156254d8dc00f42Jeff Hamiltonimport android.nfc.NdefMessage; 236be655c768a82716612c00fdd156254d8dc00f42Jeff Hamiltonimport android.nfc.Tag; 2474fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pellyimport android.nfc.TagLostException; 256be655c768a82716612c00fdd156254d8dc00f42Jeff Hamiltonimport android.os.Bundle; 26590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pellyimport android.os.RemoteException; 273dd6c458530476eccb33bc05c9c9cd83823bcf8dNick Pellyimport android.util.Log; 286be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton 296be655c768a82716612c00fdd156254d8dc00f42Jeff Hamiltonimport java.io.IOException; 30590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly 31590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly/** 3274fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * Provides access to NDEF content and operations on a {@link Tag}. 336be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton * 3474fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <p>Acquire a {@link Ndef} object using {@link #get}. 3574fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * 3674fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <p>NDEF is an NFC Forum data format. The data formats are implemented in 3774fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * {@link android.nfc.NdefMessage} and 3874fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * {@link android.nfc.NdefRecord}. This class provides methods to 3974fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * retrieve and modify the {@link android.nfc.NdefMessage} 4074fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * on a tag. 4174fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * 4274fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <p>There are currently four NFC Forum standardized tag types that can be 4374fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * formatted to contain NDEF data. 4474fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <ul> 4574fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <li>NFC Forum Type 1 Tag ({@link #NFC_FORUM_TYPE_1}), such as the Innovision Topaz 4639cf3a445e507f219ecc8a476f6038f095d9d520Nick Pelly * <li>NFC Forum Type 2 Tag ({@link #NFC_FORUM_TYPE_2}), such as the NXP MIFARE Ultralight 4774fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <li>NFC Forum Type 3 Tag ({@link #NFC_FORUM_TYPE_3}), such as Sony Felica 4874fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <li>NFC Forum Type 4 Tag ({@link #NFC_FORUM_TYPE_4}), such as NXP MIFARE Desfire 4974fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * </ul> 5074fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * It is mandatory for all Android devices with NFC to correctly enumerate 5174fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * {@link Ndef} on NFC Forum Tag Types 1-4, and implement all NDEF operations 5274fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * as defined in this class. 5374fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * 5465e37ee936e2406e58719584ce30b6aa21792ce0Paul Quei * <p>Some vendors have their own well defined specifications for storing NDEF data 5574fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * on tags that do not fall into the above categories. Android devices with NFC 5674fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * should enumerate and implement {@link Ndef} under these vendor specifications 5774fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * where possible, but it is not mandatory. {@link #getType} returns a String 5874fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * describing this specification, for example {@link #MIFARE_CLASSIC} is 5974fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <code>com.nxp.ndef.mifareclassic</code>. 6074fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * 6174fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <p>Android devices that support MIFARE Classic must also correctly 6274fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * implement {@link Ndef} on MIFARE Classic tags formatted to NDEF. 6374fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * 6474fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <p>For guaranteed compatibility across all Android devices with NFC, it is 6574fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * recommended to use NFC Forum Types 1-4 in new deployments of NFC tags 6674fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * with NDEF payload. Vendor NDEF formats will not work on all Android devices. 676be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton * 6839cf3a445e507f219ecc8a476f6038f095d9d520Nick Pelly * <p class="note"><strong>Note:</strong> Methods that perform I/O operations 6939cf3a445e507f219ecc8a476f6038f095d9d520Nick Pelly * require the {@link android.Manifest.permission#NFC} permission. 70590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly */ 716be655c768a82716612c00fdd156254d8dc00f42Jeff Hamiltonpublic final class Ndef extends BasicTagTechnology { 723dd6c458530476eccb33bc05c9c9cd83823bcf8dNick Pelly private static final String TAG = "NFC"; 733dd6c458530476eccb33bc05c9c9cd83823bcf8dNick Pelly 743300e4c3ea2f2317532ded6f9e79d6ad9e038679Martijn Coenen /** @hide */ 753300e4c3ea2f2317532ded6f9e79d6ad9e038679Martijn Coenen public static final int NDEF_MODE_READ_ONLY = 1; 763300e4c3ea2f2317532ded6f9e79d6ad9e038679Martijn Coenen /** @hide */ 773300e4c3ea2f2317532ded6f9e79d6ad9e038679Martijn Coenen public static final int NDEF_MODE_READ_WRITE = 2; 783300e4c3ea2f2317532ded6f9e79d6ad9e038679Martijn Coenen /** @hide */ 793300e4c3ea2f2317532ded6f9e79d6ad9e038679Martijn Coenen public static final int NDEF_MODE_UNKNOWN = 3; 80590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly 8172df4ea8300ad345eb256cf43d8dae35eef39ba2Martijn Coenen /** @hide */ 8272df4ea8300ad345eb256cf43d8dae35eef39ba2Martijn Coenen public static final String EXTRA_NDEF_MSG = "ndefmsg"; 8372df4ea8300ad345eb256cf43d8dae35eef39ba2Martijn Coenen 846d9fc7e1efa9e99bdab366fc5d579c139fd04e71Martijn Coenen /** @hide */ 856d9fc7e1efa9e99bdab366fc5d579c139fd04e71Martijn Coenen public static final String EXTRA_NDEF_MAXLENGTH = "ndefmaxlength"; 866d9fc7e1efa9e99bdab366fc5d579c139fd04e71Martijn Coenen 873300e4c3ea2f2317532ded6f9e79d6ad9e038679Martijn Coenen /** @hide */ 883300e4c3ea2f2317532ded6f9e79d6ad9e038679Martijn Coenen public static final String EXTRA_NDEF_CARDSTATE = "ndefcardstate"; 893300e4c3ea2f2317532ded6f9e79d6ad9e038679Martijn Coenen 90d27ebf1e698c4e6929cb635768031a2e25b18acdMartijn Coenen /** @hide */ 91d27ebf1e698c4e6929cb635768031a2e25b18acdMartijn Coenen public static final String EXTRA_NDEF_TYPE = "ndeftype"; 92d27ebf1e698c4e6929cb635768031a2e25b18acdMartijn Coenen 93f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly /** @hide */ 94f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly public static final int TYPE_OTHER = -1; 95f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly /** @hide */ 96f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly public static final int TYPE_1 = 1; 97f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly /** @hide */ 98f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly public static final int TYPE_2 = 2; 99f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly /** @hide */ 100f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly public static final int TYPE_3 = 3; 101f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly /** @hide */ 102f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly public static final int TYPE_4 = 4; 103f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly /** @hide */ 104f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly public static final int TYPE_MIFARE_CLASSIC = 101; 1055644d0e18ad847b66a8cb4f185cb28edebe75d88Jeff Hamilton /** @hide */ 1065644d0e18ad847b66a8cb4f185cb28edebe75d88Jeff Hamilton public static final int TYPE_ICODE_SLI = 102; 107f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly 108f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly /** @hide */ 109f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly public static final String UNKNOWN = "android.ndef.unknown"; 110f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly 11174fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly /** NFC Forum Tag Type 1 */ 112f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly public static final String NFC_FORUM_TYPE_1 = "org.nfcforum.ndef.type1"; 11374fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly /** NFC Forum Tag Type 2 */ 114f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly public static final String NFC_FORUM_TYPE_2 = "org.nfcforum.ndef.type2"; 11574fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly /** NFC Forum Tag Type 4 */ 116f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly public static final String NFC_FORUM_TYPE_3 = "org.nfcforum.ndef.type3"; 11774fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly /** NFC Forum Tag Type 4 */ 118f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly public static final String NFC_FORUM_TYPE_4 = "org.nfcforum.ndef.type4"; 11974fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly /** NDEF on MIFARE Classic */ 120f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly public static final String MIFARE_CLASSIC = "com.nxp.ndef.mifareclassic"; 1215644d0e18ad847b66a8cb4f185cb28edebe75d88Jeff Hamilton /** 1225644d0e18ad847b66a8cb4f185cb28edebe75d88Jeff Hamilton * NDEF on iCODE SLI 1235644d0e18ad847b66a8cb4f185cb28edebe75d88Jeff Hamilton * @hide 1245644d0e18ad847b66a8cb4f185cb28edebe75d88Jeff Hamilton */ 1255644d0e18ad847b66a8cb4f185cb28edebe75d88Jeff Hamilton public static final String ICODE_SLI = "com.nxp.ndef.icodesli"; 126d27ebf1e698c4e6929cb635768031a2e25b18acdMartijn Coenen 1273300e4c3ea2f2317532ded6f9e79d6ad9e038679Martijn Coenen private final int mMaxNdefSize; 1283300e4c3ea2f2317532ded6f9e79d6ad9e038679Martijn Coenen private final int mCardState; 129e3f6336bcffc250da90ec864bccfa73ad1d016b9Martijn Coenen private final NdefMessage mNdefMsg; 130d27ebf1e698c4e6929cb635768031a2e25b18acdMartijn Coenen private final int mNdefType; 1316d9fc7e1efa9e99bdab366fc5d579c139fd04e71Martijn Coenen 132590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly /** 13374fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * Get an instance of {@link Ndef} for the given tag. 13474fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * 13574fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <p>Returns null if {@link Ndef} was not enumerated in {@link Tag#getTechList}. 13674fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * This indicates the tag is not NDEF formatted, or that this tag 13774fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * is NDEF formatted but under a vendor specification that this Android 13874fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * device does not implement. 1394e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton * 14074fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <p>Does not cause any RF activity and does not block. 14174fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * 1420bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen * @param tag an NDEF compatible tag 1430bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen * @return Ndef object 1444e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton */ 1454e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton public static Ndef get(Tag tag) { 1464e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton if (!tag.hasTech(TagTechnology.NDEF)) return null; 1474e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton try { 1484e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton return new Ndef(tag); 1494e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton } catch (RemoteException e) { 1504e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton return null; 1514e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton } 1524e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton } 1534e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton 1544e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton /** 155590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * Internal constructor, to be used by NfcAdapter 156590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * @hide 157590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly */ 1584e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton public Ndef(Tag tag) throws RemoteException { 1594e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton super(tag, TagTechnology.NDEF); 1604e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton Bundle extras = tag.getTechExtras(TagTechnology.NDEF); 1616d9fc7e1efa9e99bdab366fc5d579c139fd04e71Martijn Coenen if (extras != null) { 1623300e4c3ea2f2317532ded6f9e79d6ad9e038679Martijn Coenen mMaxNdefSize = extras.getInt(EXTRA_NDEF_MAXLENGTH); 1633300e4c3ea2f2317532ded6f9e79d6ad9e038679Martijn Coenen mCardState = extras.getInt(EXTRA_NDEF_CARDSTATE); 164e3f6336bcffc250da90ec864bccfa73ad1d016b9Martijn Coenen mNdefMsg = extras.getParcelable(EXTRA_NDEF_MSG); 165d27ebf1e698c4e6929cb635768031a2e25b18acdMartijn Coenen mNdefType = extras.getInt(EXTRA_NDEF_TYPE); 1666d9fc7e1efa9e99bdab366fc5d579c139fd04e71Martijn Coenen } else { 1673300e4c3ea2f2317532ded6f9e79d6ad9e038679Martijn Coenen throw new NullPointerException("NDEF tech extras are null."); 1686d9fc7e1efa9e99bdab366fc5d579c139fd04e71Martijn Coenen } 1693300e4c3ea2f2317532ded6f9e79d6ad9e038679Martijn Coenen 1706be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton } 171a926540d5455a973dd8ca19c00c108620d9c68c2Sylvain Fonteneau 1726be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton /** 17374fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * Get the {@link NdefMessage} that was read from the tag at discovery time. 17474fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * 17574fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <p>If the NDEF Message is modified by an I/O operation then it 17674fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * will not be updated here, this function only returns what was discovered 17774fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * when the tag entered the field. 178a032783241cbbed47ed05df32c56298ee0f9902bMartijn Coenen * <p>Note that this method may return null if the tag was in the 179a032783241cbbed47ed05df32c56298ee0f9902bMartijn Coenen * INITIALIZED state as defined by NFC Forum, as in this state the 180a032783241cbbed47ed05df32c56298ee0f9902bMartijn Coenen * tag is formatted to support NDEF but does not contain a message yet. 18174fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <p>Does not cause any RF activity and does not block. 182a032783241cbbed47ed05df32c56298ee0f9902bMartijn Coenen * @return NDEF Message read from the tag at discovery time, can be null 1836be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton */ 184e3f6336bcffc250da90ec864bccfa73ad1d016b9Martijn Coenen public NdefMessage getCachedNdefMessage() { 185e3f6336bcffc250da90ec864bccfa73ad1d016b9Martijn Coenen return mNdefMsg; 186a926540d5455a973dd8ca19c00c108620d9c68c2Sylvain Fonteneau } 187a926540d5455a973dd8ca19c00c108620d9c68c2Sylvain Fonteneau 188a926540d5455a973dd8ca19c00c108620d9c68c2Sylvain Fonteneau /** 18974fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * Get the NDEF tag type. 19074fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * 191ddbb2c997b8462d7242b50ea1689a53122d4fce4Nick Pelly * <p>Returns one of {@link #NFC_FORUM_TYPE_1}, {@link #NFC_FORUM_TYPE_2}, 192ddbb2c997b8462d7242b50ea1689a53122d4fce4Nick Pelly * {@link #NFC_FORUM_TYPE_3}, {@link #NFC_FORUM_TYPE_4}, 19374fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * {@link #MIFARE_CLASSIC} or another NDEF tag type that has not yet been 19474fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * formalized in this Android API. 19574fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * 19674fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <p>Does not cause any RF activity and does not block. 19774fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * 19874fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * @return a string representing the NDEF tag type 199d27ebf1e698c4e6929cb635768031a2e25b18acdMartijn Coenen */ 200f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly public String getType() { 201f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly switch (mNdefType) { 202f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly case TYPE_1: 203f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly return NFC_FORUM_TYPE_1; 204f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly case TYPE_2: 205f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly return NFC_FORUM_TYPE_2; 206f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly case TYPE_3: 207f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly return NFC_FORUM_TYPE_3; 208f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly case TYPE_4: 209f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly return NFC_FORUM_TYPE_4; 210f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly case TYPE_MIFARE_CLASSIC: 211f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly return MIFARE_CLASSIC; 2125644d0e18ad847b66a8cb4f185cb28edebe75d88Jeff Hamilton case TYPE_ICODE_SLI: 2135644d0e18ad847b66a8cb4f185cb28edebe75d88Jeff Hamilton return ICODE_SLI; 214f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly default: 215f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly return UNKNOWN; 216f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly } 217d27ebf1e698c4e6929cb635768031a2e25b18acdMartijn Coenen } 218d27ebf1e698c4e6929cb635768031a2e25b18acdMartijn Coenen 219d27ebf1e698c4e6929cb635768031a2e25b18acdMartijn Coenen /** 22074fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * Get the maximum NDEF message size in bytes. 22174fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * 22274fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <p>Does not cause any RF activity and does not block. 22374fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * 22474fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * @return size in bytes 2256be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton */ 2263300e4c3ea2f2317532ded6f9e79d6ad9e038679Martijn Coenen public int getMaxSize() { 2273300e4c3ea2f2317532ded6f9e79d6ad9e038679Martijn Coenen return mMaxNdefSize; 2286be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton } 2296be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton 2306be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton /** 23174fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * Determine if the tag is writable. 23274fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * 23374fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <p>NFC Forum tags can be in read-only or read-write states. 23474fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * 23574fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <p>Does not cause any RF activity and does not block. 23674fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * 237e47150e933e6f610546f57183477f324566e521eNick Pelly * <p>Requires {@link android.Manifest.permission#NFC} permission. 23874fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * 23974fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * @return true if the tag is writable 240590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly */ 2413300e4c3ea2f2317532ded6f9e79d6ad9e038679Martijn Coenen public boolean isWritable() { 2423300e4c3ea2f2317532ded6f9e79d6ad9e038679Martijn Coenen return (mCardState == NDEF_MODE_READ_WRITE); 243590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly } 244590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly 245590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly /** 24674fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * Read the current {@link android.nfc.NdefMessage} on this tag. 24774fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * 24874fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <p>This always reads the current NDEF Message stored on the tag. 24974fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * 250a032783241cbbed47ed05df32c56298ee0f9902bMartijn Coenen * <p>Note that this method may return null if the tag was in the 251a032783241cbbed47ed05df32c56298ee0f9902bMartijn Coenen * INITIALIZED state as defined by NFC Forum, as in that state the 252a032783241cbbed47ed05df32c56298ee0f9902bMartijn Coenen * tag is formatted to support NDEF but does not contain a message yet. 253a032783241cbbed47ed05df32c56298ee0f9902bMartijn Coenen * 25474fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <p>This is an I/O operation and will block until complete. It must 25574fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * not be called from the main application thread. A blocked call will be canceled with 25674fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * {@link IOException} if {@link #close} is called from another thread. 25774fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * 2586c65344fcf5aa1499dafe1cad1d1ba5c66293776Martijn Coenen * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission. 2596c65344fcf5aa1499dafe1cad1d1ba5c66293776Martijn Coenen * 260a032783241cbbed47ed05df32c56298ee0f9902bMartijn Coenen * @return the NDEF Message, can be null 26174fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * @throws TagLostException if the tag leaves the field 26274fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * @throws IOException if there is an I/O failure, or the operation is canceled 26374fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * @throws FormatException if the NDEF Message on the tag is malformed 264e3f6336bcffc250da90ec864bccfa73ad1d016b9Martijn Coenen */ 265e3f6336bcffc250da90ec864bccfa73ad1d016b9Martijn Coenen public NdefMessage getNdefMessage() throws IOException, FormatException { 2664049f9d00a86f848d42d2429068496b31a6795adMartijn Coenen checkConnected(); 2674049f9d00a86f848d42d2429068496b31a6795adMartijn Coenen 268e3f6336bcffc250da90ec864bccfa73ad1d016b9Martijn Coenen try { 2694e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton INfcTag tagService = mTag.getTagService(); 27023fc93a7c1e340e79642d3d0bf4b4658c8645c8eMartijn Coenen if (tagService == null) { 27123fc93a7c1e340e79642d3d0bf4b4658c8645c8eMartijn Coenen throw new IOException("Mock tags don't support this operation."); 27223fc93a7c1e340e79642d3d0bf4b4658c8645c8eMartijn Coenen } 273e3f6336bcffc250da90ec864bccfa73ad1d016b9Martijn Coenen int serviceHandle = mTag.getServiceHandle(); 2744e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton if (tagService.isNdef(serviceHandle)) { 2754e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton NdefMessage msg = tagService.ndefRead(serviceHandle); 276a032783241cbbed47ed05df32c56298ee0f9902bMartijn Coenen if (msg == null && !tagService.isPresent(serviceHandle)) { 277a032783241cbbed47ed05df32c56298ee0f9902bMartijn Coenen throw new TagLostException(); 278e3f6336bcffc250da90ec864bccfa73ad1d016b9Martijn Coenen } 279e3f6336bcffc250da90ec864bccfa73ad1d016b9Martijn Coenen return msg; 280266e0a387123773538d7768a63d37793500169a1Mathias Jeppsson } else if (!tagService.isPresent(serviceHandle)) { 281266e0a387123773538d7768a63d37793500169a1Mathias Jeppsson throw new TagLostException(); 282e3f6336bcffc250da90ec864bccfa73ad1d016b9Martijn Coenen } else { 283e3f6336bcffc250da90ec864bccfa73ad1d016b9Martijn Coenen return null; 284e3f6336bcffc250da90ec864bccfa73ad1d016b9Martijn Coenen } 285e3f6336bcffc250da90ec864bccfa73ad1d016b9Martijn Coenen } catch (RemoteException e) { 2863dd6c458530476eccb33bc05c9c9cd83823bcf8dNick Pelly Log.e(TAG, "NFC service dead", e); 287e3f6336bcffc250da90ec864bccfa73ad1d016b9Martijn Coenen return null; 288e3f6336bcffc250da90ec864bccfa73ad1d016b9Martijn Coenen } 289e3f6336bcffc250da90ec864bccfa73ad1d016b9Martijn Coenen } 2903ce86481cbde92e2cb6fe3a46cbedd8b2a5c4b48Jeff Hamilton 291e3f6336bcffc250da90ec864bccfa73ad1d016b9Martijn Coenen /** 29274fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * Overwrite the {@link NdefMessage} on this tag. 29374fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * 29474fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <p>This is an I/O operation and will block until complete. It must 29574fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * not be called from the main application thread. A blocked call will be canceled with 29674fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * {@link IOException} if {@link #close} is called from another thread. 29774fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * 29839cf3a445e507f219ecc8a476f6038f095d9d520Nick Pelly * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission. 29939cf3a445e507f219ecc8a476f6038f095d9d520Nick Pelly * 30074fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * @param msg the NDEF Message to write, must not be null 30174fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * @throws TagLostException if the tag leaves the field 30274fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * @throws IOException if there is an I/O failure, or the operation is canceled 30374fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * @throws FormatException if the NDEF Message to write is malformed 304590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly */ 3056be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton public void writeNdefMessage(NdefMessage msg) throws IOException, FormatException { 3064049f9d00a86f848d42d2429068496b31a6795adMartijn Coenen checkConnected(); 3074049f9d00a86f848d42d2429068496b31a6795adMartijn Coenen 308590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly try { 3094e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton INfcTag tagService = mTag.getTagService(); 31023fc93a7c1e340e79642d3d0bf4b4658c8645c8eMartijn Coenen if (tagService == null) { 31123fc93a7c1e340e79642d3d0bf4b4658c8645c8eMartijn Coenen throw new IOException("Mock tags don't support this operation."); 31223fc93a7c1e340e79642d3d0bf4b4658c8645c8eMartijn Coenen } 31301d159aa2c6303089269258f3ae047e74df9e2a9Martijn Coenen int serviceHandle = mTag.getServiceHandle(); 3144e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton if (tagService.isNdef(serviceHandle)) { 3154e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton int errorCode = tagService.ndefWrite(serviceHandle, msg); 31601d159aa2c6303089269258f3ae047e74df9e2a9Martijn Coenen switch (errorCode) { 31701d159aa2c6303089269258f3ae047e74df9e2a9Martijn Coenen case ErrorCodes.SUCCESS: 31801d159aa2c6303089269258f3ae047e74df9e2a9Martijn Coenen break; 31901d159aa2c6303089269258f3ae047e74df9e2a9Martijn Coenen case ErrorCodes.ERROR_IO: 32001d159aa2c6303089269258f3ae047e74df9e2a9Martijn Coenen throw new IOException(); 32101d159aa2c6303089269258f3ae047e74df9e2a9Martijn Coenen case ErrorCodes.ERROR_INVALID_PARAM: 32201d159aa2c6303089269258f3ae047e74df9e2a9Martijn Coenen throw new FormatException(); 32301d159aa2c6303089269258f3ae047e74df9e2a9Martijn Coenen default: 32401d159aa2c6303089269258f3ae047e74df9e2a9Martijn Coenen // Should not happen 32501d159aa2c6303089269258f3ae047e74df9e2a9Martijn Coenen throw new IOException(); 32601d159aa2c6303089269258f3ae047e74df9e2a9Martijn Coenen } 32701d159aa2c6303089269258f3ae047e74df9e2a9Martijn Coenen } 32801d159aa2c6303089269258f3ae047e74df9e2a9Martijn Coenen else { 32901d159aa2c6303089269258f3ae047e74df9e2a9Martijn Coenen throw new IOException("Tag is not ndef"); 330590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly } 331590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly } catch (RemoteException e) { 3323dd6c458530476eccb33bc05c9c9cd83823bcf8dNick Pelly Log.e(TAG, "NFC service dead", e); 333590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly } 334590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly } 335590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly 336590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly /** 33774fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * Indicates whether a tag can be made read-only with {@link #makeReadOnly()}. 33874fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * 33974fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <p>Does not cause any RF activity and does not block. 34074fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * 34174fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * @return true if it is possible to make this tag read-only 34225be53652167300183282d170a00a6df576523f5Martijn Coenen */ 343f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly public boolean canMakeReadOnly() { 344faca12adc62d148505fadfd286e6a2752c197fa0Martijn Coenen INfcTag tagService = mTag.getTagService(); 34523fc93a7c1e340e79642d3d0bf4b4658c8645c8eMartijn Coenen if (tagService == null) { 34623fc93a7c1e340e79642d3d0bf4b4658c8645c8eMartijn Coenen return false; 34723fc93a7c1e340e79642d3d0bf4b4658c8645c8eMartijn Coenen } 348faca12adc62d148505fadfd286e6a2752c197fa0Martijn Coenen try { 349faca12adc62d148505fadfd286e6a2752c197fa0Martijn Coenen return tagService.canMakeReadOnly(mNdefType); 350faca12adc62d148505fadfd286e6a2752c197fa0Martijn Coenen } catch (RemoteException e) { 351faca12adc62d148505fadfd286e6a2752c197fa0Martijn Coenen Log.e(TAG, "NFC service dead", e); 35225be53652167300183282d170a00a6df576523f5Martijn Coenen return false; 35325be53652167300183282d170a00a6df576523f5Martijn Coenen } 35425be53652167300183282d170a00a6df576523f5Martijn Coenen } 35525be53652167300183282d170a00a6df576523f5Martijn Coenen 35625be53652167300183282d170a00a6df576523f5Martijn Coenen /** 35774fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * Make a tag read-only. 35874fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * 35974fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <p>This sets the CC field to indicate the tag is read-only, 36074fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * and where possible permanently sets the lock bits to prevent 36174fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * any further modification of the memory. 36274fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <p>This is a one-way process and cannot be reverted! 36374fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * 36474fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <p>This is an I/O operation and will block until complete. It must 36574fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * not be called from the main application thread. A blocked call will be canceled with 36674fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * {@link IOException} if {@link #close} is called from another thread. 36774fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * 36839cf3a445e507f219ecc8a476f6038f095d9d520Nick Pelly * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission. 36939cf3a445e507f219ecc8a476f6038f095d9d520Nick Pelly * 37074fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * @return true on success, false if it is not possible to make this tag read-only 37174fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * @throws TagLostException if the tag leaves the field 37274fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * @throws IOException if there is an I/O failure, or the operation is canceled 373590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly */ 374f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly public boolean makeReadOnly() throws IOException { 3754049f9d00a86f848d42d2429068496b31a6795adMartijn Coenen checkConnected(); 3764049f9d00a86f848d42d2429068496b31a6795adMartijn Coenen 377590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly try { 3784e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton INfcTag tagService = mTag.getTagService(); 37923fc93a7c1e340e79642d3d0bf4b4658c8645c8eMartijn Coenen if (tagService == null) { 38023fc93a7c1e340e79642d3d0bf4b4658c8645c8eMartijn Coenen return false; 38123fc93a7c1e340e79642d3d0bf4b4658c8645c8eMartijn Coenen } 3824e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton if (tagService.isNdef(mTag.getServiceHandle())) { 3834e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton int errorCode = tagService.ndefMakeReadOnly(mTag.getServiceHandle()); 38407e6f616d122496342a5bae51323bb218d88f7f2Martijn Coenen switch (errorCode) { 38507e6f616d122496342a5bae51323bb218d88f7f2Martijn Coenen case ErrorCodes.SUCCESS: 38607e6f616d122496342a5bae51323bb218d88f7f2Martijn Coenen return true; 38707e6f616d122496342a5bae51323bb218d88f7f2Martijn Coenen case ErrorCodes.ERROR_IO: 38807e6f616d122496342a5bae51323bb218d88f7f2Martijn Coenen throw new IOException(); 38907e6f616d122496342a5bae51323bb218d88f7f2Martijn Coenen case ErrorCodes.ERROR_INVALID_PARAM: 39007e6f616d122496342a5bae51323bb218d88f7f2Martijn Coenen return false; 39107e6f616d122496342a5bae51323bb218d88f7f2Martijn Coenen default: 39207e6f616d122496342a5bae51323bb218d88f7f2Martijn Coenen // Should not happen 39307e6f616d122496342a5bae51323bb218d88f7f2Martijn Coenen throw new IOException(); 39407e6f616d122496342a5bae51323bb218d88f7f2Martijn Coenen } 39507e6f616d122496342a5bae51323bb218d88f7f2Martijn Coenen } 39607e6f616d122496342a5bae51323bb218d88f7f2Martijn Coenen else { 39707e6f616d122496342a5bae51323bb218d88f7f2Martijn Coenen throw new IOException("Tag is not ndef"); 39807e6f616d122496342a5bae51323bb218d88f7f2Martijn Coenen } 399590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly } catch (RemoteException e) { 4003dd6c458530476eccb33bc05c9c9cd83823bcf8dNick Pelly Log.e(TAG, "NFC service dead", e); 401590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly return false; 402590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly } 403590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly } 4046be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton} 405