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 17590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pellypackage android.nfc; 18590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly 1974fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pellyimport android.content.Context; 20d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamiltonimport android.nfc.tech.IsoDep; 21d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamiltonimport android.nfc.tech.MifareClassic; 22d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamiltonimport android.nfc.tech.MifareUltralight; 23d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamiltonimport android.nfc.tech.Ndef; 24d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamiltonimport android.nfc.tech.NdefFormatable; 25d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamiltonimport android.nfc.tech.NfcA; 26d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamiltonimport android.nfc.tech.NfcB; 27f8538594fe6ba6db3310da042597840601d78cdaMartijn Coenenimport android.nfc.tech.NfcBarcode; 28d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamiltonimport android.nfc.tech.NfcF; 29d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamiltonimport android.nfc.tech.NfcV; 304e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamiltonimport android.nfc.tech.TagTechnology; 316be655c768a82716612c00fdd156254d8dc00f42Jeff Hamiltonimport android.os.Bundle; 32590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pellyimport android.os.Parcel; 33590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pellyimport android.os.Parcelable; 342dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenenimport android.os.RemoteException; 356be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton 362dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenenimport java.io.IOException; 376be655c768a82716612c00fdd156254d8dc00f42Jeff Hamiltonimport java.util.Arrays; 38590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly 39590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly/** 4074fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * Represents an NFC tag that has been discovered. 41590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * <p> 4274fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * {@link Tag} is an immutable object that represents the state of a NFC tag at 4374fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * the time of discovery. It can be used as a handle to {@link TagTechnology} classes 4428319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * to perform advanced operations, or directly queried for its ID via {@link #getId} and the 4528319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * set of technologies it contains via {@link #getTechList}. Arrays passed to and 4628319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * returned by this class are <em>not</em> cloned, so be careful not to modify them. 47590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * <p> 4874fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * A new tag object is created every time a tag is discovered (comes into range), even 4974fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * if it is the same physical tag. If a tag is removed and then returned into range, then 5074fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * only the most recent tag object can be successfully used to create a {@link TagTechnology}. 5174fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * 5274fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <h3>Tag Dispatch</h3> 5374fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * When a tag is discovered, a {@link Tag} object is created and passed to a 5428319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * single activity via the {@link NfcAdapter#EXTRA_TAG} extra in an 5528319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * {@link android.content.Intent} via {@link Context#startActivity}. A four stage dispatch is used 5628319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * to select the 5728319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * most appropriate activity to handle the tag. The Android OS executes each stage in order, 5828319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * and completes dispatch as soon as a single matching activity is found. If there are multiple 5928319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * matching activities found at any one stage then the Android activity chooser dialog is shown 6028319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * to allow the user to select the activity to receive the tag. 6128319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * 6228319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * <p>The Tag dispatch mechanism was designed to give a high probability of dispatching 6328319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * a tag to the correct activity without showing the user an activity chooser dialog. 6428319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * This is important for NFC interactions because they are very transient -- if a user has to 6528319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * move the Android device to choose an application then the connection will likely be broken. 6628319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * 6774fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <h4>1. Foreground activity dispatch</h4> 6828319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * A foreground activity that has called 6928319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * {@link NfcAdapter#enableForegroundDispatch NfcAdapter.enableForegroundDispatch()} is 7028319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * given priority. See the documentation on 7128319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * {@link NfcAdapter#enableForegroundDispatch NfcAdapter.enableForegroundDispatch()} for 7274fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * its usage. 7374fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <h4>2. NDEF data dispatch</h4> 7428319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * If the tag contains NDEF data the system inspects the first {@link NdefRecord} in the first 7528319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * {@link NdefMessage}. If the record is a URI, SmartPoster, or MIME data 7628319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * {@link Context#startActivity} is called with {@link NfcAdapter#ACTION_NDEF_DISCOVERED}. For URI 7728319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * and SmartPoster records the URI is put into the intent's data field. For MIME records the MIME 7828319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * type is put in the intent's type field. This allows activities to register to be launched only 7928319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * when data they know how to handle is present on a tag. This is the preferred method of handling 8028319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * data on a tag since NDEF data can be stored on many types of tags and doesn't depend on a 8128319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * specific tag technology. 8274fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * See {@link NfcAdapter#ACTION_NDEF_DISCOVERED} for more detail. If the tag does not contain 8328319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * NDEF data, or if no activity is registered 8428319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * for {@link NfcAdapter#ACTION_NDEF_DISCOVERED} with a matching data URI or MIME type then dispatch 8528319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * moves to stage 3. 8674fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <h4>3. Tag Technology dispatch</h4> 8774fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * {@link Context#startActivity} is called with {@link NfcAdapter#ACTION_TECH_DISCOVERED} to 8828319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * dispatch the tag to an activity that can handle the technologies present on the tag. 8974fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * Technologies are defined as sub-classes of {@link TagTechnology}, see the package 9028319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * {@link android.nfc.tech}. The Android OS looks for an activity that can handle one or 9128319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * more technologies in the tag. See {@link NfcAdapter#ACTION_TECH_DISCOVERED} for more detail. 9274fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <h4>4. Fall-back dispatch</h4> 9328319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * If no activity has been matched then {@link Context#startActivity} is called with 9474fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * {@link NfcAdapter#ACTION_TAG_DISCOVERED}. This is intended as a fall-back mechanism. 9574fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * See {@link NfcAdapter#ACTION_TAG_DISCOVERED}. 9674fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * 9774fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <h3>NFC Tag Background</h3> 9874fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * An NFC tag is a passive NFC device, powered by the NFC field of this Android device while 9928319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * it is in range. Tag's can come in many forms, such as stickers, cards, key fobs, or 10074fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * even embedded in a more sophisticated device. 10174fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <p> 10274fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * Tags can have a wide range of capabilities. Simple tags just offer read/write semantics, 10374fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * and contain some one time 10474fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * programmable areas to make read-only. More complex tags offer math operations 10574fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * and per-sector access control and authentication. The most sophisticated tags 10628319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * contain operating environments allowing complex interactions with the 10728319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * code executing on the tag. Use {@link TagTechnology} classes to access a broad 10874fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * range of capabilities available in NFC tags. 109590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * <p> 110590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly */ 111f003e26df96067b4b136f0859012cb7ec3ed930fNick Pellypublic final class Tag implements Parcelable { 1121f5badc1cb08f10ddf4b09aaaf34060a23999a51Nick Pelly final byte[] mId; 1131f5badc1cb08f10ddf4b09aaaf34060a23999a51Nick Pelly final int[] mTechList; 1141f5badc1cb08f10ddf4b09aaaf34060a23999a51Nick Pelly final String[] mTechStringList; 1151f5badc1cb08f10ddf4b09aaaf34060a23999a51Nick Pelly final Bundle[] mTechExtras; 1161f5badc1cb08f10ddf4b09aaaf34060a23999a51Nick Pelly final int mServiceHandle; // for use by NFC service, 0 indicates a mock 1171f5badc1cb08f10ddf4b09aaaf34060a23999a51Nick Pelly final INfcTag mTagService; // interface to NFC service, will be null if mock tag 118a926540d5455a973dd8ca19c00c108620d9c68c2Sylvain Fonteneau 1191f5badc1cb08f10ddf4b09aaaf34060a23999a51Nick Pelly int mConnectedTechnology; 1204049f9d00a86f848d42d2429068496b31a6795adMartijn Coenen 121590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly /** 12207f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly * Hidden constructor to be used by NFC service and internal classes. 123590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * @hide 124590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly */ 1254e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton public Tag(byte[] id, int[] techList, Bundle[] techListExtras, int serviceHandle, 1264e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton INfcTag tagService) { 1276be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton if (techList == null) { 12807f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly throw new IllegalArgumentException("rawTargets cannot be null"); 12907f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly } 13007f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly mId = id; 1316be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton mTechList = Arrays.copyOf(techList, techList.length); 132d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton mTechStringList = generateTechStringList(techList); 1336be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton // Ensure mTechExtras is as long as mTechList 1346be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton mTechExtras = Arrays.copyOf(techListExtras, techList.length); 13507f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly mServiceHandle = serviceHandle; 1364e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton mTagService = tagService; 1374049f9d00a86f848d42d2429068496b31a6795adMartijn Coenen 1384049f9d00a86f848d42d2429068496b31a6795adMartijn Coenen mConnectedTechnology = -1; 13907f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly } 14007f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly 14107f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly /** 14207f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly * Construct a mock Tag. 1434e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton * <p>This is an application constructed tag, so NfcAdapter methods on this Tag may fail 1444e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton * with {@link IllegalArgumentException} since it does not represent a physical Tag. 14507f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly * <p>This constructor might be useful for mock testing. 14607f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly * @param id The tag identifier, can be null 1476be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton * @param techList must not be null 14807f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly * @return freshly constructed tag 149f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly * @hide 15007f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly */ 1516be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton public static Tag createMockTag(byte[] id, int[] techList, Bundle[] techListExtras) { 15223fc93a7c1e340e79642d3d0bf4b4658c8645c8eMartijn Coenen // set serviceHandle to 0 and tagService to null to indicate mock tag 1534e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton return new Tag(id, techList, techListExtras, 0, null); 154590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly } 155590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly 156d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton private String[] generateTechStringList(int[] techList) { 157d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton final int size = techList.length; 158d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton String[] strings = new String[size]; 159d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton for (int i = 0; i < size; i++) { 160d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton switch (techList[i]) { 161d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton case TagTechnology.ISO_DEP: 162d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton strings[i] = IsoDep.class.getName(); 163d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton break; 164d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton case TagTechnology.MIFARE_CLASSIC: 165d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton strings[i] = MifareClassic.class.getName(); 166d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton break; 167d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton case TagTechnology.MIFARE_ULTRALIGHT: 168d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton strings[i] = MifareUltralight.class.getName(); 169d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton break; 170d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton case TagTechnology.NDEF: 171d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton strings[i] = Ndef.class.getName(); 172d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton break; 173d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton case TagTechnology.NDEF_FORMATABLE: 174d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton strings[i] = NdefFormatable.class.getName(); 175d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton break; 176d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton case TagTechnology.NFC_A: 177d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton strings[i] = NfcA.class.getName(); 178d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton break; 179d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton case TagTechnology.NFC_B: 180d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton strings[i] = NfcB.class.getName(); 181d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton break; 182d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton case TagTechnology.NFC_F: 183d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton strings[i] = NfcF.class.getName(); 184d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton break; 185d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton case TagTechnology.NFC_V: 186d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton strings[i] = NfcV.class.getName(); 187d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton break; 188f8538594fe6ba6db3310da042597840601d78cdaMartijn Coenen case TagTechnology.NFC_BARCODE: 189f8538594fe6ba6db3310da042597840601d78cdaMartijn Coenen strings[i] = NfcBarcode.class.getName(); 190f8538594fe6ba6db3310da042597840601d78cdaMartijn Coenen break; 191d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton default: 192d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton throw new IllegalArgumentException("Unknown tech type " + techList[i]); 193d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton } 194d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton } 195d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton return strings; 196d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton } 197d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton 198590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly /** 199590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * For use by NfcService only. 200590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * @hide 201590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly */ 20207f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly public int getServiceHandle() { 20307f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly return mServiceHandle; 204590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly } 205590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly 206590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly /** 20707f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly * Get the Tag Identifier (if it has one). 20874fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <p>The tag identifier is a low level serial number, used for anti-collision 20974fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * and identification. 21074fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <p> Most tags have a stable unique identifier 21174fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * (UID), but some tags will generate a random ID every time they are discovered 21274fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * (RID), and there are some tags with no ID at all (the byte array will be zero-sized). 21374fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <p> The size and format of an ID is specific to the RF technology used by the tag. 21474fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <p> This function retrieves the ID as determined at discovery time, and does not 21574fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * perform any further RF communication or block. 21674fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * @return ID as byte array, never null 21707f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly */ 21807f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly public byte[] getId() { 21907f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly return mId; 22007f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly } 22107f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly 22207f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly /** 22374fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * Get the technologies available in this tag, as fully qualified class names. 22474fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <p> 22574fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * A technology is an implementation of the {@link TagTechnology} interface, 22674fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * and can be instantiated by calling the static <code>get(Tag)</code> 22774fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * method on the implementation with this Tag. The {@link TagTechnology} 22874fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * object can then be used to perform advanced, technology-specific operations on a tag. 22974fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <p> 23074fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * Android defines a mandatory set of technologies that must be correctly 23174fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * enumerated by all Android NFC devices, and an optional 23274fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * set of proprietary technologies. 23374fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * See {@link TagTechnology} for more details. 23474fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <p> 235c1576ad627d3d2b2d3c0764c605ebbf3ddc24401Jeff Hamilton * The ordering of the returned array is undefined and should not be relied upon. 23674fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * @return an array of fully-qualified {@link TagTechnology} class-names. 237590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly */ 238d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton public String[] getTechList() { 239d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton return mTechStringList; 240590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly } 241590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly 2422dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen /** 2432dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen * Rediscover the technologies available on this tag. 2442dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen * <p> 2452dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen * The technologies that are available on a tag may change due to 2462dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen * operations being performed on a tag. For example, formatting a 2472dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen * tag as NDEF adds the {@link Ndef} technology. The {@link rediscover} 2482dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen * method reenumerates the available technologies on the tag 2492dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen * and returns a new {@link Tag} object containing these technologies. 2502dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen * <p> 2512dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen * You may not be connected to any of this {@link Tag}'s technologies 2522dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen * when calling this method. 2532dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen * This method guarantees that you will be returned the same Tag 2542dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen * if it is still in the field. 2552dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen * <p>May cause RF activity and may block. Must not be called 2562dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen * from the main application thread. A blocked call will be canceled with 2572dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen * {@link IOException} by calling {@link #close} from another thread. 2582dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen * <p>Does not remove power from the RF field, so a tag having a random 2592dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen * ID should not change its ID. 2602dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen * @return the rediscovered tag object. 2612dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen * @throws IOException if the tag cannot be rediscovered 2622dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen * @hide 2632dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen */ 2642dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen // TODO See if we need TagLostException 2652dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen // TODO Unhide for ICS 2662dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen // TODO Update documentation to make sure it matches with the final 2672dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen // implementation. 2682dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen public Tag rediscover() throws IOException { 2692dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen if (getConnectedTechnology() != -1) { 2702dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen throw new IllegalStateException("Close connection to the technology first!"); 2712dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen } 2722dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen 27323fc93a7c1e340e79642d3d0bf4b4658c8645c8eMartijn Coenen if (mTagService == null) { 27423fc93a7c1e340e79642d3d0bf4b4658c8645c8eMartijn Coenen throw new IOException("Mock tags don't support this operation."); 27523fc93a7c1e340e79642d3d0bf4b4658c8645c8eMartijn Coenen } 2762dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen try { 2772dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen Tag newTag = mTagService.rediscover(getServiceHandle()); 2782dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen if (newTag != null) { 2792dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen return newTag; 2802dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen } else { 2812dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen throw new IOException("Failed to rediscover tag"); 2822dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen } 2832dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen } catch (RemoteException e) { 2842dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen throw new IOException("NFC service dead"); 2852dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen } 2862dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen } 2872dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen 2882dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen 2894e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton /** @hide */ 2904e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton public boolean hasTech(int techType) { 2914e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton for (int tech : mTechList) { 2924e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton if (tech == techType) return true; 2934e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton } 2944e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton return false; 2954e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton } 29674fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly 2974e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton /** @hide */ 2984e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton public Bundle getTechExtras(int tech) { 2991253ebc74a8453a88dc47a2b698145098d201681Martijn Coenen int pos = -1; 3001253ebc74a8453a88dc47a2b698145098d201681Martijn Coenen for (int idx = 0; idx < mTechList.length; idx++) { 3011253ebc74a8453a88dc47a2b698145098d201681Martijn Coenen if (mTechList[idx] == tech) { 3021253ebc74a8453a88dc47a2b698145098d201681Martijn Coenen pos = idx; 3031253ebc74a8453a88dc47a2b698145098d201681Martijn Coenen break; 3041253ebc74a8453a88dc47a2b698145098d201681Martijn Coenen } 3051253ebc74a8453a88dc47a2b698145098d201681Martijn Coenen } 3066be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton if (pos < 0) { 3076be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton return null; 3086be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton } 3096be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton 3104e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton return mTechExtras[pos]; 3114e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton } 3126be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton 3134e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton /** @hide */ 3144e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton public INfcTag getTagService() { 3154e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton return mTagService; 31607f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly } 31707f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly 31874fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly /** 31974fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * Human-readable description of the tag, for debugging. 32074fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly */ 32107f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly @Override 32207f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly public String toString() { 3238856c4278d9fd727081083d0f88459a8152d88c0Jeff Hamilton StringBuilder sb = new StringBuilder("TAG: Tech ["); 3248856c4278d9fd727081083d0f88459a8152d88c0Jeff Hamilton String[] techList = getTechList(); 3258856c4278d9fd727081083d0f88459a8152d88c0Jeff Hamilton int length = techList.length; 3268856c4278d9fd727081083d0f88459a8152d88c0Jeff Hamilton for (int i = 0; i < length; i++) { 3278856c4278d9fd727081083d0f88459a8152d88c0Jeff Hamilton sb.append(techList[i]); 3288856c4278d9fd727081083d0f88459a8152d88c0Jeff Hamilton if (i < length - 1) { 3298856c4278d9fd727081083d0f88459a8152d88c0Jeff Hamilton sb.append(", "); 3308856c4278d9fd727081083d0f88459a8152d88c0Jeff Hamilton } 33107f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly } 3328856c4278d9fd727081083d0f88459a8152d88c0Jeff Hamilton sb.append("]"); 33307f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly return sb.toString(); 33407f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly } 33507f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly 33607f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly /*package*/ static byte[] readBytesWithNull(Parcel in) { 33707f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly int len = in.readInt(); 33807f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly byte[] result = null; 339e2e4ea9ea8f5724403e6267d193a740dc7c78785Sylvain Fonteneau if (len >= 0) { 34007f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly result = new byte[len]; 34107f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly in.readByteArray(result); 342590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly } 34307f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly return result; 34407f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly } 34507f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly 34607f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly /*package*/ static void writeBytesWithNull(Parcel out, byte[] b) { 34707f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly if (b == null) { 34807f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly out.writeInt(-1); 34907f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly return; 35007f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly } 35107f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly out.writeInt(b.length); 35207f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly out.writeByteArray(b); 353590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly } 354590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly 355590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly @Override 356590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly public int describeContents() { 357590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly return 0; 358590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly } 359590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly 360590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly @Override 361590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly public void writeToParcel(Parcel dest, int flags) { 362c5a418ecb7681159ae6674a4d91177c6841537b1Sylvain Fonteneau // Null mTagService means this is a mock tag 363c5a418ecb7681159ae6674a4d91177c6841537b1Sylvain Fonteneau int isMock = (mTagService == null)?1:0; 364c5a418ecb7681159ae6674a4d91177c6841537b1Sylvain Fonteneau 36507f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly writeBytesWithNull(dest, mId); 3666be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton dest.writeInt(mTechList.length); 3676be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton dest.writeIntArray(mTechList); 3686be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton dest.writeTypedArray(mTechExtras, 0); 36907f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly dest.writeInt(mServiceHandle); 370c5a418ecb7681159ae6674a4d91177c6841537b1Sylvain Fonteneau dest.writeInt(isMock); 371c5a418ecb7681159ae6674a4d91177c6841537b1Sylvain Fonteneau if (isMock == 0) { 372c5a418ecb7681159ae6674a4d91177c6841537b1Sylvain Fonteneau dest.writeStrongBinder(mTagService.asBinder()); 373c5a418ecb7681159ae6674a4d91177c6841537b1Sylvain Fonteneau } 374590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly } 375590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly 376590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly public static final Parcelable.Creator<Tag> CREATOR = 377590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly new Parcelable.Creator<Tag>() { 3786be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton @Override 379590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly public Tag createFromParcel(Parcel in) { 380c5a418ecb7681159ae6674a4d91177c6841537b1Sylvain Fonteneau INfcTag tagService; 381c5a418ecb7681159ae6674a4d91177c6841537b1Sylvain Fonteneau 38207f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly // Tag fields 38307f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly byte[] id = Tag.readBytesWithNull(in); 3846be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton int[] techList = new int[in.readInt()]; 3856be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton in.readIntArray(techList); 3866be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton Bundle[] techExtras = in.createTypedArray(Bundle.CREATOR); 38707f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly int serviceHandle = in.readInt(); 388c5a418ecb7681159ae6674a4d91177c6841537b1Sylvain Fonteneau int isMock = in.readInt(); 389c5a418ecb7681159ae6674a4d91177c6841537b1Sylvain Fonteneau if (isMock == 0) { 390c5a418ecb7681159ae6674a4d91177c6841537b1Sylvain Fonteneau tagService = INfcTag.Stub.asInterface(in.readStrongBinder()); 391c5a418ecb7681159ae6674a4d91177c6841537b1Sylvain Fonteneau } 392c5a418ecb7681159ae6674a4d91177c6841537b1Sylvain Fonteneau else { 393c5a418ecb7681159ae6674a4d91177c6841537b1Sylvain Fonteneau tagService = null; 394c5a418ecb7681159ae6674a4d91177c6841537b1Sylvain Fonteneau } 39507f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly 3964e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton return new Tag(id, techList, techExtras, serviceHandle, tagService); 397590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly } 3986be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton 3996be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton @Override 400590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly public Tag[] newArray(int size) { 401590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly return new Tag[size]; 402590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly } 403590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly }; 4044049f9d00a86f848d42d2429068496b31a6795adMartijn Coenen 405be372d6462605010910e771cef15d5adccd0a59eJeff Hamilton /** 406be372d6462605010910e771cef15d5adccd0a59eJeff Hamilton * For internal use only. 407be372d6462605010910e771cef15d5adccd0a59eJeff Hamilton * 4084049f9d00a86f848d42d2429068496b31a6795adMartijn Coenen * @hide 4094049f9d00a86f848d42d2429068496b31a6795adMartijn Coenen */ 4104049f9d00a86f848d42d2429068496b31a6795adMartijn Coenen public synchronized void setConnectedTechnology(int technology) { 4114049f9d00a86f848d42d2429068496b31a6795adMartijn Coenen if (mConnectedTechnology == -1) { 4124049f9d00a86f848d42d2429068496b31a6795adMartijn Coenen mConnectedTechnology = technology; 4134049f9d00a86f848d42d2429068496b31a6795adMartijn Coenen } else { 4144049f9d00a86f848d42d2429068496b31a6795adMartijn Coenen throw new IllegalStateException("Close other technology first!"); 4154049f9d00a86f848d42d2429068496b31a6795adMartijn Coenen } 4164049f9d00a86f848d42d2429068496b31a6795adMartijn Coenen } 4174049f9d00a86f848d42d2429068496b31a6795adMartijn Coenen 418be372d6462605010910e771cef15d5adccd0a59eJeff Hamilton /** 419be372d6462605010910e771cef15d5adccd0a59eJeff Hamilton * For internal use only. 420be372d6462605010910e771cef15d5adccd0a59eJeff Hamilton * 4214049f9d00a86f848d42d2429068496b31a6795adMartijn Coenen * @hide 4224049f9d00a86f848d42d2429068496b31a6795adMartijn Coenen */ 4234049f9d00a86f848d42d2429068496b31a6795adMartijn Coenen public int getConnectedTechnology() { 4244049f9d00a86f848d42d2429068496b31a6795adMartijn Coenen return mConnectedTechnology; 4254049f9d00a86f848d42d2429068496b31a6795adMartijn Coenen } 4264049f9d00a86f848d42d2429068496b31a6795adMartijn Coenen 427be372d6462605010910e771cef15d5adccd0a59eJeff Hamilton /** 428be372d6462605010910e771cef15d5adccd0a59eJeff Hamilton * For internal use only. 429be372d6462605010910e771cef15d5adccd0a59eJeff Hamilton * 4304049f9d00a86f848d42d2429068496b31a6795adMartijn Coenen * @hide 4314049f9d00a86f848d42d2429068496b31a6795adMartijn Coenen */ 4324049f9d00a86f848d42d2429068496b31a6795adMartijn Coenen public void setTechnologyDisconnected() { 4334049f9d00a86f848d42d2429068496b31a6795adMartijn Coenen mConnectedTechnology = -1; 4344049f9d00a86f848d42d2429068496b31a6795adMartijn Coenen } 4351253ebc74a8453a88dc47a2b698145098d201681Martijn Coenen} 436