diff options
Diffstat (limited to 'docs/html/training/beam-files/send-files.jd')
-rw-r--r-- | docs/html/training/beam-files/send-files.jd | 294 |
1 files changed, 294 insertions, 0 deletions
diff --git a/docs/html/training/beam-files/send-files.jd b/docs/html/training/beam-files/send-files.jd new file mode 100644 index 0000000..917b87f --- /dev/null +++ b/docs/html/training/beam-files/send-files.jd @@ -0,0 +1,294 @@ +page.title=Sending Files to Another Device + +trainingnavtop=true +@jd:body + + +<div id="tb-wrapper"> +<div id="tb"> + +<!-- table of contents --> +<h2>This lesson teaches you to</h2> +<ol> + <li><a href="#DeclareFeatures">Declare Features in the Manifest</a> + <li><a href="#TestAndroidBeam">Test for Android Beam File Transfer Support</a></li> + <li> + <a href="#CreateCallback" + >Create a Callback Method That Provides Files</a> + </li> + <li><a href="#ProvideUri">Specify the Files to Send</a> +</ol> + +<h2>You should also read</h2> +<ul> + <li><a href="{@docRoot}guide/topics/data/data-storage.html">Storage Options</a></li> +</ul> + +</div> +</div> +<p> + This lesson shows you how to design your app to send large files to another device using + Android Beam file transfer. To send files, you request permission to use NFC and external + storage, test to ensure your device supports NFC, and provide URIs to Android Beam file + transfer. +</p> +<p> + The Android Beam file transfer feature has the following requirements: +</p> +<ol> + <li> + Android Beam file transfer for large files is only available in Android 4.1 (API level 16) + and higher. + </li> + <li> + Files you want to transfer must reside in external storage. To learn more about using + external storage, read <a href="{@docRoot}guide/topics/data/data-storage.html#filesExternal" + >Using the External Storage</a>. + </li> + <li> + Each file you want to transfer must be world-readable. You can set this permission by + calling the method {@link java.io.File#setReadable File.setReadable(true,false)}. + </li> + <li> + You must provide a file URI for the files you want to transfer. Android Beam file transfer + is unable to handle content URIs generated by + {@link android.support.v4.content.FileProvider#getUriForFile FileProvider.getUriForFile}. + </li> +</ol> + +<h2 id="DeclareFeatures">Declare Features in the Manifest</h2> +<p> + First, edit your app manifest to declare the permissions and features your app needs. +</p> +<h3>Request Permissions</h3> +<p> + To allow your app to use Android Beam file transfer to send files from external storage using + NFC, you must request the following permissions in your app manifest: +</p> +<dl> + <dt> + {@link android.Manifest.permission#NFC NFC} + </dt> + <dd> + Allows your app to send data over NFC. To specify this permission, add the following element + as a child of the <code><a href="{@docRoot}guide/topics/manifest/manifest-element.html" + ><manifest></a></code> element: +<pre> + <uses-permission android:name="android.permission.NFC" /> +</pre> + </dd> + <dt> + {@link android.Manifest.permission#READ_EXTERNAL_STORAGE READ_EXTERNAL_STORAGE} + </dt> + <dd> + Allows your app to read from external storage. To specify this permission, add the following + element as a child of the + <code><a href="{@docRoot}guide/topics/manifest/manifest-element.html" + ><manifest></a></code> element: +<pre> + <uses-permission + android:name="android.permission.READ_EXTERNAL_STORAGE" /> +</pre> + <p class="note"> + <strong>Note:</strong> As of Android 4.2.2 (API level 17), this permission is not + enforced. Future versions of the platform may require it for apps that want to read from + external storage. To ensure forward compatibility, request the permission now, before it + becomes required. + </p> + </dd> +</dl> +<h3>Specify the NFC feature</h3> +<p> + Specify that your app uses NFC, by adding a + <code><a href="{@docRoot}guide/topics/manifest/uses-feature-element.html" + ><uses-feature></a></code> element as a child + of the <code><a href="{@docRoot}guide/topics/manifest/manifest-element.html" + ><manifest></a></code> element. Set the <code>android:required</code> attribute to + <code>true</code> to indicate that your app won't function unless NFC is present. +</p> +<p> + The following snippet shows you how to specify the + <code><a href="{@docRoot}guide/topics/manifest/uses-feature-element.html" + ><uses-feature></a></code> element: +</p> +<pre> +<uses-feature + android:name="android.hardware.nfc" + android:required="true" /></pre> +<p> + Note that if your app only uses NFC as an option, but still functions if NFC isn't present, you + should set <code>android:required</code> to <code>false</code>, and test for NFC in code. +</p> +<h3>Specify Android Beam file transfer</h3> +<p> + Since Android Beam file transfer is only available in Android 4.1 (API level 16) and later, + if your app depends on Android Beam file transfer for a key part of its functionality you must + specify the <code><a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html" + ><uses-sdk></a></code> element with the + <code><a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min" + >android:minSdkVersion</a>="16"</code> attribute. Otherwise, you can set + <code><a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min" + >android:minSdkVersion</a></code> to another value as necessary, and test for the platform + version in code, as described in the following section. +</p> +<h2 id="TestAndroidBeam">Test for Android Beam File Transfer Support</h2> +<p> + To specify in your app manifest that NFC is optional, you use the following element: +</p> +<pre> +<uses-feature android:name="android.hardware.nfc" android:required="false" /></pre> +<p> + If you set the attribute + <code><a href="guide/topics/manifest/uses-feature-element.html#required" + >android:required</a>="false"</code>, you must test for NFC support and Android Beam file + transfer support in code. +</p> +<p> + To test for Android Beam file transfer support in code, start by testing that the device + supports NFC by calling {@link android.content.pm.PackageManager#hasSystemFeature + PackageManager.hasSystemFeature()} with the argument + {@link android.content.pm.PackageManager#FEATURE_NFC FEATURE_NFC}. Next, check that the Android + version supports Android Beam file transfer by testing the value of + {@link android.os.Build.VERSION#SDK_INT}. If Android Beam file transfer is supported, get an + instance of the NFC controller, which allows you to communicate with the NFC hardware. + For example: +</p> +<pre> +public class MainActivity extends Activity { + ... + NfcAdapter mNfcAdapter; + // Flag to indicate that Android Beam is available + boolean mAndroidBeamAvailable = false; + ... + @Override + protected void onCreate(Bundle savedInstanceState) { + ... + // NFC isn't available on the device + if (!PackageManager.hasSystemFeature(PackageManager.FEATURE_NFC)) { + /* + * Disable NFC features here. + * For example, disable menu items or buttons that activate + * NFC-related features + */ + ... + // Android Beam file transfer isn't supported + } else if (Build.VERSION.SDK_INT < + Build.VERSION_CODES.JELLY_BEAN_MR1) { + // If Android Beam isn't available, don't continue. + mAndroidBeamAvailable = false; + /* + * Disable Android Beam file transfer features here. + */ + ... + // Android Beam file transfer is available, continue + } else { + mNfcAdapter = NfcAdapter.getDefaultAdapter(this); + ... + } + } + ... +}</pre> + +<h2 id="CreateCallback"> + Create a Callback Method that Provides Files +</h2> +<p> + Once you've verified that the device supports Android Beam file transfer, add a callback + method that the system invokes when Android Beam file transfer detects that the user wants + to send files to another NFC-enabled device. In this callback method, return an array of + {@link android.net.Uri} objects. Android Beam file transfer copies the files represented by + these URIs to the receiving device. +</p> +<p> + To add the callback method, implement the + {@link android.nfc.NfcAdapter.CreateBeamUrisCallback} interface and its method + {@link android.nfc.NfcAdapter.CreateBeamUrisCallback#createBeamUris createBeamUris()}. The + following snippet shows you how to do this: +</p> +<pre> +public class MainActivity extends Activity { + ... + // List of URIs to provide to Android Beam + private Uri[] mFileUris = new Uri[10]; + ... + /** + * Callback that Android Beam file transfer calls to get + * files to share + */ + private class FileUriCallback implements + NfcAdapter.CreateBeamUrisCallback { + public FileUriCallback() { + } + /** + * Create content URIs as needed to share with another device + */ + @Override + public Uri[] createBeamUris(NfcEvent event) { + return mFileUris; + } + } + ... +} +</pre> +<p> + Once you've implemented the interface, provide the callback to Android Beam file transfer by + calling {@link android.nfc.NfcAdapter#setBeamPushUrisCallback setBeamPushUrisCallback()}. The + following snippet shows you how to do this: +</p> +<pre> +public class MainActivity extends Activity { + ... + // Instance that returns available files from this app + private FileUriCallback mFileUriCallback; + ... + @Override + protected void onCreate(Bundle savedInstanceState) { + ... + // Android Beam file transfer is available, continue + ... + mNfcAdapter = NfcAdapter.getDefaultAdapter(this); + /* + * Instantiate a new FileUriCallback to handle requests for + * URIs + */ + mFileUriCallback = new FileUriCallback(); + // Set the dynamic callback for URI requests. + mNfcAdapter.setBeamPushUrisCallback(mFileUriCallback,this); + ... + } + ... +} +</pre> +<p class="note"> + <strong>Note:</strong> You can also provide the array of {@link android.net.Uri} objects + directly to the NFC framework through your app's {@link android.nfc.NfcAdapter} instance. Choose + this approach if you can define the URIs to transfer before the NFC touch event occurs. + To learn more about this approach, see {@link android.nfc.NfcAdapter#setBeamPushUris + NfcAdapter.setBeamPushUris()}. +</p> +<h2 id="ProvideUri">Specify the Files to Send</h2> +<p> + To transfer one or more files to another NFC-enabled device, get a file URI (a URI with a + <code>file</code> scheme) for each file and then add the URI to an array of + {@link android.net.Uri} objects. To transfer a file, you must also have permanent read access + for the file. For example, the following snippet shows you how to get a file URI from a file + name and then add the URI to the array: +</p> +<pre> + /* + * Create a list of URIs, get a File, + * and set its permissions + */ + private Uri[] mFileUris = new Uri[10]; + String transferFile = "transferimage.jpg"; + File extDir = getExternalFilesDir(null); + File requestFile = new File(extDir, transferFile); + requestFile.setReadable(true, false); + // Get a URI for the File and add it to the list of URIs + fileUri = Uri.fromFile(requestFile); + if (fileUri != null) { + mFileUris[0] = fileUri; + } else { + Log.e("My Activity", "No File URI available for file."); + } +</pre> |