1590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly/* 29024564107b58955f7bd257cab6fc6dfcb2e5ec2Daniel Tomas * Copyright (C) 2010 The Android Open Source Project 39024564107b58955f7bd257cab6fc6dfcb2e5ec2Daniel Tomas * 49024564107b58955f7bd257cab6fc6dfcb2e5ec2Daniel Tomas * Licensed under the Apache License, Version 2.0 (the "License"); 59024564107b58955f7bd257cab6fc6dfcb2e5ec2Daniel Tomas * you may not use this file except in compliance with the License. 69024564107b58955f7bd257cab6fc6dfcb2e5ec2Daniel Tomas * You may obtain a copy of the License at 79024564107b58955f7bd257cab6fc6dfcb2e5ec2Daniel Tomas * 89024564107b58955f7bd257cab6fc6dfcb2e5ec2Daniel Tomas * http://www.apache.org/licenses/LICENSE-2.0 99024564107b58955f7bd257cab6fc6dfcb2e5ec2Daniel Tomas * 109024564107b58955f7bd257cab6fc6dfcb2e5ec2Daniel Tomas * Unless required by applicable law or agreed to in writing, software 119024564107b58955f7bd257cab6fc6dfcb2e5ec2Daniel Tomas * distributed under the License is distributed on an "AS IS" BASIS, 129024564107b58955f7bd257cab6fc6dfcb2e5ec2Daniel Tomas * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139024564107b58955f7bd257cab6fc6dfcb2e5ec2Daniel Tomas * See the License for the specific language governing permissions and 149024564107b58955f7bd257cab6fc6dfcb2e5ec2Daniel Tomas * limitations under the License. 15590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly */ 16590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly 17590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pellypackage android.nfc; 18590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly 19bb951c893973691554f49d2e725985125f866b27Jeff Hamiltonimport java.util.HashMap; 20bb951c893973691554f49d2e725985125f866b27Jeff Hamilton 21590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pellyimport android.annotation.SdkConstant; 22590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pellyimport android.annotation.SdkConstant.SdkConstantType; 2352d3203ef69d4babbc4dd030a15c08c0b8d1d226Jeff Hamiltonimport android.app.Activity; 24fdf9086e24f4720ee9fbc852b980041f126aa3c2Nick Pellyimport android.app.ActivityThread; 2552d3203ef69d4babbc4dd030a15c08c0b8d1d226Jeff Hamiltonimport android.app.OnActivityPausedListener; 2652d3203ef69d4babbc4dd030a15c08c0b8d1d226Jeff Hamiltonimport android.app.PendingIntent; 2750b4d8f643f31b37e9872f562fb869059cf79c8aNick Pellyimport android.content.Context; 2852d3203ef69d4babbc4dd030a15c08c0b8d1d226Jeff Hamiltonimport android.content.IntentFilter; 29fdf9086e24f4720ee9fbc852b980041f126aa3c2Nick Pellyimport android.content.pm.IPackageManager; 30fdf9086e24f4720ee9fbc852b980041f126aa3c2Nick Pellyimport android.content.pm.PackageManager; 311d7e9062330a5a02247752de32a68ecbeba82783Nick Pellyimport android.net.Uri; 3228319c0cec94977682db32b949628a8e4b8183dcJeff Hamiltonimport android.nfc.tech.MifareClassic; 3328319c0cec94977682db32b949628a8e4b8183dcJeff Hamiltonimport android.nfc.tech.Ndef; 3428319c0cec94977682db32b949628a8e4b8183dcJeff Hamiltonimport android.nfc.tech.NfcA; 3528319c0cec94977682db32b949628a8e4b8183dcJeff Hamiltonimport android.nfc.tech.NfcF; 36590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pellyimport android.os.IBinder; 37590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pellyimport android.os.RemoteException; 38590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pellyimport android.os.ServiceManager; 39590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pellyimport android.util.Log; 40590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly 41590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly/** 4274fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * Represents the local NFC adapter. 43590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * <p> 4450b4d8f643f31b37e9872f562fb869059cf79c8aNick Pelly * Use the helper {@link #getDefaultAdapter(Context)} to get the default NFC 4550b4d8f643f31b37e9872f562fb869059cf79c8aNick Pelly * adapter for this Android device. 463aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * 473aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * <div class="special reference"> 483aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * <h3>Developer Guides</h3> 493aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * <p>For more information about using NFC, read the 503aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * <a href="{@docRoot}guide/topics/nfc/index.html">Near Field Communication</a> developer guide.</p> 513aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * </div> 52590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly */ 53590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pellypublic final class NfcAdapter { 54c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly static final String TAG = "NFC"; 5550b4d8f643f31b37e9872f562fb869059cf79c8aNick Pelly 56590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly /** 57641dd62155fd2eeddd93b2036154b13c05b70ba2Jeff Hamilton * Intent to start an activity when a tag with NDEF payload is discovered. 58641dd62155fd2eeddd93b2036154b13c05b70ba2Jeff Hamilton * 5928319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * <p>The system inspects the first {@link NdefRecord} in the first {@link NdefMessage} and 6028319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * looks for a URI, SmartPoster, or MIME record. If a URI or SmartPoster record is found the 6128319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * intent will contain the URI in its data field. If a MIME record is found the intent will 6228319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * contain the MIME type in its type field. This allows activities to register 6328319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * {@link IntentFilter}s targeting specific content on tags. Activities should register the 6428319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * most specific intent filters possible to avoid the activity chooser dialog, which can 6528319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * disrupt the interaction with the tag as the user interacts with the screen. 6628319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * 6728319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * <p>If the tag has an NDEF payload this intent is started before 6828319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * {@link #ACTION_TECH_DISCOVERED}. If any activities respond to this intent neither 69f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly * {@link #ACTION_TECH_DISCOVERED} or {@link #ACTION_TAG_DISCOVERED} will be started. 70c97a552023c3c71079b39092e80c9b44f25a789bNick Pelly * 71c97a552023c3c71079b39092e80c9b44f25a789bNick Pelly * <p>The MIME type or data URI of this intent are normalized before dispatch - 72c97a552023c3c71079b39092e80c9b44f25a789bNick Pelly * so that MIME, URI scheme and URI host are always lower-case. 73641dd62155fd2eeddd93b2036154b13c05b70ba2Jeff Hamilton */ 74641dd62155fd2eeddd93b2036154b13c05b70ba2Jeff Hamilton @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) 75641dd62155fd2eeddd93b2036154b13c05b70ba2Jeff Hamilton public static final String ACTION_NDEF_DISCOVERED = "android.nfc.action.NDEF_DISCOVERED"; 76641dd62155fd2eeddd93b2036154b13c05b70ba2Jeff Hamilton 77641dd62155fd2eeddd93b2036154b13c05b70ba2Jeff Hamilton /** 7828319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * Intent to start an activity when a tag is discovered and activities are registered for the 7928319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * specific technologies on the tag. 8028319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * 8128319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * <p>To receive this intent an activity must include an intent filter 8228319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * for this action and specify the desired tech types in a 8328319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * manifest <code>meta-data</code> entry. Here is an example manfiest entry: 8428319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * <pre> 8597e0a1c6f3b7ab8f0796931182f0343dd7e73782Scott Main * <activity android:name=".nfc.TechFilter" android:label="NFC/TechFilter"> 8697e0a1c6f3b7ab8f0796931182f0343dd7e73782Scott Main * <!-- Add a technology filter --> 8797e0a1c6f3b7ab8f0796931182f0343dd7e73782Scott Main * <intent-filter> 8897e0a1c6f3b7ab8f0796931182f0343dd7e73782Scott Main * <action android:name="android.nfc.action.TECH_DISCOVERED" /> 8997e0a1c6f3b7ab8f0796931182f0343dd7e73782Scott Main * </intent-filter> 9097e0a1c6f3b7ab8f0796931182f0343dd7e73782Scott Main * 9197e0a1c6f3b7ab8f0796931182f0343dd7e73782Scott Main * <meta-data android:name="android.nfc.action.TECH_DISCOVERED" 9297e0a1c6f3b7ab8f0796931182f0343dd7e73782Scott Main * android:resource="@xml/filter_nfc" 9397e0a1c6f3b7ab8f0796931182f0343dd7e73782Scott Main * /> 9497e0a1c6f3b7ab8f0796931182f0343dd7e73782Scott Main * </activity></pre> 9528319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * 9628319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * <p>The meta-data XML file should contain one or more <code>tech-list</code> entries 9728319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * each consisting or one or more <code>tech</code> entries. The <code>tech</code> entries refer 9828319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * to the qualified class name implementing the technology, for example "android.nfc.tech.NfcA". 99641dd62155fd2eeddd93b2036154b13c05b70ba2Jeff Hamilton * 10028319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * <p>A tag matches if any of the 10128319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * <code>tech-list</code> sets is a subset of {@link Tag#getTechList() Tag.getTechList()}. Each 10228319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * of the <code>tech-list</code>s is considered independently and the 10328319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * activity is considered a match is any single <code>tech-list</code> matches the tag that was 10428319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * discovered. This provides AND and OR semantics for filtering desired techs. Here is an 10528319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * example that will match any tag using {@link NfcF} or any tag using {@link NfcA}, 10628319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * {@link MifareClassic}, and {@link Ndef}: 107641dd62155fd2eeddd93b2036154b13c05b70ba2Jeff Hamilton * 10828319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * <pre> 10928319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> 11028319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * <!-- capture anything using NfcF --> 11128319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * <tech-list> 11228319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * <tech>android.nfc.tech.NfcF</tech> 11328319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * </tech-list> 11428319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * 11528319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * <!-- OR --> 11628319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * 11728319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * <!-- capture all MIFARE Classics with NDEF payloads --> 11828319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * <tech-list> 11928319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * <tech>android.nfc.tech.NfcA</tech> 12028319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * <tech>android.nfc.tech.MifareClassic</tech> 12128319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * <tech>android.nfc.tech.Ndef</tech> 12228319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * </tech-list> 12397e0a1c6f3b7ab8f0796931182f0343dd7e73782Scott Main * </resources></pre> 12428319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * 12528319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * <p>This intent is started after {@link #ACTION_NDEF_DISCOVERED} and before 12628319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * {@link #ACTION_TAG_DISCOVERED}. If any activities respond to {@link #ACTION_NDEF_DISCOVERED} 12728319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * this intent will not be started. If any activities respond to this intent 12828319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * {@link #ACTION_TAG_DISCOVERED} will not be started. 129641dd62155fd2eeddd93b2036154b13c05b70ba2Jeff Hamilton */ 130641dd62155fd2eeddd93b2036154b13c05b70ba2Jeff Hamilton @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) 131f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly public static final String ACTION_TECH_DISCOVERED = "android.nfc.action.TECH_DISCOVERED"; 132641dd62155fd2eeddd93b2036154b13c05b70ba2Jeff Hamilton 133641dd62155fd2eeddd93b2036154b13c05b70ba2Jeff Hamilton /** 13411b075e218b9921a953eeebe73fcd1a8a81f764bNick Pelly * Intent to start an activity when a tag is discovered. 13528319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * 13628319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * <p>This intent will not be started when a tag is discovered if any activities respond to 13701425365a85e605139f612502f68954cad869e5bJason parks * {@link #ACTION_NDEF_DISCOVERED} or {@link #ACTION_TECH_DISCOVERED} for the current tag. 138590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly */ 139590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) 140590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly public static final String ACTION_TAG_DISCOVERED = "android.nfc.action.TAG_DISCOVERED"; 141590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly 142590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly /** 1436be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton * Broadcast to only the activity that handles ACTION_TAG_DISCOVERED 1446be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton * @hide 1456be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton */ 1466be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton public static final String ACTION_TAG_LEFT_FIELD = "android.nfc.action.TAG_LOST"; 1476be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton 1486be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton /** 14928319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * Mandatory extra containing the {@link Tag} that was discovered for the 15028319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * {@link #ACTION_NDEF_DISCOVERED}, {@link #ACTION_TECH_DISCOVERED}, and 15128319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * {@link #ACTION_TAG_DISCOVERED} intents. 152590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly */ 15311b075e218b9921a953eeebe73fcd1a8a81f764bNick Pelly public static final String EXTRA_TAG = "android.nfc.extra.TAG"; 154590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly 155590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly /** 156c97a552023c3c71079b39092e80c9b44f25a789bNick Pelly * Extra containing an array of {@link NdefMessage} present on the discovered tag.<p> 157c97a552023c3c71079b39092e80c9b44f25a789bNick Pelly * This extra is mandatory for {@link #ACTION_NDEF_DISCOVERED} intents, 158c97a552023c3c71079b39092e80c9b44f25a789bNick Pelly * and optional for {@link #ACTION_TECH_DISCOVERED}, and 159c97a552023c3c71079b39092e80c9b44f25a789bNick Pelly * {@link #ACTION_TAG_DISCOVERED} intents.<p> 160c97a552023c3c71079b39092e80c9b44f25a789bNick Pelly * When this extra is present there will always be at least one 161c97a552023c3c71079b39092e80c9b44f25a789bNick Pelly * {@link NdefMessage} element. Most NDEF tags have only one NDEF message, 162c97a552023c3c71079b39092e80c9b44f25a789bNick Pelly * but we use an array for future compatibility. 163590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly */ 16411b075e218b9921a953eeebe73fcd1a8a81f764bNick Pelly public static final String EXTRA_NDEF_MESSAGES = "android.nfc.extra.NDEF_MESSAGES"; 16511b075e218b9921a953eeebe73fcd1a8a81f764bNick Pelly 16611b075e218b9921a953eeebe73fcd1a8a81f764bNick Pelly /** 16728319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * Optional extra containing a byte array containing the ID of the discovered tag for 16828319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * the {@link #ACTION_NDEF_DISCOVERED}, {@link #ACTION_TECH_DISCOVERED}, and 16928319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * {@link #ACTION_TAG_DISCOVERED} intents. 17011b075e218b9921a953eeebe73fcd1a8a81f764bNick Pelly */ 17111b075e218b9921a953eeebe73fcd1a8a81f764bNick Pelly public static final String EXTRA_ID = "android.nfc.extra.ID"; 172590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly 173590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly /** 1748d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly * Broadcast Action: The state of the local NFC adapter has been 1758d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly * changed. 1768d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly * <p>For example, NFC has been turned on or off. 1778d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly * <p>Always contains the extra field {@link #EXTRA_STATE} 178afb082dba5232a45a7563e085f12284f7d5ffc1dBrad Fitzpatrick * @hide 179afb082dba5232a45a7563e085f12284f7d5ffc1dBrad Fitzpatrick */ 1808d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 1818d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly public static final String ACTION_ADAPTER_STATE_CHANGED = 1828d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly "android.nfc.action.ADAPTER_STATE_CHANGED"; 183afb082dba5232a45a7563e085f12284f7d5ffc1dBrad Fitzpatrick 184afb082dba5232a45a7563e085f12284f7d5ffc1dBrad Fitzpatrick /** 1858d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly * Used as an int extra field in {@link #ACTION_STATE_CHANGED} 1868d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly * intents to request the current power state. Possible values are: 1878d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly * {@link #STATE_OFF}, 1888d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly * {@link #STATE_TURNING_ON}, 1898d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly * {@link #STATE_ON}, 1908d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly * {@link #STATE_TURNING_OFF}, 191afb082dba5232a45a7563e085f12284f7d5ffc1dBrad Fitzpatrick * @hide 192afb082dba5232a45a7563e085f12284f7d5ffc1dBrad Fitzpatrick */ 1938d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly public static final String EXTRA_ADAPTER_STATE = "android.nfc.extra.ADAPTER_STATE"; 1948d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly 1958d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly /** @hide */ 1968d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly public static final int STATE_OFF = 1; 1978d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly /** @hide */ 1988d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly public static final int STATE_TURNING_ON = 2; 1998d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly /** @hide */ 2008d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly public static final int STATE_ON = 3; 2018d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly /** @hide */ 2028d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly public static final int STATE_TURNING_OFF = 4; 203afb082dba5232a45a7563e085f12284f7d5ffc1dBrad Fitzpatrick 20420e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen /** @hide */ 20520e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen public static final String ACTION_HANDOVER_TRANSFER_STARTED = 20620e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen "android.nfc.action.HANDOVER_TRANSFER_STARTED"; 20720e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen 20820e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen /** @hide */ 20920e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen public static final String ACTION_HANDOVER_TRANSFER_DONE = 21020e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen "android.nfc.action.HANDOVER_TRANSFER_DONE"; 21120e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen 21220e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen /** @hide */ 21320e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen public static final String EXTRA_HANDOVER_TRANSFER_STATUS = 21420e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen "android.nfc.extra.HANDOVER_TRANSFER_STATUS"; 21520e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen 21620e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen /** @hide */ 21720e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen public static final int HANDOVER_TRANSFER_STATUS_SUCCESS = 0; 21820e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen /** @hide */ 21920e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen public static final int HANDOVER_TRANSFER_STATUS_FAILURE = 1; 22020e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen 22120e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen /** @hide */ 22220e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen public static final String EXTRA_HANDOVER_TRANSFER_URI = 22320e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen "android.nfc.extra.HANDOVER_TRANSFER_URI"; 22420e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen 225c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly // Guarded by NfcAdapter.class 226c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly static boolean sIsInitialized = false; 227590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly 228c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly // Final after first constructor, except for 229c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly // attemptDeadServiceRecovery() when NFC crashes - we accept a best effort 230c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly // recovery 231c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly static INfcAdapter sService; 232c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly static INfcTag sTagService; 233590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly 234590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly /** 235bb951c893973691554f49d2e725985125f866b27Jeff Hamilton * The NfcAdapter object for each application context. 236bb951c893973691554f49d2e725985125f866b27Jeff Hamilton * There is a 1-1 relationship between application context and 237bb951c893973691554f49d2e725985125f866b27Jeff Hamilton * NfcAdapter object. 238bb951c893973691554f49d2e725985125f866b27Jeff Hamilton */ 239bb951c893973691554f49d2e725985125f866b27Jeff Hamilton static HashMap<Context, NfcAdapter> sNfcAdapters = new HashMap(); //guard by NfcAdapter.class 240bb951c893973691554f49d2e725985125f866b27Jeff Hamilton 241bb951c893973691554f49d2e725985125f866b27Jeff Hamilton /** 242bb951c893973691554f49d2e725985125f866b27Jeff Hamilton * NfcAdapter used with a null context. This ctor was deprecated but we have 243bb951c893973691554f49d2e725985125f866b27Jeff Hamilton * to support it for backwards compatibility. New methods that require context 244bb951c893973691554f49d2e725985125f866b27Jeff Hamilton * might throw when called on the null-context NfcAdapter. 245590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly */ 246bb951c893973691554f49d2e725985125f866b27Jeff Hamilton static NfcAdapter sNullContextNfcAdapter; // protected by NfcAdapter.class 247590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly 248c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly final NfcActivityManager mNfcActivityManager; 249bb951c893973691554f49d2e725985125f866b27Jeff Hamilton final Context mContext; 250590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly 251590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly /** 2522d68a6ba3c1354f363e5ee77448f163664bf47d9Scott Main * A callback to be invoked when the system successfully delivers your {@link NdefMessage} 2532d68a6ba3c1354f363e5ee77448f163664bf47d9Scott Main * to another device. 2542d68a6ba3c1354f363e5ee77448f163664bf47d9Scott Main * @see #setOnNdefPushCompleteCallback 255590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly */ 256c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly public interface OnNdefPushCompleteCallback { 257c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly /** 258c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * Called on successful NDEF push. 259c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * 260c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * <p>This callback is usually made on a binder thread (not the UI thread). 261c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * 262c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * @param event {@link NfcEvent} with the {@link NfcEvent#nfcAdapter} field set 2632d68a6ba3c1354f363e5ee77448f163664bf47d9Scott Main * @see #setNdefPushMessageCallback 264c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly */ 265c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly public void onNdefPushComplete(NfcEvent event); 266c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly } 267590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly 26801425365a85e605139f612502f68954cad869e5bJason parks /** 2692d68a6ba3c1354f363e5ee77448f163664bf47d9Scott Main * A callback to be invoked when another NFC device capable of NDEF push (Android Beam) 2702d68a6ba3c1354f363e5ee77448f163664bf47d9Scott Main * is within range. 2712d68a6ba3c1354f363e5ee77448f163664bf47d9Scott Main * <p>Implement this interface and pass it to {@link 2722d68a6ba3c1354f363e5ee77448f163664bf47d9Scott Main * NfcAdapter#setNdefPushMessageCallback setNdefPushMessageCallback()} in order to create an 2732d68a6ba3c1354f363e5ee77448f163664bf47d9Scott Main * {@link NdefMessage} at the moment that another device is within range for NFC. Using this 2742d68a6ba3c1354f363e5ee77448f163664bf47d9Scott Main * callback allows you to create a message with data that might vary based on the 2752d68a6ba3c1354f363e5ee77448f163664bf47d9Scott Main * content currently visible to the user. Alternatively, you can call {@link 2762d68a6ba3c1354f363e5ee77448f163664bf47d9Scott Main * #setNdefPushMessage setNdefPushMessage()} if the {@link NdefMessage} always contains the 2772d68a6ba3c1354f363e5ee77448f163664bf47d9Scott Main * same data. 27801425365a85e605139f612502f68954cad869e5bJason parks */ 279c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly public interface CreateNdefMessageCallback { 28001425365a85e605139f612502f68954cad869e5bJason parks /** 281c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * Called to provide a {@link NdefMessage} to push. 282c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * 283c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * <p>This callback is usually made on a binder thread (not the UI thread). 284c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * 285c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * <p>Called when this device is in range of another device 286c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * that might support NDEF push. It allows the application to 287c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * create the NDEF message only when it is required. 288c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * 289c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * <p>NDEF push cannot occur until this method returns, so do not 290c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * block for too long. 291c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * 292c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * <p>The Android operating system will usually show a system UI 293c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * on top of your activity during this time, so do not try to request 294c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * input from the user to complete the callback, or provide custom NDEF 295c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * push UI. The user probably will not see it. 296c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * 297c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * @param event {@link NfcEvent} with the {@link NfcEvent#nfcAdapter} field set 298c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * @return NDEF message to push, or null to not provide a message 29901425365a85e605139f612502f68954cad869e5bJason parks */ 300c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly public NdefMessage createNdefMessage(NfcEvent event); 30101425365a85e605139f612502f68954cad869e5bJason parks } 30201425365a85e605139f612502f68954cad869e5bJason parks 30320e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen 30420e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen // TODO javadoc 30520e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen public interface CreateBeamUrisCallback { 30620e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen public Uri[] createBeamUris(NfcEvent event); 30720e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen } 30820e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen 309590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly /** 310fdf9086e24f4720ee9fbc852b980041f126aa3c2Nick Pelly * Helper to check if this device has FEATURE_NFC, but without using 311fdf9086e24f4720ee9fbc852b980041f126aa3c2Nick Pelly * a context. 312fdf9086e24f4720ee9fbc852b980041f126aa3c2Nick Pelly * Equivalent to 313fdf9086e24f4720ee9fbc852b980041f126aa3c2Nick Pelly * context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_NFC) 314fdf9086e24f4720ee9fbc852b980041f126aa3c2Nick Pelly */ 315fdf9086e24f4720ee9fbc852b980041f126aa3c2Nick Pelly private static boolean hasNfcFeature() { 316fdf9086e24f4720ee9fbc852b980041f126aa3c2Nick Pelly IPackageManager pm = ActivityThread.getPackageManager(); 317fdf9086e24f4720ee9fbc852b980041f126aa3c2Nick Pelly if (pm == null) { 318fdf9086e24f4720ee9fbc852b980041f126aa3c2Nick Pelly Log.e(TAG, "Cannot get package manager, assuming no NFC feature"); 319fdf9086e24f4720ee9fbc852b980041f126aa3c2Nick Pelly return false; 320fdf9086e24f4720ee9fbc852b980041f126aa3c2Nick Pelly } 321fdf9086e24f4720ee9fbc852b980041f126aa3c2Nick Pelly try { 322fdf9086e24f4720ee9fbc852b980041f126aa3c2Nick Pelly return pm.hasSystemFeature(PackageManager.FEATURE_NFC); 323fdf9086e24f4720ee9fbc852b980041f126aa3c2Nick Pelly } catch (RemoteException e) { 324fdf9086e24f4720ee9fbc852b980041f126aa3c2Nick Pelly Log.e(TAG, "Package manager query failed, assuming no NFC feature", e); 325fdf9086e24f4720ee9fbc852b980041f126aa3c2Nick Pelly return false; 326fdf9086e24f4720ee9fbc852b980041f126aa3c2Nick Pelly } 327fdf9086e24f4720ee9fbc852b980041f126aa3c2Nick Pelly } 328fdf9086e24f4720ee9fbc852b980041f126aa3c2Nick Pelly 329c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly /** 330bb951c893973691554f49d2e725985125f866b27Jeff Hamilton * Returns the NfcAdapter for application context, 331bb951c893973691554f49d2e725985125f866b27Jeff Hamilton * or throws if NFC is not available. 332bb951c893973691554f49d2e725985125f866b27Jeff Hamilton * @hide 333c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly */ 334bb951c893973691554f49d2e725985125f866b27Jeff Hamilton public static synchronized NfcAdapter getNfcAdapter(Context context) { 33550b4d8f643f31b37e9872f562fb869059cf79c8aNick Pelly if (!sIsInitialized) { 33650b4d8f643f31b37e9872f562fb869059cf79c8aNick Pelly /* is this device meant to have NFC */ 33750b4d8f643f31b37e9872f562fb869059cf79c8aNick Pelly if (!hasNfcFeature()) { 33850b4d8f643f31b37e9872f562fb869059cf79c8aNick Pelly Log.v(TAG, "this device does not have NFC support"); 339c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly throw new UnsupportedOperationException(); 34050b4d8f643f31b37e9872f562fb869059cf79c8aNick Pelly } 34150b4d8f643f31b37e9872f562fb869059cf79c8aNick Pelly 34250b4d8f643f31b37e9872f562fb869059cf79c8aNick Pelly sService = getServiceInterface(); 34350b4d8f643f31b37e9872f562fb869059cf79c8aNick Pelly if (sService == null) { 34450b4d8f643f31b37e9872f562fb869059cf79c8aNick Pelly Log.e(TAG, "could not retrieve NFC service"); 345c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly throw new UnsupportedOperationException(); 34650b4d8f643f31b37e9872f562fb869059cf79c8aNick Pelly } 3473dd6c458530476eccb33bc05c9c9cd83823bcf8dNick Pelly try { 3483dd6c458530476eccb33bc05c9c9cd83823bcf8dNick Pelly sTagService = sService.getNfcTagInterface(); 3493dd6c458530476eccb33bc05c9c9cd83823bcf8dNick Pelly } catch (RemoteException e) { 3503dd6c458530476eccb33bc05c9c9cd83823bcf8dNick Pelly Log.e(TAG, "could not retrieve NFC Tag service"); 351c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly throw new UnsupportedOperationException(); 3523dd6c458530476eccb33bc05c9c9cd83823bcf8dNick Pelly } 353bb951c893973691554f49d2e725985125f866b27Jeff Hamilton 354bb951c893973691554f49d2e725985125f866b27Jeff Hamilton sIsInitialized = true; 355bb951c893973691554f49d2e725985125f866b27Jeff Hamilton } 356bb951c893973691554f49d2e725985125f866b27Jeff Hamilton if (context == null) { 357bb951c893973691554f49d2e725985125f866b27Jeff Hamilton if (sNullContextNfcAdapter == null) { 358bb951c893973691554f49d2e725985125f866b27Jeff Hamilton sNullContextNfcAdapter = new NfcAdapter(null); 359bb951c893973691554f49d2e725985125f866b27Jeff Hamilton } 360bb951c893973691554f49d2e725985125f866b27Jeff Hamilton return sNullContextNfcAdapter; 36150b4d8f643f31b37e9872f562fb869059cf79c8aNick Pelly } 362bb951c893973691554f49d2e725985125f866b27Jeff Hamilton NfcAdapter adapter = sNfcAdapters.get(context); 363bb951c893973691554f49d2e725985125f866b27Jeff Hamilton if (adapter == null) { 364bb951c893973691554f49d2e725985125f866b27Jeff Hamilton adapter = new NfcAdapter(context); 365bb951c893973691554f49d2e725985125f866b27Jeff Hamilton sNfcAdapters.put(context, adapter); 366c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly } 367bb951c893973691554f49d2e725985125f866b27Jeff Hamilton return adapter; 36850b4d8f643f31b37e9872f562fb869059cf79c8aNick Pelly } 36950b4d8f643f31b37e9872f562fb869059cf79c8aNick Pelly 3706d55e1342fc35c26dd97700ae791b34668266018Nick Pelly /** get handle to NFC service interface */ 37150b4d8f643f31b37e9872f562fb869059cf79c8aNick Pelly private static INfcAdapter getServiceInterface() { 3726d55e1342fc35c26dd97700ae791b34668266018Nick Pelly /* get a handle to NFC service */ 3736d55e1342fc35c26dd97700ae791b34668266018Nick Pelly IBinder b = ServiceManager.getService("nfc"); 3746d55e1342fc35c26dd97700ae791b34668266018Nick Pelly if (b == null) { 3756d55e1342fc35c26dd97700ae791b34668266018Nick Pelly return null; 3766d55e1342fc35c26dd97700ae791b34668266018Nick Pelly } 3776d55e1342fc35c26dd97700ae791b34668266018Nick Pelly return INfcAdapter.Stub.asInterface(b); 3786d55e1342fc35c26dd97700ae791b34668266018Nick Pelly } 3796d55e1342fc35c26dd97700ae791b34668266018Nick Pelly 380fdf9086e24f4720ee9fbc852b980041f126aa3c2Nick Pelly /** 38150b4d8f643f31b37e9872f562fb869059cf79c8aNick Pelly * Helper to get the default NFC Adapter. 38250b4d8f643f31b37e9872f562fb869059cf79c8aNick Pelly * <p> 38350b4d8f643f31b37e9872f562fb869059cf79c8aNick Pelly * Most Android devices will only have one NFC Adapter (NFC Controller). 38450b4d8f643f31b37e9872f562fb869059cf79c8aNick Pelly * <p> 38550b4d8f643f31b37e9872f562fb869059cf79c8aNick Pelly * This helper is the equivalent of: 38697e0a1c6f3b7ab8f0796931182f0343dd7e73782Scott Main * <pre> 38750b4d8f643f31b37e9872f562fb869059cf79c8aNick Pelly * NfcManager manager = (NfcManager) context.getSystemService(Context.NFC_SERVICE); 38897e0a1c6f3b7ab8f0796931182f0343dd7e73782Scott Main * NfcAdapter adapter = manager.getDefaultAdapter();</pre> 38950b4d8f643f31b37e9872f562fb869059cf79c8aNick Pelly * @param context the calling application's context 39050b4d8f643f31b37e9872f562fb869059cf79c8aNick Pelly * 39150b4d8f643f31b37e9872f562fb869059cf79c8aNick Pelly * @return the default NFC adapter, or null if no NFC adapter exists 39250b4d8f643f31b37e9872f562fb869059cf79c8aNick Pelly */ 39350b4d8f643f31b37e9872f562fb869059cf79c8aNick Pelly public static NfcAdapter getDefaultAdapter(Context context) { 394bb951c893973691554f49d2e725985125f866b27Jeff Hamilton if (context == null) { 395bb951c893973691554f49d2e725985125f866b27Jeff Hamilton throw new IllegalArgumentException("context cannot be null"); 396bb951c893973691554f49d2e725985125f866b27Jeff Hamilton } 397bb951c893973691554f49d2e725985125f866b27Jeff Hamilton context = context.getApplicationContext(); 398b04cce0eb5917db436b7db39eb67c064df2e015aNick Pelly if (context == null) { 399b04cce0eb5917db436b7db39eb67c064df2e015aNick Pelly throw new IllegalArgumentException( 400b04cce0eb5917db436b7db39eb67c064df2e015aNick Pelly "context not associated with any application (using a mock context?)"); 401b04cce0eb5917db436b7db39eb67c064df2e015aNick Pelly } 402b04cce0eb5917db436b7db39eb67c064df2e015aNick Pelly /* use getSystemService() for consistency */ 40350b4d8f643f31b37e9872f562fb869059cf79c8aNick Pelly NfcManager manager = (NfcManager) context.getSystemService(Context.NFC_SERVICE); 404a5193b24c1c944331f329eca1d4f85df3a024b1dNick Pelly if (manager == null) { 405a5193b24c1c944331f329eca1d4f85df3a024b1dNick Pelly // NFC not available 406a5193b24c1c944331f329eca1d4f85df3a024b1dNick Pelly return null; 407a5193b24c1c944331f329eca1d4f85df3a024b1dNick Pelly } 40850b4d8f643f31b37e9872f562fb869059cf79c8aNick Pelly return manager.getDefaultAdapter(); 40950b4d8f643f31b37e9872f562fb869059cf79c8aNick Pelly } 41050b4d8f643f31b37e9872f562fb869059cf79c8aNick Pelly 41150b4d8f643f31b37e9872f562fb869059cf79c8aNick Pelly /** 412bb951c893973691554f49d2e725985125f866b27Jeff Hamilton * Legacy NfcAdapter getter, always use {@link #getDefaultAdapter(Context)} instead.<p> 413bb951c893973691554f49d2e725985125f866b27Jeff Hamilton * This method was deprecated at API level 10 (Gingerbread MR1) because a context is required 414bb951c893973691554f49d2e725985125f866b27Jeff Hamilton * for many NFC API methods. Those methods will fail when called on an NfcAdapter 415bb951c893973691554f49d2e725985125f866b27Jeff Hamilton * object created from this method.<p> 41650b4d8f643f31b37e9872f562fb869059cf79c8aNick Pelly * @deprecated use {@link #getDefaultAdapter(Context)} 417a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * @hide 418590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly */ 41950b4d8f643f31b37e9872f562fb869059cf79c8aNick Pelly @Deprecated 420590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly public static NfcAdapter getDefaultAdapter() { 421c97a552023c3c71079b39092e80c9b44f25a789bNick Pelly // introduced in API version 9 (GB 2.3) 422a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly // deprecated in API version 10 (GB 2.3.3) 423a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly // removed from public API in version 16 (ICS MR2) 424c97a552023c3c71079b39092e80c9b44f25a789bNick Pelly // should maintain as a hidden API for binary compatibility for a little longer 42550b4d8f643f31b37e9872f562fb869059cf79c8aNick Pelly Log.w(TAG, "WARNING: NfcAdapter.getDefaultAdapter() is deprecated, use " + 42650b4d8f643f31b37e9872f562fb869059cf79c8aNick Pelly "NfcAdapter.getDefaultAdapter(Context) instead", new Exception()); 427bb951c893973691554f49d2e725985125f866b27Jeff Hamilton 428bb951c893973691554f49d2e725985125f866b27Jeff Hamilton return NfcAdapter.getNfcAdapter(null); 429bb951c893973691554f49d2e725985125f866b27Jeff Hamilton } 430bb951c893973691554f49d2e725985125f866b27Jeff Hamilton 431bb951c893973691554f49d2e725985125f866b27Jeff Hamilton NfcAdapter(Context context) { 432bb951c893973691554f49d2e725985125f866b27Jeff Hamilton mContext = context; 433bb951c893973691554f49d2e725985125f866b27Jeff Hamilton mNfcActivityManager = new NfcActivityManager(this); 43450b4d8f643f31b37e9872f562fb869059cf79c8aNick Pelly } 435590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly 436c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly /** 437bb951c893973691554f49d2e725985125f866b27Jeff Hamilton * @hide 438c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly */ 439bb951c893973691554f49d2e725985125f866b27Jeff Hamilton public Context getContext() { 440bb951c893973691554f49d2e725985125f866b27Jeff Hamilton return mContext; 44150b4d8f643f31b37e9872f562fb869059cf79c8aNick Pelly } 44250b4d8f643f31b37e9872f562fb869059cf79c8aNick Pelly 44350b4d8f643f31b37e9872f562fb869059cf79c8aNick Pelly /** 44450b4d8f643f31b37e9872f562fb869059cf79c8aNick Pelly * Returns the binder interface to the service. 44550b4d8f643f31b37e9872f562fb869059cf79c8aNick Pelly * @hide 44650b4d8f643f31b37e9872f562fb869059cf79c8aNick Pelly */ 44750b4d8f643f31b37e9872f562fb869059cf79c8aNick Pelly public INfcAdapter getService() { 448253c509cb0d36b39c3d878c0caf7f1eca194068aNick Pelly isEnabled(); // NOP call to recover sService if it is stale 44950b4d8f643f31b37e9872f562fb869059cf79c8aNick Pelly return sService; 450590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly } 451590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly 4526be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton /** 4533dd6c458530476eccb33bc05c9c9cd83823bcf8dNick Pelly * Returns the binder interface to the tag service. 4543dd6c458530476eccb33bc05c9c9cd83823bcf8dNick Pelly * @hide 4553dd6c458530476eccb33bc05c9c9cd83823bcf8dNick Pelly */ 4563dd6c458530476eccb33bc05c9c9cd83823bcf8dNick Pelly public INfcTag getTagService() { 457253c509cb0d36b39c3d878c0caf7f1eca194068aNick Pelly isEnabled(); // NOP call to recover sTagService if it is stale 4583dd6c458530476eccb33bc05c9c9cd83823bcf8dNick Pelly return sTagService; 4593dd6c458530476eccb33bc05c9c9cd83823bcf8dNick Pelly } 4603dd6c458530476eccb33bc05c9c9cd83823bcf8dNick Pelly 4613dd6c458530476eccb33bc05c9c9cd83823bcf8dNick Pelly /** 4626be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton * NFC service dead - attempt best effort recovery 4636be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton * @hide 4646be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton */ 4656be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton public void attemptDeadServiceRecovery(Exception e) { 4666d55e1342fc35c26dd97700ae791b34668266018Nick Pelly Log.e(TAG, "NFC service dead - attempting to recover", e); 4676d55e1342fc35c26dd97700ae791b34668266018Nick Pelly INfcAdapter service = getServiceInterface(); 4686d55e1342fc35c26dd97700ae791b34668266018Nick Pelly if (service == null) { 4696d55e1342fc35c26dd97700ae791b34668266018Nick Pelly Log.e(TAG, "could not retrieve NFC service during service recovery"); 4703dd6c458530476eccb33bc05c9c9cd83823bcf8dNick Pelly // nothing more can be done now, sService is still stale, we'll hit 4713dd6c458530476eccb33bc05c9c9cd83823bcf8dNick Pelly // this recovery path again later 4726d55e1342fc35c26dd97700ae791b34668266018Nick Pelly return; 4736d55e1342fc35c26dd97700ae791b34668266018Nick Pelly } 4743dd6c458530476eccb33bc05c9c9cd83823bcf8dNick Pelly // assigning to sService is not thread-safe, but this is best-effort code 4753dd6c458530476eccb33bc05c9c9cd83823bcf8dNick Pelly // and on a well-behaved system should never happen 47650b4d8f643f31b37e9872f562fb869059cf79c8aNick Pelly sService = service; 4773dd6c458530476eccb33bc05c9c9cd83823bcf8dNick Pelly try { 4783dd6c458530476eccb33bc05c9c9cd83823bcf8dNick Pelly sTagService = service.getNfcTagInterface(); 4793dd6c458530476eccb33bc05c9c9cd83823bcf8dNick Pelly } catch (RemoteException ee) { 4803dd6c458530476eccb33bc05c9c9cd83823bcf8dNick Pelly Log.e(TAG, "could not retrieve NFC tag service during service recovery"); 4813dd6c458530476eccb33bc05c9c9cd83823bcf8dNick Pelly // nothing more can be done now, sService is still stale, we'll hit 4823dd6c458530476eccb33bc05c9c9cd83823bcf8dNick Pelly // this recovery path again later 4833dd6c458530476eccb33bc05c9c9cd83823bcf8dNick Pelly } 4843dd6c458530476eccb33bc05c9c9cd83823bcf8dNick Pelly 4856d55e1342fc35c26dd97700ae791b34668266018Nick Pelly return; 4866d55e1342fc35c26dd97700ae791b34668266018Nick Pelly } 4876d55e1342fc35c26dd97700ae791b34668266018Nick Pelly 488590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly /** 4897ea5c45e8d89f59065f088d4e11cceeeed9d64d1Nick Pelly * Return true if this NFC Adapter has any features enabled. 490590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * 49174fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <p>If this method returns false, the NFC hardware is guaranteed not to 492cccf01d3e270bbf53ae6601698109ac4ef461076Nick Pelly * generate or respond to any NFC communication over its NFC radio. 493cccf01d3e270bbf53ae6601698109ac4ef461076Nick Pelly * <p>Applications can use this to check if NFC is enabled. Applications 494cccf01d3e270bbf53ae6601698109ac4ef461076Nick Pelly * can request Settings UI allowing the user to toggle NFC using: 495cccf01d3e270bbf53ae6601698109ac4ef461076Nick Pelly * <p><pre>startActivity(new Intent(Settings.ACTION_NFC_SETTINGS))</pre> 49674fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * 497cccf01d3e270bbf53ae6601698109ac4ef461076Nick Pelly * @see android.provider.Settings#ACTION_NFC_SETTINGS 49874fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * @return true if this NFC Adapter has any features enabled 499590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly */ 5007ea5c45e8d89f59065f088d4e11cceeeed9d64d1Nick Pelly public boolean isEnabled() { 501590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly try { 5028d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly return sService.getState() == STATE_ON; 503590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly } catch (RemoteException e) { 5046d55e1342fc35c26dd97700ae791b34668266018Nick Pelly attemptDeadServiceRecovery(e); 505590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly return false; 506590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly } 507590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly } 508590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly 509590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly /** 5108d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly * Return the state of this NFC Adapter. 5118d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly * 5128d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly * <p>Returns one of {@link #STATE_ON}, {@link #STATE_TURNING_ON}, 5138d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly * {@link #STATE_OFF}, {@link #STATE_TURNING_OFF}. 5148d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly * 5158d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly * <p>{@link #isEnabled()} is equivalent to 5168d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly * <code>{@link #getAdapterState()} == {@link #STATE_ON}</code> 5178d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly * 5188d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly * @return the current state of this NFC adapter 5198d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly * 5208d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly * @hide 5218d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly */ 5228d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly public int getAdapterState() { 5238d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly try { 5248d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly return sService.getState(); 5258d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly } catch (RemoteException e) { 5268d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly attemptDeadServiceRecovery(e); 5278d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly return NfcAdapter.STATE_OFF; 5288d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly } 5298d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly } 5308d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly 5318d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly /** 5327ea5c45e8d89f59065f088d4e11cceeeed9d64d1Nick Pelly * Enable NFC hardware. 5338d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly * 5348d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly * <p>This call is asynchronous. Listen for 5358d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly * {@link #ACTION_ADAPTER_STATE_CHANGED} broadcasts to find out when the 5368d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly * operation is complete. 5378d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly * 5388d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly * <p>If this returns true, then either NFC is already on, or 5398d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly * a {@link #ACTION_ADAPTER_STATE_CHANGED} broadcast will be sent 5408d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly * to indicate a state transition. If this returns false, then 5418d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly * there is some problem that prevents an attempt to turn 5428d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly * NFC on (for example we are in airplane mode and NFC is not 5438d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly * toggleable in airplane mode on this platform). 544afb082dba5232a45a7563e085f12284f7d5ffc1dBrad Fitzpatrick * 545590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * @hide 546590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly */ 5477ea5c45e8d89f59065f088d4e11cceeeed9d64d1Nick Pelly public boolean enable() { 548590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly try { 54950b4d8f643f31b37e9872f562fb869059cf79c8aNick Pelly return sService.enable(); 550590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly } catch (RemoteException e) { 5516d55e1342fc35c26dd97700ae791b34668266018Nick Pelly attemptDeadServiceRecovery(e); 552590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly return false; 553590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly } 554590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly } 555590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly 556590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly /** 5577ea5c45e8d89f59065f088d4e11cceeeed9d64d1Nick Pelly * Disable NFC hardware. 5588d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly * 5598d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly * <p>No NFC features will work after this call, and the hardware 5607ea5c45e8d89f59065f088d4e11cceeeed9d64d1Nick Pelly * will not perform or respond to any NFC communication. 5618d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly * 5628d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly * <p>This call is asynchronous. Listen for 5638d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly * {@link #ACTION_ADAPTER_STATE_CHANGED} broadcasts to find out when the 5648d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly * operation is complete. 5658d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly * 5668d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly * <p>If this returns true, then either NFC is already off, or 5678d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly * a {@link #ACTION_ADAPTER_STATE_CHANGED} broadcast will be sent 5688d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly * to indicate a state transition. If this returns false, then 5698d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly * there is some problem that prevents an attempt to turn 5708d32a01bd24b8a0d1a98f0581b3394a78fab8242Nick Pelly * NFC off. 571afb082dba5232a45a7563e085f12284f7d5ffc1dBrad Fitzpatrick * 572590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * @hide 573590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly */ 5743bba8d0457408421a6468f03bbb36e9ff32b81cfSunil Jogi 5757ea5c45e8d89f59065f088d4e11cceeeed9d64d1Nick Pelly public boolean disable() { 576590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly try { 5773bba8d0457408421a6468f03bbb36e9ff32b81cfSunil Jogi return sService.disable(true); 578590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly } catch (RemoteException e) { 5796d55e1342fc35c26dd97700ae791b34668266018Nick Pelly attemptDeadServiceRecovery(e); 580590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly return false; 581590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly } 582590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly } 5831d7e9062330a5a02247752de32a68ecbeba82783Nick Pelly 5842c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen /** 5852c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * Set one or more {@link Uri}s to send using Android Beam (TM). Every 5862c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * Uri you provide must have either scheme 'file' or scheme 'content'. 5872c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * 5882c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * <p>For the data provided through this method, Android Beam tries to 5892c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * switch to alternate transports such as Bluetooth to achieve a fast 5902c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * transfer speed. Hence this method is very suitable 5912c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * for transferring large files such as pictures or songs. 5922c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * 5932c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * <p>The receiving side will store the content of each Uri in 5942c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * a file and present a notification to the user to open the file 5952c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * with a {@link android.content.Intent} with action 5962c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * {@link android.content.Intent#ACTION_VIEW}. 5972c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * If multiple URIs are sent, the {@link android.content.Intent} will refer 5982c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * to the first of the stored files. 5992c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * 6002c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * <p>This method may be called at any time before {@link Activity#onDestroy}, 6012c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * but the URI(s) are only made available for Android Beam when the 6022c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * specified activity(s) are in resumed (foreground) state. The recommended 6032c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * approach is to call this method during your Activity's 6042c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * {@link Activity#onCreate} - see sample 6052c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * code below. This method does not immediately perform any I/O or blocking work, 6062c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * so is safe to call on your main thread. 6072c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * 6082c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * <p>{@link #setBeamPushUris} and {@link #setBeamPushUrisCallback} 6092c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * have priority over both {@link #setNdefPushMessage} and 6102c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * {@link #setNdefPushMessageCallback}. 6112c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * 6122c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * <p>If {@link #setBeamPushUris} is called with a null Uri array, 6132c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * and/or {@link #setBeamPushUrisCallback} is called with a null callback, 6142c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * then the Uri push will be completely disabled for the specified activity(s). 6152c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * 6162c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * <p>Code example: 6172c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * <pre> 6182c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * protected void onCreate(Bundle savedInstanceState) { 6192c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * super.onCreate(savedInstanceState); 6202c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this); 6212c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * if (nfcAdapter == null) return; // NFC not available on this device 6222c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * nfcAdapter.setBeamPushUris(new Uri[] {uri1, uri2}, this); 62397e0a1c6f3b7ab8f0796931182f0343dd7e73782Scott Main * }</pre> 6242c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * And that is it. Only one call per activity is necessary. The Android 6252c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * OS will automatically release its references to the Uri(s) and the 6262c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * Activity object when it is destroyed if you follow this pattern. 6272c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * 6282c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * <p>If your Activity wants to dynamically supply Uri(s), 6292c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * then set a callback using {@link #setBeamPushUrisCallback} instead 6302c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * of using this method. 6312c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * 6322c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * <p class="note">Do not pass in an Activity that has already been through 6332c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * {@link Activity#onDestroy}. This is guaranteed if you call this API 6342c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * during {@link Activity#onCreate}. 6352c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * 6363b6ecf0ec1a6822577450908f46496cbe121202eMartijn Coenen * <p class="note">If this device does not support alternate transports 6373b6ecf0ec1a6822577450908f46496cbe121202eMartijn Coenen * such as Bluetooth or WiFI, calling this method does nothing. 6383b6ecf0ec1a6822577450908f46496cbe121202eMartijn Coenen * 6392c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission. 6402c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * 6412c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * @param uris an array of Uri(s) to push over Android Beam 6422c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * @param activity activity for which the Uri(s) will be pushed 6432c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen */ 64420e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen public void setBeamPushUris(Uri[] uris, Activity activity) { 64520e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen if (activity == null) { 64620e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen throw new NullPointerException("activity cannot be null"); 64720e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen } 6482c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen if (uris != null) { 6492c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen for (Uri uri : uris) { 6502c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen if (uri == null) throw new NullPointerException("Uri not " + 6512c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen "allowed to be null"); 6522c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen String scheme = uri.getScheme(); 6532c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen if (scheme == null || (!scheme.equalsIgnoreCase("file") && 6542c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen !scheme.equalsIgnoreCase("content"))) { 6552c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen throw new IllegalArgumentException("URI needs to have " + 6562c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen "either scheme file or scheme content"); 6572c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen } 6582c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen } 6592c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen } 66020e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen mNfcActivityManager.setNdefPushContentUri(activity, uris); 66120e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen } 66220e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen 6632c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen /** 6642c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * Set a callback that will dynamically generate one or more {@link Uri}s 6652c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * to send using Android Beam (TM). Every Uri the callback provides 6662c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * must have either scheme 'file' or scheme 'content'. 6672c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * 6682c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * <p>For the data provided through this callback, Android Beam tries to 6692c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * switch to alternate transports such as Bluetooth to achieve a fast 6702c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * transfer speed. Hence this method is very suitable 6712c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * for transferring large files such as pictures or songs. 6722c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * 6732c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * <p>The receiving side will store the content of each Uri in 6742c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * a file and present a notification to the user to open the file 6752c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * with a {@link android.content.Intent} with action 6762c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * {@link android.content.Intent#ACTION_VIEW}. 6772c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * If multiple URIs are sent, the {@link android.content.Intent} will refer 6782c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * to the first of the stored files. 6792c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * 6802c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * <p>This method may be called at any time before {@link Activity#onDestroy}, 6812c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * but the URI(s) are only made available for Android Beam when the 6822c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * specified activity(s) are in resumed (foreground) state. The recommended 6832c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * approach is to call this method during your Activity's 6842c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * {@link Activity#onCreate} - see sample 6852c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * code below. This method does not immediately perform any I/O or blocking work, 6862c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * so is safe to call on your main thread. 6872c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * 6882c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * <p>{@link #setBeamPushUris} and {@link #setBeamPushUrisCallback} 6892c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * have priority over both {@link #setNdefPushMessage} and 6902c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * {@link #setNdefPushMessageCallback}. 6912c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * 6922c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * <p>If {@link #setBeamPushUris} is called with a null Uri array, 6932c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * and/or {@link #setBeamPushUrisCallback} is called with a null callback, 6942c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * then the Uri push will be completely disabled for the specified activity(s). 6952c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * 6962c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * <p>Code example: 6972c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * <pre> 6982c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * protected void onCreate(Bundle savedInstanceState) { 6992c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * super.onCreate(savedInstanceState); 7002c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this); 7012c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * if (nfcAdapter == null) return; // NFC not available on this device 7022c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * nfcAdapter.setBeamPushUrisCallback(callback, this); 70397e0a1c6f3b7ab8f0796931182f0343dd7e73782Scott Main * }</pre> 7042c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * And that is it. Only one call per activity is necessary. The Android 7052c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * OS will automatically release its references to the Uri(s) and the 7062c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * Activity object when it is destroyed if you follow this pattern. 7072c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * 7082c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * <p class="note">Do not pass in an Activity that has already been through 7092c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * {@link Activity#onDestroy}. This is guaranteed if you call this API 7102c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * during {@link Activity#onCreate}. 7112c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * 7123b6ecf0ec1a6822577450908f46496cbe121202eMartijn Coenen * <p class="note">If this device does not support alternate transports 7133b6ecf0ec1a6822577450908f46496cbe121202eMartijn Coenen * such as Bluetooth or WiFI, calling this method does nothing. 7143b6ecf0ec1a6822577450908f46496cbe121202eMartijn Coenen * 7152c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission. 7162c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * 7172c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * @param callback callback, or null to disable 7182c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * @param activity activity for which the Uri(s) will be pushed 7192c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen */ 72020e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen public void setBeamPushUrisCallback(CreateBeamUrisCallback callback, Activity activity) { 7211d7e9062330a5a02247752de32a68ecbeba82783Nick Pelly if (activity == null) { 7221d7e9062330a5a02247752de32a68ecbeba82783Nick Pelly throw new NullPointerException("activity cannot be null"); 7231d7e9062330a5a02247752de32a68ecbeba82783Nick Pelly } 72420e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen mNfcActivityManager.setNdefPushContentUriCallback(activity, callback); 7251d7e9062330a5a02247752de32a68ecbeba82783Nick Pelly } 726590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly 72752d3203ef69d4babbc4dd030a15c08c0b8d1d226Jeff Hamilton /** 7288ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * Set a static {@link NdefMessage} to send using Android Beam (TM). 729c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * 7308ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * <p>This method may be called at any time before {@link Activity#onDestroy}, 7318ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * but the NDEF message is only made available for NDEF push when the 7328ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * specified activity(s) are in resumed (foreground) state. The recommended 7338ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * approach is to call this method during your Activity's 7348ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * {@link Activity#onCreate} - see sample 7358ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * code below. This method does not immediately perform any I/O or blocking work, 7368ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * so is safe to call on your main thread. 737c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * 738c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * <p>Only one NDEF message can be pushed by the currently resumed activity. 739c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * If both {@link #setNdefPushMessage} and 7408ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * {@link #setNdefPushMessageCallback} are set, then 741c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * the callback will take priority. 742c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * 7438ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * <p>If neither {@link #setNdefPushMessage} or 7448ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * {@link #setNdefPushMessageCallback} have been called for your activity, then 7458ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * the Android OS may choose to send a default NDEF message on your behalf, 7468ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * such as a URI for your application. 747c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * 7488ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * <p>If {@link #setNdefPushMessage} is called with a null NDEF message, 7498ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * and/or {@link #setNdefPushMessageCallback} is called with a null callback, 7508ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * then NDEF push will be completely disabled for the specified activity(s). 7518ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * This also disables any default NDEF message the Android OS would have 752854e077555ce5b606c6a688dd5fd0594be02b9f8Martijn Coenen * otherwise sent on your behalf for those activity(s). 753854e077555ce5b606c6a688dd5fd0594be02b9f8Martijn Coenen * 754854e077555ce5b606c6a688dd5fd0594be02b9f8Martijn Coenen * <p>If you want to prevent the Android OS from sending default NDEF 755854e077555ce5b606c6a688dd5fd0594be02b9f8Martijn Coenen * messages completely (for all activities), you can include a 75697e0a1c6f3b7ab8f0796931182f0343dd7e73782Scott Main * {@code <meta-data>} element inside the {@code <application>} 757854e077555ce5b606c6a688dd5fd0594be02b9f8Martijn Coenen * element of your AndroidManifest.xml file, like this: 75897e0a1c6f3b7ab8f0796931182f0343dd7e73782Scott Main * <pre> 75997e0a1c6f3b7ab8f0796931182f0343dd7e73782Scott Main * <application ...> 76097e0a1c6f3b7ab8f0796931182f0343dd7e73782Scott Main * <meta-data android:name="android.nfc.disable_beam_default" 76197e0a1c6f3b7ab8f0796931182f0343dd7e73782Scott Main * android:value="true" /> 76297e0a1c6f3b7ab8f0796931182f0343dd7e73782Scott Main * </application></pre> 7638ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * 7648ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * <p>The API allows for multiple activities to be specified at a time, 7658ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * but it is strongly recommended to just register one at a time, 7668ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * and to do so during the activity's {@link Activity#onCreate}. For example: 7678ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * <pre> 7688ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * protected void onCreate(Bundle savedInstanceState) { 7698ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * super.onCreate(savedInstanceState); 7708ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this); 7718ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * if (nfcAdapter == null) return; // NFC not available on this device 7728ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * nfcAdapter.setNdefPushMessage(ndefMessage, this); 77397e0a1c6f3b7ab8f0796931182f0343dd7e73782Scott Main * }</pre> 7748ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * And that is it. Only one call per activity is necessary. The Android 7758ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * OS will automatically release its references to the NDEF message and the 7768ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * Activity object when it is destroyed if you follow this pattern. 7778ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * 7788ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * <p>If your Activity wants to dynamically generate an NDEF message, 7798ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * then set a callback using {@link #setNdefPushMessageCallback} instead 7808ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * of a static message. 7818ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * 7828ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * <p class="note">Do not pass in an Activity that has already been through 7838ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * {@link Activity#onDestroy}. This is guaranteed if you call this API 7848ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * during {@link Activity#onCreate}. 78582328bfd40008d85917cc01a1b2eb8eed1f23ec4Nick Pelly * 7862c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * <p class="note">For sending large content such as pictures and songs, 7872c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * consider using {@link #setBeamPushUris}, which switches to alternate transports 7882c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * such as Bluetooth to achieve a fast transfer rate. 7892c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * 790c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission. 791c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * 792c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * @param message NDEF message to push over NFC, or null to disable 7938ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * @param activity activity for which the NDEF message will be pushed 7948ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * @param activities optional additional activities, however we strongly recommend 7958ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * to only register one at a time, and to do so in that activity's 7968ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * {@link Activity#onCreate} 797c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly */ 79882328bfd40008d85917cc01a1b2eb8eed1f23ec4Nick Pelly public void setNdefPushMessage(NdefMessage message, Activity activity, 79982328bfd40008d85917cc01a1b2eb8eed1f23ec4Nick Pelly Activity ... activities) { 8008ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly int targetSdkVersion = getSdkVersion(); 8018ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly try { 8028ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly if (activity == null) { 8038ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly throw new NullPointerException("activity cannot be null"); 8048ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly } 8058ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly mNfcActivityManager.setNdefPushMessage(activity, message); 8068ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly for (Activity a : activities) { 8078ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly if (a == null) { 8088ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly throw new NullPointerException("activities cannot contain null"); 8098ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly } 8108ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly mNfcActivityManager.setNdefPushMessage(a, message); 8118ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly } 8128ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly } catch (IllegalStateException e) { 8138ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly if (targetSdkVersion < android.os.Build.VERSION_CODES.JELLY_BEAN) { 8148ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly // Less strict on old applications - just log the error 8158ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly Log.e(TAG, "Cannot call API with Activity that has already " + 8168ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly "been destroyed", e); 8178ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly } else { 8188ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly // Prevent new applications from making this mistake, re-throw 8198ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly throw(e); 82082328bfd40008d85917cc01a1b2eb8eed1f23ec4Nick Pelly } 821c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly } 822c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly } 823c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly 824c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly /** 8258ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * Set a callback that dynamically generates NDEF messages to send using Android Beam (TM). 826c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * 8278ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * <p>This method may be called at any time before {@link Activity#onDestroy}, 8288ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * but the NDEF message callback can only occur when the 8298ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * specified activity(s) are in resumed (foreground) state. The recommended 8308ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * approach is to call this method during your Activity's 8318ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * {@link Activity#onCreate} - see sample 8328ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * code below. This method does not immediately perform any I/O or blocking work, 8338ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * so is safe to call on your main thread. 834c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * 835c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * <p>Only one NDEF message can be pushed by the currently resumed activity. 836c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * If both {@link #setNdefPushMessage} and 8378ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * {@link #setNdefPushMessageCallback} are set, then 838c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * the callback will take priority. 839c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * 8408ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * <p>If neither {@link #setNdefPushMessage} or 8418ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * {@link #setNdefPushMessageCallback} have been called for your activity, then 8428ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * the Android OS may choose to send a default NDEF message on your behalf, 8438ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * such as a URI for your application. 844c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * 8458ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * <p>If {@link #setNdefPushMessage} is called with a null NDEF message, 8468ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * and/or {@link #setNdefPushMessageCallback} is called with a null callback, 8478ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * then NDEF push will be completely disabled for the specified activity(s). 8488ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * This also disables any default NDEF message the Android OS would have 849854e077555ce5b606c6a688dd5fd0594be02b9f8Martijn Coenen * otherwise sent on your behalf for those activity(s). 850854e077555ce5b606c6a688dd5fd0594be02b9f8Martijn Coenen * 851854e077555ce5b606c6a688dd5fd0594be02b9f8Martijn Coenen * <p>If you want to prevent the Android OS from sending default NDEF 852854e077555ce5b606c6a688dd5fd0594be02b9f8Martijn Coenen * messages completely (for all activities), you can include a 85397e0a1c6f3b7ab8f0796931182f0343dd7e73782Scott Main * {@code <meta-data>} element inside the {@code <application>} 854854e077555ce5b606c6a688dd5fd0594be02b9f8Martijn Coenen * element of your AndroidManifest.xml file, like this: 85597e0a1c6f3b7ab8f0796931182f0343dd7e73782Scott Main * <pre> 85697e0a1c6f3b7ab8f0796931182f0343dd7e73782Scott Main * <application ...> 85797e0a1c6f3b7ab8f0796931182f0343dd7e73782Scott Main * <meta-data android:name="android.nfc.disable_beam_default" 85897e0a1c6f3b7ab8f0796931182f0343dd7e73782Scott Main * android:value="true" /> 85997e0a1c6f3b7ab8f0796931182f0343dd7e73782Scott Main * </application></pre> 8608ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * 8618ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * <p>The API allows for multiple activities to be specified at a time, 8628ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * but it is strongly recommended to just register one at a time, 8638ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * and to do so during the activity's {@link Activity#onCreate}. For example: 8648ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * <pre> 8658ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * protected void onCreate(Bundle savedInstanceState) { 8668ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * super.onCreate(savedInstanceState); 8678ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this); 8688ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * if (nfcAdapter == null) return; // NFC not available on this device 8698ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * nfcAdapter.setNdefPushMessageCallback(callback, this); 87097e0a1c6f3b7ab8f0796931182f0343dd7e73782Scott Main * }</pre> 8718ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * And that is it. Only one call per activity is necessary. The Android 8728ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * OS will automatically release its references to the callback and the 8738ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * Activity object when it is destroyed if you follow this pattern. 8748ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * 8758ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * <p class="note">Do not pass in an Activity that has already been through 8768ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * {@link Activity#onDestroy}. This is guaranteed if you call this API 8778ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * during {@link Activity#onCreate}. 8782c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * <p class="note">For sending large content such as pictures and songs, 8792c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * consider using {@link #setBeamPushUris}, which switches to alternate transports 8802c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen * such as Bluetooth to achieve a fast transfer rate. 881c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission. 882c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * 883c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * @param callback callback, or null to disable 8848ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * @param activity activity for which the NDEF message will be pushed 8858ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * @param activities optional additional activities, however we strongly recommend 8868ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * to only register one at a time, and to do so in that activity's 8878ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * {@link Activity#onCreate} 888c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly */ 88982328bfd40008d85917cc01a1b2eb8eed1f23ec4Nick Pelly public void setNdefPushMessageCallback(CreateNdefMessageCallback callback, Activity activity, 890c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly Activity ... activities) { 8918ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly int targetSdkVersion = getSdkVersion(); 8928ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly try { 8938ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly if (activity == null) { 8948ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly throw new NullPointerException("activity cannot be null"); 8958ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly } 8968ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly mNfcActivityManager.setNdefPushMessageCallback(activity, callback); 8978ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly for (Activity a : activities) { 8988ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly if (a == null) { 8998ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly throw new NullPointerException("activities cannot contain null"); 9008ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly } 9018ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly mNfcActivityManager.setNdefPushMessageCallback(a, callback); 9028ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly } 9038ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly } catch (IllegalStateException e) { 9048ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly if (targetSdkVersion < android.os.Build.VERSION_CODES.JELLY_BEAN) { 9058ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly // Less strict on old applications - just log the error 9068ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly Log.e(TAG, "Cannot call API with Activity that has already " + 9078ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly "been destroyed", e); 9088ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly } else { 9098ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly // Prevent new applications from making this mistake, re-throw 9108ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly throw(e); 91182328bfd40008d85917cc01a1b2eb8eed1f23ec4Nick Pelly } 912c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly } 913c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly } 914c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly 915c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly /** 9168ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * Set a callback on successful Android Beam (TM). 9178ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * 9188ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * <p>This method may be called at any time before {@link Activity#onDestroy}, 9198ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * but the callback can only occur when the 9208ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * specified activity(s) are in resumed (foreground) state. The recommended 9218ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * approach is to call this method during your Activity's 9228ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * {@link Activity#onCreate} - see sample 9238ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * code below. This method does not immediately perform any I/O or blocking work, 9248ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * so is safe to call on your main thread. 9258ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * 9268ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * <p>The API allows for multiple activities to be specified at a time, 9278ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * but it is strongly recommended to just register one at a time, 9288ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * and to do so during the activity's {@link Activity#onCreate}. For example: 9298ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * <pre> 9308ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * protected void onCreate(Bundle savedInstanceState) { 9318ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * super.onCreate(savedInstanceState); 9328ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this); 9338ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * if (nfcAdapter == null) return; // NFC not available on this device 9348ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * nfcAdapter.setOnNdefPushCompleteCallback(callback, this); 93597e0a1c6f3b7ab8f0796931182f0343dd7e73782Scott Main * }</pre> 9368ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * And that is it. Only one call per activity is necessary. The Android 9378ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * OS will automatically release its references to the callback and the 9388ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * Activity object when it is destroyed if you follow this pattern. 939c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * 9408ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * <p class="note">Do not pass in an Activity that has already been through 9418ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * {@link Activity#onDestroy}. This is guaranteed if you call this API 9428ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * during {@link Activity#onCreate}. 94382328bfd40008d85917cc01a1b2eb8eed1f23ec4Nick Pelly * 944c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission. 945c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * 946c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * @param callback callback, or null to disable 9478ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * @param activity activity for which the NDEF message will be pushed 9488ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * @param activities optional additional activities, however we strongly recommend 9498ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * to only register one at a time, and to do so in that activity's 9508ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * {@link Activity#onCreate} 951c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly */ 952c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly public void setOnNdefPushCompleteCallback(OnNdefPushCompleteCallback callback, 95382328bfd40008d85917cc01a1b2eb8eed1f23ec4Nick Pelly Activity activity, Activity ... activities) { 9548ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly int targetSdkVersion = getSdkVersion(); 9558ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly try { 9568ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly if (activity == null) { 9578ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly throw new NullPointerException("activity cannot be null"); 9588ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly } 9598ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly mNfcActivityManager.setOnNdefPushCompleteCallback(activity, callback); 9608ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly for (Activity a : activities) { 9618ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly if (a == null) { 9628ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly throw new NullPointerException("activities cannot contain null"); 9638ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly } 9648ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly mNfcActivityManager.setOnNdefPushCompleteCallback(a, callback); 9658ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly } 9668ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly } catch (IllegalStateException e) { 9678ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly if (targetSdkVersion < android.os.Build.VERSION_CODES.JELLY_BEAN) { 9688ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly // Less strict on old applications - just log the error 9698ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly Log.e(TAG, "Cannot call API with Activity that has already " + 9708ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly "been destroyed", e); 9718ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly } else { 9728ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly // Prevent new applications from making this mistake, re-throw 9738ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly throw(e); 97482328bfd40008d85917cc01a1b2eb8eed1f23ec4Nick Pelly } 975c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly } 976c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly } 977c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly 978c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly /** 97974fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * Enable foreground dispatch to the given Activity. 98074fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * 98174fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <p>This will give give priority to the foreground activity when 98274fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * dispatching a discovered {@link Tag} to an application. 98374fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * 984167d9e473f9240d452b25218625c326f31eebbaaJeff Hamilton * <p>If any IntentFilters are provided to this method they are used to match dispatch Intents 985167d9e473f9240d452b25218625c326f31eebbaaJeff Hamilton * for both the {@link NfcAdapter#ACTION_NDEF_DISCOVERED} and 986167d9e473f9240d452b25218625c326f31eebbaaJeff Hamilton * {@link NfcAdapter#ACTION_TAG_DISCOVERED}. Since {@link NfcAdapter#ACTION_TECH_DISCOVERED} 987167d9e473f9240d452b25218625c326f31eebbaaJeff Hamilton * relies on meta data outside of the IntentFilter matching for that dispatch Intent is handled 988167d9e473f9240d452b25218625c326f31eebbaaJeff Hamilton * by passing in the tech lists separately. Each first level entry in the tech list represents 989167d9e473f9240d452b25218625c326f31eebbaaJeff Hamilton * an array of technologies that must all be present to match. If any of the first level sets 990167d9e473f9240d452b25218625c326f31eebbaaJeff Hamilton * match then the dispatch is routed through the given PendingIntent. In other words, the second 991167d9e473f9240d452b25218625c326f31eebbaaJeff Hamilton * level is ANDed together and the first level entries are ORed together. 99274fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * 993167d9e473f9240d452b25218625c326f31eebbaaJeff Hamilton * <p>If you pass {@code null} for both the {@code filters} and {@code techLists} parameters 994167d9e473f9240d452b25218625c326f31eebbaaJeff Hamilton * that acts a wild card and will cause the foreground activity to receive all tags via the 995167d9e473f9240d452b25218625c326f31eebbaaJeff Hamilton * {@link NfcAdapter#ACTION_TAG_DISCOVERED} intent. 99652d3203ef69d4babbc4dd030a15c08c0b8d1d226Jeff Hamilton * 997167d9e473f9240d452b25218625c326f31eebbaaJeff Hamilton * <p>This method must be called from the main thread, and only when the activity is in the 998167d9e473f9240d452b25218625c326f31eebbaaJeff Hamilton * foreground (resumed). Also, activities must call {@link #disableForegroundDispatch} before 999167d9e473f9240d452b25218625c326f31eebbaaJeff Hamilton * the completion of their {@link Activity#onPause} callback to disable foreground dispatch 1000167d9e473f9240d452b25218625c326f31eebbaaJeff Hamilton * after it has been enabled. 100152d3203ef69d4babbc4dd030a15c08c0b8d1d226Jeff Hamilton * 100239cf3a445e507f219ecc8a476f6038f095d9d520Nick Pelly * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission. 100339cf3a445e507f219ecc8a476f6038f095d9d520Nick Pelly * 100452d3203ef69d4babbc4dd030a15c08c0b8d1d226Jeff Hamilton * @param activity the Activity to dispatch to 100552d3203ef69d4babbc4dd030a15c08c0b8d1d226Jeff Hamilton * @param intent the PendingIntent to start for the dispatch 10069f20cd7ff26548e98d7b8412807720c7b340133dJeff Hamilton * @param filters the IntentFilters to override dispatching for, or null to always dispatch 1007167d9e473f9240d452b25218625c326f31eebbaaJeff Hamilton * @param techLists the tech lists used to perform matching for dispatching of the 1008167d9e473f9240d452b25218625c326f31eebbaaJeff Hamilton * {@link NfcAdapter#ACTION_TECH_DISCOVERED} intent 100974fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * @throws IllegalStateException if the Activity is not currently in the foreground 101052d3203ef69d4babbc4dd030a15c08c0b8d1d226Jeff Hamilton */ 101152d3203ef69d4babbc4dd030a15c08c0b8d1d226Jeff Hamilton public void enableForegroundDispatch(Activity activity, PendingIntent intent, 1012d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton IntentFilter[] filters, String[][] techLists) { 10139f20cd7ff26548e98d7b8412807720c7b340133dJeff Hamilton if (activity == null || intent == null) { 101452d3203ef69d4babbc4dd030a15c08c0b8d1d226Jeff Hamilton throw new NullPointerException(); 101552d3203ef69d4babbc4dd030a15c08c0b8d1d226Jeff Hamilton } 101652d3203ef69d4babbc4dd030a15c08c0b8d1d226Jeff Hamilton if (!activity.isResumed()) { 1017c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly throw new IllegalStateException("Foreground dispatch can only be enabled " + 101852d3203ef69d4babbc4dd030a15c08c0b8d1d226Jeff Hamilton "when your activity is resumed"); 101952d3203ef69d4babbc4dd030a15c08c0b8d1d226Jeff Hamilton } 102052d3203ef69d4babbc4dd030a15c08c0b8d1d226Jeff Hamilton try { 1021d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton TechListParcel parcel = null; 1022d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton if (techLists != null && techLists.length > 0) { 1023d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton parcel = new TechListParcel(techLists); 1024d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton } 102552d3203ef69d4babbc4dd030a15c08c0b8d1d226Jeff Hamilton ActivityThread.currentActivityThread().registerOnActivityPausedListener(activity, 1026ce3224cda51f946871daa1e11e3976e25c59e6faJeff Hamilton mForegroundDispatchListener); 1027c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly sService.setForegroundDispatch(intent, filters, parcel); 102852d3203ef69d4babbc4dd030a15c08c0b8d1d226Jeff Hamilton } catch (RemoteException e) { 102952d3203ef69d4babbc4dd030a15c08c0b8d1d226Jeff Hamilton attemptDeadServiceRecovery(e); 103052d3203ef69d4babbc4dd030a15c08c0b8d1d226Jeff Hamilton } 103152d3203ef69d4babbc4dd030a15c08c0b8d1d226Jeff Hamilton } 103252d3203ef69d4babbc4dd030a15c08c0b8d1d226Jeff Hamilton 103352d3203ef69d4babbc4dd030a15c08c0b8d1d226Jeff Hamilton /** 103474fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * Disable foreground dispatch to the given activity. 103533ff2405581271adf14ed4e45597a3b0b80a46abJeff Hamilton * 103674fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <p>After calling {@link #enableForegroundDispatch}, an activity 103774fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * must call this method before its {@link Activity#onPause} callback 103874fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * completes. 103952d3203ef69d4babbc4dd030a15c08c0b8d1d226Jeff Hamilton * 104033ff2405581271adf14ed4e45597a3b0b80a46abJeff Hamilton * <p>This method must be called from the main thread. 104174fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * 104239cf3a445e507f219ecc8a476f6038f095d9d520Nick Pelly * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission. 104339cf3a445e507f219ecc8a476f6038f095d9d520Nick Pelly * 104474fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * @param activity the Activity to disable dispatch to 104574fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * @throws IllegalStateException if the Activity has already been paused 104652d3203ef69d4babbc4dd030a15c08c0b8d1d226Jeff Hamilton */ 104752d3203ef69d4babbc4dd030a15c08c0b8d1d226Jeff Hamilton public void disableForegroundDispatch(Activity activity) { 1048ce3224cda51f946871daa1e11e3976e25c59e6faJeff Hamilton ActivityThread.currentActivityThread().unregisterOnActivityPausedListener(activity, 1049ce3224cda51f946871daa1e11e3976e25c59e6faJeff Hamilton mForegroundDispatchListener); 105052d3203ef69d4babbc4dd030a15c08c0b8d1d226Jeff Hamilton disableForegroundDispatchInternal(activity, false); 105152d3203ef69d4babbc4dd030a15c08c0b8d1d226Jeff Hamilton } 105252d3203ef69d4babbc4dd030a15c08c0b8d1d226Jeff Hamilton 1053ce3224cda51f946871daa1e11e3976e25c59e6faJeff Hamilton OnActivityPausedListener mForegroundDispatchListener = new OnActivityPausedListener() { 105433ff2405581271adf14ed4e45597a3b0b80a46abJeff Hamilton @Override 105533ff2405581271adf14ed4e45597a3b0b80a46abJeff Hamilton public void onPaused(Activity activity) { 105633ff2405581271adf14ed4e45597a3b0b80a46abJeff Hamilton disableForegroundDispatchInternal(activity, true); 105733ff2405581271adf14ed4e45597a3b0b80a46abJeff Hamilton } 1058ce3224cda51f946871daa1e11e3976e25c59e6faJeff Hamilton }; 105933ff2405581271adf14ed4e45597a3b0b80a46abJeff Hamilton 106052d3203ef69d4babbc4dd030a15c08c0b8d1d226Jeff Hamilton void disableForegroundDispatchInternal(Activity activity, boolean force) { 106152d3203ef69d4babbc4dd030a15c08c0b8d1d226Jeff Hamilton try { 1062c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly sService.setForegroundDispatch(null, null, null); 106352d3203ef69d4babbc4dd030a15c08c0b8d1d226Jeff Hamilton if (!force && !activity.isResumed()) { 1064c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly throw new IllegalStateException("You must disable foreground dispatching " + 106552d3203ef69d4babbc4dd030a15c08c0b8d1d226Jeff Hamilton "while your activity is still resumed"); 106652d3203ef69d4babbc4dd030a15c08c0b8d1d226Jeff Hamilton } 106752d3203ef69d4babbc4dd030a15c08c0b8d1d226Jeff Hamilton } catch (RemoteException e) { 106852d3203ef69d4babbc4dd030a15c08c0b8d1d226Jeff Hamilton attemptDeadServiceRecovery(e); 106933ff2405581271adf14ed4e45597a3b0b80a46abJeff Hamilton } 107033ff2405581271adf14ed4e45597a3b0b80a46abJeff Hamilton } 107133ff2405581271adf14ed4e45597a3b0b80a46abJeff Hamilton 107233ff2405581271adf14ed4e45597a3b0b80a46abJeff Hamilton /** 1073c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * Enable NDEF message push over NFC while this Activity is in the foreground. 107474fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * 1075c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * <p>You must explicitly call this method every time the activity is 1076c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * resumed, and you must call {@link #disableForegroundNdefPush} before 1077c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * your activity completes {@link Activity#onPause}. 10789f20cd7ff26548e98d7b8412807720c7b340133dJeff Hamilton * 1079c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * <p>Strongly recommend to use the new {@link #setNdefPushMessage} 1080c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * instead: it automatically hooks into your activity life-cycle, 1081c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * so you do not need to call enable/disable in your onResume/onPause. 108274fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * 1083c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * <p>For NDEF push to function properly the other NFC device must 1084c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * support either NFC Forum's SNEP (Simple Ndef Exchange Protocol), or 1085c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * Android's "com.android.npp" (Ndef Push Protocol). This was optional 1086c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * on Gingerbread level Android NFC devices, but SNEP is mandatory on 1087c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * Ice-Cream-Sandwich and beyond. 108801425365a85e605139f612502f68954cad869e5bJason parks * 108901425365a85e605139f612502f68954cad869e5bJason parks * <p>This method must be called from the main thread. 109001425365a85e605139f612502f68954cad869e5bJason parks * 109101425365a85e605139f612502f68954cad869e5bJason parks * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission. 109201425365a85e605139f612502f68954cad869e5bJason parks * 1093c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * @param activity foreground activity 1094c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * @param message a NDEF Message to push over NFC 1095c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * @throws IllegalStateException if the activity is not currently in the foreground 1096c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * @deprecated use {@link #setNdefPushMessage} instead 109701425365a85e605139f612502f68954cad869e5bJason parks */ 1098c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly @Deprecated 1099c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly public void enableForegroundNdefPush(Activity activity, NdefMessage message) { 1100c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly if (activity == null || message == null) { 110101425365a85e605139f612502f68954cad869e5bJason parks throw new NullPointerException(); 110201425365a85e605139f612502f68954cad869e5bJason parks } 1103c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly enforceResumed(activity); 1104c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly mNfcActivityManager.setNdefPushMessage(activity, message); 110501425365a85e605139f612502f68954cad869e5bJason parks } 110601425365a85e605139f612502f68954cad869e5bJason parks 110701425365a85e605139f612502f68954cad869e5bJason parks /** 110874fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * Disable NDEF message push over P2P. 110933ff2405581271adf14ed4e45597a3b0b80a46abJeff Hamilton * 111074fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <p>After calling {@link #enableForegroundNdefPush}, an activity 111174fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * must call this method before its {@link Activity#onPause} callback 111274fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * completes. 111333ff2405581271adf14ed4e45597a3b0b80a46abJeff Hamilton * 1114c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * <p>Strongly recommend to use the new {@link #setNdefPushMessage} 1115c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * instead: it automatically hooks into your activity life-cycle, 1116c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * so you do not need to call enable/disable in your onResume/onPause. 1117c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * 111833ff2405581271adf14ed4e45597a3b0b80a46abJeff Hamilton * <p>This method must be called from the main thread. 111974fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * 112039cf3a445e507f219ecc8a476f6038f095d9d520Nick Pelly * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission. 112139cf3a445e507f219ecc8a476f6038f095d9d520Nick Pelly * 112274fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * @param activity the Foreground activity 112374fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * @throws IllegalStateException if the Activity has already been paused 1124c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * @deprecated use {@link #setNdefPushMessage} instead 112533ff2405581271adf14ed4e45597a3b0b80a46abJeff Hamilton */ 1126c97a552023c3c71079b39092e80c9b44f25a789bNick Pelly @Deprecated 1127ce3224cda51f946871daa1e11e3976e25c59e6faJeff Hamilton public void disableForegroundNdefPush(Activity activity) { 1128c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly if (activity == null) { 1129c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly throw new NullPointerException(); 1130c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly } 1131c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly enforceResumed(activity); 1132c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly mNfcActivityManager.setNdefPushMessage(activity, null); 1133c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly mNfcActivityManager.setNdefPushMessageCallback(activity, null); 1134c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly mNfcActivityManager.setOnNdefPushCompleteCallback(activity, null); 113533ff2405581271adf14ed4e45597a3b0b80a46abJeff Hamilton } 113633ff2405581271adf14ed4e45597a3b0b80a46abJeff Hamilton 1137c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly /** 1138c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * Enable NDEF Push feature. 1139c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * <p>This API is for the Settings application. 11406d7489407995210f3f01690d1f0c8b970362d8aeMartijn Coenen * @hide 11416d7489407995210f3f01690d1f0c8b970362d8aeMartijn Coenen */ 1142c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly public boolean enableNdefPush() { 11436d7489407995210f3f01690d1f0c8b970362d8aeMartijn Coenen try { 1144c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly return sService.enableNdefPush(); 11456d7489407995210f3f01690d1f0c8b970362d8aeMartijn Coenen } catch (RemoteException e) { 11466d7489407995210f3f01690d1f0c8b970362d8aeMartijn Coenen attemptDeadServiceRecovery(e); 11476d7489407995210f3f01690d1f0c8b970362d8aeMartijn Coenen return false; 11486d7489407995210f3f01690d1f0c8b970362d8aeMartijn Coenen } 11496d7489407995210f3f01690d1f0c8b970362d8aeMartijn Coenen } 11506d7489407995210f3f01690d1f0c8b970362d8aeMartijn Coenen 11516d7489407995210f3f01690d1f0c8b970362d8aeMartijn Coenen /** 1152c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * Disable NDEF Push feature. 1153c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * <p>This API is for the Settings application. 11546d7489407995210f3f01690d1f0c8b970362d8aeMartijn Coenen * @hide 11556d7489407995210f3f01690d1f0c8b970362d8aeMartijn Coenen */ 1156c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly public boolean disableNdefPush() { 11576d7489407995210f3f01690d1f0c8b970362d8aeMartijn Coenen try { 1158c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly return sService.disableNdefPush(); 11596d7489407995210f3f01690d1f0c8b970362d8aeMartijn Coenen } catch (RemoteException e) { 11606d7489407995210f3f01690d1f0c8b970362d8aeMartijn Coenen attemptDeadServiceRecovery(e); 11616d7489407995210f3f01690d1f0c8b970362d8aeMartijn Coenen return false; 11626d7489407995210f3f01690d1f0c8b970362d8aeMartijn Coenen } 11636d7489407995210f3f01690d1f0c8b970362d8aeMartijn Coenen } 11646d7489407995210f3f01690d1f0c8b970362d8aeMartijn Coenen 11656d7489407995210f3f01690d1f0c8b970362d8aeMartijn Coenen /** 1166cccf01d3e270bbf53ae6601698109ac4ef461076Nick Pelly * Return true if the NDEF Push (Android Beam) feature is enabled. 1167cccf01d3e270bbf53ae6601698109ac4ef461076Nick Pelly * <p>This function will return true only if both NFC is enabled, and the 1168cccf01d3e270bbf53ae6601698109ac4ef461076Nick Pelly * NDEF Push feature is enabled. 1169cccf01d3e270bbf53ae6601698109ac4ef461076Nick Pelly * <p>Note that if NFC is enabled but NDEF Push is disabled then this 1170cccf01d3e270bbf53ae6601698109ac4ef461076Nick Pelly * device can still <i>receive</i> NDEF messages, it just cannot send them. 1171cccf01d3e270bbf53ae6601698109ac4ef461076Nick Pelly * <p>Applications cannot directly toggle the NDEF Push feature, but they 1172cccf01d3e270bbf53ae6601698109ac4ef461076Nick Pelly * can request Settings UI allowing the user to toggle NDEF Push using 1173cccf01d3e270bbf53ae6601698109ac4ef461076Nick Pelly * <code>startActivity(new Intent(Settings.ACTION_NFCSHARING_SETTINGS))</code> 1174cccf01d3e270bbf53ae6601698109ac4ef461076Nick Pelly * <p>Example usage in an Activity that requires NDEF Push: 1175cccf01d3e270bbf53ae6601698109ac4ef461076Nick Pelly * <p><pre> 1176cccf01d3e270bbf53ae6601698109ac4ef461076Nick Pelly * protected void onResume() { 1177cccf01d3e270bbf53ae6601698109ac4ef461076Nick Pelly * super.onResume(); 1178cccf01d3e270bbf53ae6601698109ac4ef461076Nick Pelly * if (!nfcAdapter.isEnabled()) { 1179cccf01d3e270bbf53ae6601698109ac4ef461076Nick Pelly * startActivity(new Intent(Settings.ACTION_NFC_SETTINGS)); 1180cccf01d3e270bbf53ae6601698109ac4ef461076Nick Pelly * } else if (!nfcAdapter.isNdefPushEnabled()) { 1181cccf01d3e270bbf53ae6601698109ac4ef461076Nick Pelly * startActivity(new Intent(Settings.ACTION_NFCSHARING_SETTINGS)); 1182cccf01d3e270bbf53ae6601698109ac4ef461076Nick Pelly * } 118397e0a1c6f3b7ab8f0796931182f0343dd7e73782Scott Main * }</pre> 11846d7489407995210f3f01690d1f0c8b970362d8aeMartijn Coenen * 1185cccf01d3e270bbf53ae6601698109ac4ef461076Nick Pelly * @see android.provider.Settings#ACTION_NFCSHARING_SETTINGS 1186c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * @return true if NDEF Push feature is enabled 11876d7489407995210f3f01690d1f0c8b970362d8aeMartijn Coenen */ 1188c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly public boolean isNdefPushEnabled() { 11896d7489407995210f3f01690d1f0c8b970362d8aeMartijn Coenen try { 1190c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly return sService.isNdefPushEnabled(); 11916d7489407995210f3f01690d1f0c8b970362d8aeMartijn Coenen } catch (RemoteException e) { 11926d7489407995210f3f01690d1f0c8b970362d8aeMartijn Coenen attemptDeadServiceRecovery(e); 11936d7489407995210f3f01690d1f0c8b970362d8aeMartijn Coenen return false; 11946d7489407995210f3f01690d1f0c8b970362d8aeMartijn Coenen } 11956d7489407995210f3f01690d1f0c8b970362d8aeMartijn Coenen } 11966d7489407995210f3f01690d1f0c8b970362d8aeMartijn Coenen 11976d7489407995210f3f01690d1f0c8b970362d8aeMartijn Coenen /** 1198c97a552023c3c71079b39092e80c9b44f25a789bNick Pelly * Inject a mock NFC tag.<p> 1199c97a552023c3c71079b39092e80c9b44f25a789bNick Pelly * Used for testing purposes. 1200c97a552023c3c71079b39092e80c9b44f25a789bNick Pelly * <p class="note">Requires the 1201c97a552023c3c71079b39092e80c9b44f25a789bNick Pelly * {@link android.Manifest.permission#WRITE_SECURE_SETTINGS} permission. 1202c97a552023c3c71079b39092e80c9b44f25a789bNick Pelly * @hide 1203c97a552023c3c71079b39092e80c9b44f25a789bNick Pelly */ 12041f5badc1cb08f10ddf4b09aaaf34060a23999a51Nick Pelly public void dispatch(Tag tag) { 1205c97a552023c3c71079b39092e80c9b44f25a789bNick Pelly if (tag == null) { 1206c97a552023c3c71079b39092e80c9b44f25a789bNick Pelly throw new NullPointerException("tag cannot be null"); 1207c97a552023c3c71079b39092e80c9b44f25a789bNick Pelly } 1208c97a552023c3c71079b39092e80c9b44f25a789bNick Pelly try { 12091f5badc1cb08f10ddf4b09aaaf34060a23999a51Nick Pelly sService.dispatch(tag); 1210c97a552023c3c71079b39092e80c9b44f25a789bNick Pelly } catch (RemoteException e) { 1211c97a552023c3c71079b39092e80c9b44f25a789bNick Pelly attemptDeadServiceRecovery(e); 1212c97a552023c3c71079b39092e80c9b44f25a789bNick Pelly } 1213c97a552023c3c71079b39092e80c9b44f25a789bNick Pelly } 1214c97a552023c3c71079b39092e80c9b44f25a789bNick Pelly 1215c97a552023c3c71079b39092e80c9b44f25a789bNick Pelly /** 12169024564107b58955f7bd257cab6fc6dfcb2e5ec2Daniel Tomas * @hide 12179024564107b58955f7bd257cab6fc6dfcb2e5ec2Daniel Tomas */ 1218188cddb1d8c89749618401e371a7e7900cb58d6dMartijn Coenen public void setP2pModes(int initiatorModes, int targetModes) { 1219188cddb1d8c89749618401e371a7e7900cb58d6dMartijn Coenen try { 1220188cddb1d8c89749618401e371a7e7900cb58d6dMartijn Coenen sService.setP2pModes(initiatorModes, targetModes); 1221188cddb1d8c89749618401e371a7e7900cb58d6dMartijn Coenen } catch (RemoteException e) { 1222188cddb1d8c89749618401e371a7e7900cb58d6dMartijn Coenen attemptDeadServiceRecovery(e); 1223188cddb1d8c89749618401e371a7e7900cb58d6dMartijn Coenen } 1224188cddb1d8c89749618401e371a7e7900cb58d6dMartijn Coenen } 1225188cddb1d8c89749618401e371a7e7900cb58d6dMartijn Coenen 1226188cddb1d8c89749618401e371a7e7900cb58d6dMartijn Coenen /** 1227188cddb1d8c89749618401e371a7e7900cb58d6dMartijn Coenen * @hide 1228188cddb1d8c89749618401e371a7e7900cb58d6dMartijn Coenen */ 1229367f41f8f61126c2ab34a34cc676756a9fc23ac2Nick Pelly public INfcAdapterExtras getNfcAdapterExtrasInterface() { 1230bb951c893973691554f49d2e725985125f866b27Jeff Hamilton if (mContext == null) { 1231bb951c893973691554f49d2e725985125f866b27Jeff Hamilton throw new UnsupportedOperationException("You need a context on NfcAdapter to use the " 1232bb951c893973691554f49d2e725985125f866b27Jeff Hamilton + " NFC extras APIs"); 1233bb951c893973691554f49d2e725985125f866b27Jeff Hamilton } 12349024564107b58955f7bd257cab6fc6dfcb2e5ec2Daniel Tomas try { 1235bb951c893973691554f49d2e725985125f866b27Jeff Hamilton return sService.getNfcAdapterExtrasInterface(mContext.getPackageName()); 12369024564107b58955f7bd257cab6fc6dfcb2e5ec2Daniel Tomas } catch (RemoteException e) { 1237367f41f8f61126c2ab34a34cc676756a9fc23ac2Nick Pelly attemptDeadServiceRecovery(e); 12389024564107b58955f7bd257cab6fc6dfcb2e5ec2Daniel Tomas return null; 12399024564107b58955f7bd257cab6fc6dfcb2e5ec2Daniel Tomas } 12409024564107b58955f7bd257cab6fc6dfcb2e5ec2Daniel Tomas } 1241c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly 1242c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly void enforceResumed(Activity activity) { 1243c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly if (!activity.isResumed()) { 1244c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly throw new IllegalStateException("API cannot be called while activity is paused"); 1245c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly } 1246c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly } 12478ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly 12488ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly int getSdkVersion() { 12498ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly if (mContext == null) { 12508ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly return android.os.Build.VERSION_CODES.GINGERBREAD; // best guess 12518ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly } else { 12528ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly return mContext.getApplicationInfo().targetSdkVersion; 12538ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly } 12548ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly } 1255590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly} 1256