NfcAdapter.java revision e47150e933e6f610546f57183477f324566e521e
1/* 2 * Copyright (C) 2010 The Android Open Source Project Licensed under the Apache 3 * License, Version 2.0 (the "License"); you may not use this file except in 4 * compliance with the License. You may obtain a copy of the License at 5 * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law 6 * or agreed to in writing, software distributed under the License is 7 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 8 * KIND, either express or implied. See the License for the specific language 9 * governing permissions and limitations under the License. 10 */ 11 12package android.nfc; 13 14import java.lang.UnsupportedOperationException; 15 16import android.annotation.SdkConstant; 17import android.annotation.SdkConstant.SdkConstantType; 18import android.content.Context; 19import android.nfc.INfcAdapter; 20import android.os.IBinder; 21import android.os.RemoteException; 22import android.os.ServiceManager; 23import android.util.Log; 24 25/** 26 * Represents the device's local NFC adapter. 27 * <p> 28 * Use the static {@link #getDefaultAdapter} method to get the default NFC 29 * Adapter for this Android device. Most Android devices will have only one NFC 30 * Adapter, and {@link #getDefaultAdapter} returns the singleton object. 31 * <p> 32 * {@link NfcAdapter} can be used to create {@link RawTagConnection} or 33 * {@link NdefTagConnection} connections to modify or perform low level access 34 * to NFC Tags. 35 * <p class="note"> 36 * <strong>Note:</strong> Some methods require the 37 * {@link android.Manifest.permission#NFC} permission. 38 */ 39public final class NfcAdapter { 40 /** 41 * Intent to start an activity when a non-NDEF tag is discovered. 42 * TODO(npelly) finalize decision on using CATEGORY or DATA URI to provide a 43 * hint for applications to filter the tag type. 44 * TODO(npelly) probably combine these two intents since tags aren't that simple 45 */ 46 @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) 47 public static final String ACTION_TAG_DISCOVERED = "android.nfc.action.TAG_DISCOVERED"; 48 49 /** 50 * Intent to start an activity when a NDEF tag is discovered. TODO(npelly) 51 * finalize decision on using CATEGORY or DATA URI to provide a hint for 52 * applications to filter the tag type. 53 */ 54 @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) 55 public static final String ACTION_NDEF_TAG_DISCOVERED = 56 "android.nfc.action.NDEF_TAG_DISCOVERED"; 57 58 /** 59 * Mandatory Tag extra for the ACTION_TAG and ACTION_NDEF_TAG intents. 60 */ 61 public static final String EXTRA_TAG = "android.nfc.extra.TAG"; 62 63 /** 64 * Broadcast Action: a transaction with a secure element has been detected. 65 * <p> 66 * Always contains the extra field 67 * {@link android.nfc.NfcAdapter#EXTRA_AID} 68 * @hide 69 */ 70 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 71 public static final String ACTION_TRANSACTION_DETECTED = 72 "android.nfc.action.TRANSACTION_DETECTED"; 73 74 /** 75 * Mandatory byte array extra field in 76 * {@link android.nfc.NfcAdapter#ACTION_TRANSACTION_DETECTED}. 77 * <p> 78 * Contains the AID of the applet involved in the transaction. 79 * @hide 80 */ 81 public static final String EXTRA_AID = "android.nfc.extra.AID"; 82 83 /** 84 * LLCP link status: The LLCP link is activated. 85 * @hide 86 */ 87 public static final int LLCP_LINK_STATE_ACTIVATED = 0; 88 89 /** 90 * LLCP link status: The LLCP link is deactivated. 91 * @hide 92 */ 93 public static final int LLCP_LINK_STATE_DEACTIVATED = 1; 94 95 /** 96 * Broadcast Action: the LLCP link state changed. 97 * <p> 98 * Always contains the extra field 99 * {@link android.nfc.NfcAdapter#EXTRA_LLCP_LINK_STATE_CHANGED}. 100 * @hide 101 */ 102 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 103 public static final String ACTION_LLCP_LINK_STATE_CHANGED = 104 "android.nfc.action.LLCP_LINK_STATE_CHANGED"; 105 106 /** 107 * Used as int extra field in 108 * {@link android.nfc.NfcAdapter#ACTION_LLCP_LINK_STATE_CHANGED}. 109 * <p> 110 * It contains the new state of the LLCP link. 111 * @hide 112 */ 113 public static final String EXTRA_LLCP_LINK_STATE_CHANGED = "android.nfc.extra.LLCP_LINK_STATE"; 114 115 /** 116 * Tag Reader Discovery mode 117 * @hide 118 */ 119 private static final int DISCOVERY_MODE_TAG_READER = 0; 120 121 /** 122 * NFC-IP1 Peer-to-Peer mode Enables the manager to act as a peer in an 123 * NFC-IP1 communication. Implementations should not assume that the 124 * controller will end up behaving as an NFC-IP1 target or initiator and 125 * should handle both cases, depending on the type of the remote peer type. 126 * @hide 127 */ 128 private static final int DISCOVERY_MODE_NFCIP1 = 1; 129 130 /** 131 * Card Emulation mode Enables the manager to act as an NFC tag. Provided 132 * that a Secure Element (an UICC for instance) is connected to the NFC 133 * controller through its SWP interface, it can be exposed to the outside 134 * NFC world and be addressed by external readers the same way they would 135 * with a tag. 136 * <p> 137 * Which Secure Element is exposed is implementation-dependent. 138 * 139 * @hide 140 */ 141 private static final int DISCOVERY_MODE_CARD_EMULATION = 2; 142 143 private static final String TAG = "NFC"; 144 145 private static boolean sIsInitialized = false; 146 private static NfcAdapter sAdapter; 147 148 private final INfcAdapter mService; 149 150 private NfcAdapter(INfcAdapter service) { 151 mService = service; 152 } 153 154 /** 155 * Get a handle to the default NFC Adapter on this Android device. 156 * <p> 157 * Most Android devices will only have one NFC Adapter (NFC Controller). 158 * 159 * @return the default NFC adapter, or null if no NFC adapter exists 160 */ 161 public static NfcAdapter getDefaultAdapter() { 162 synchronized (NfcAdapter.class) { 163 if (sIsInitialized) { 164 return sAdapter; 165 } 166 sIsInitialized = true; 167 168 IBinder b = ServiceManager.getService("nfc"); 169 if (b == null) { 170 Log.d(TAG, "NFC Service not available"); 171 return null; 172 } 173 174 sAdapter = new NfcAdapter(INfcAdapter.Stub.asInterface(b)); 175 return sAdapter; 176 } 177 } 178 179 /** 180 * Return true if this NFC Adapter is enabled to discover new tags. 181 * <p> 182 * If this method returns false, then applications should request the user 183 * turn on NFC tag discovery in Settings. 184 * 185 * @return true if this NFC Adapter is enabled to discover new tags 186 */ 187 public boolean isTagDiscoveryEnabled() { 188 try { 189 return mService.isEnabled(); 190 } catch (RemoteException e) { 191 Log.e(TAG, "RemoteException in isEnabled()", e); 192 return false; 193 } 194 } 195 196 /** 197 * @hide 198 */ 199 public boolean enableTagDiscovery() { 200 try { 201 return mService.enable(); 202 } catch (RemoteException e) { 203 Log.e(TAG, "RemoteException in enable()", e); 204 return false; 205 } 206 } 207 208 /** 209 * @hide 210 */ 211 public boolean disableTagDiscovery() { 212 try { 213 return mService.disable(); 214 } catch (RemoteException e) { 215 Log.e(TAG, "RemoteException in disable()", e); 216 return false; 217 } 218 } 219 220 /** 221 * Set the NDEF Message that this NFC adapter should appear as to Tag 222 * readers. 223 * <p> 224 * Any Tag reader can read the contents of the local tag when it is in 225 * proximity, without any further user confirmation. 226 * <p> 227 * The implementation of this method must either 228 * <ul> 229 * <li>act as a passive tag containing this NDEF message 230 * <li>provide the NDEF message on over LLCP to peer NFC adapters 231 * </ul> 232 * The NDEF message is preserved across reboot. 233 * <p>Requires {@link android.Manifest.permission#NFC} permission. 234 * 235 * @param message NDEF message to make public 236 */ 237 public void setLocalNdefMessage(NdefMessage message) { 238 try { 239 mService.localSet(message); 240 } catch (RemoteException e) { 241 Log.e(TAG, "NFC service died", e); 242 } 243 } 244 245 /** 246 * Get the NDEF Message that this adapter appears as to Tag readers. 247 * <p>Requires {@link android.Manifest.permission#NFC} permission. 248 * 249 * @return NDEF Message that is publicly readable 250 */ 251 public NdefMessage getLocalNdefMessage() { 252 try { 253 return mService.localGet(); 254 } catch (RemoteException e) { 255 Log.e(TAG, "NFC service died", e); 256 return null; 257 } 258 } 259 260 /** 261 * Create a raw tag connection to the default Target 262 * <p>Requires {@link android.Manifest.permission#NFC} permission. 263 */ 264 public RawTagConnection createRawTagConnection(Tag tag) { 265 try { 266 return new RawTagConnection(mService, tag); 267 } catch (RemoteException e) { 268 Log.e(TAG, "NFC service died", e); 269 return null; 270 } 271 } 272 273 /** 274 * Create a raw tag connection to the specified Target 275 * <p>Requires {@link android.Manifest.permission#NFC} permission. 276 */ 277 public RawTagConnection createRawTagConnection(Tag tag, String target) { 278 try { 279 return new RawTagConnection(mService, tag, target); 280 } catch (RemoteException e) { 281 Log.e(TAG, "NFC service died", e); 282 return null; 283 } 284 } 285 286 /** 287 * Create an NDEF tag connection to the default Target 288 * <p>Requires {@link android.Manifest.permission#NFC} permission. 289 */ 290 public NdefTagConnection createNdefTagConnection(NdefTag tag) { 291 try { 292 return new NdefTagConnection(mService, tag); 293 } catch (RemoteException e) { 294 Log.e(TAG, "NFC service died", e); 295 return null; 296 } 297 } 298 299 /** 300 * Create an NDEF tag connection to the specified Target 301 * <p>Requires {@link android.Manifest.permission#NFC} permission. 302 */ 303 public NdefTagConnection createNdefTagConnection(NdefTag tag, String target) { 304 try { 305 return new NdefTagConnection(mService, tag, target); 306 } catch (RemoteException e) { 307 Log.e(TAG, "NFC service died", e); 308 return null; 309 } 310 } 311} 312