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