Merge "DOC CHANGE: Android Beam training class" into jb-mr2-docs
This commit is contained in:
61
docs/html/training/beam-files/index.jd
Normal file
61
docs/html/training/beam-files/index.jd
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
page.title=Sharing Files with NFC
|
||||||
|
|
||||||
|
trainingnavtop=true
|
||||||
|
startpage=true
|
||||||
|
|
||||||
|
|
||||||
|
@jd:body
|
||||||
|
|
||||||
|
<div id="tb-wrapper">
|
||||||
|
<div id="tb">
|
||||||
|
|
||||||
|
<h2>Dependencies and prerequisites</h2>
|
||||||
|
<ul>
|
||||||
|
<li>Android 4.1 (API Level 16) or higher</li>
|
||||||
|
<li>At least two NFC-enabled Android devices (NFC is not supported in the emulator)</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h2>You should also read</h2>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="{@docRoot}guide/topics/data/data-storage.html#filesExternal"
|
||||||
|
>Using the External Storage</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Android allows you to transfer large files between devices using the Android Beam file transfer
|
||||||
|
feature. This feature has a simple API and allows users to start the transfer process by simply
|
||||||
|
touching devices. In response, Android Beam file transfer automatically copies files from one
|
||||||
|
device to the other and notifies the user when it's finished.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
While the Android Beam file transfer API handles large amounts of data, the Android Beam NDEF
|
||||||
|
transfer API introduced in Android 4.0 (API level 14) handles small amounts of data such as
|
||||||
|
URIs or other small messages. In addition, Android Beam is only one of the features available
|
||||||
|
in the Android NFC framework, which allows you to read NDEF messages from NFC tags. To learn
|
||||||
|
more about Android Beam, see the topic
|
||||||
|
<a href="{@docRoot}guide/topics/connectivity/nfc/nfc.html#p2p"
|
||||||
|
>Beaming NDEF Messages to Other Devices</a>. To learn more about the NFC framework, see the
|
||||||
|
<a href="{@docRoot}guide/topics/connectivity/nfc/index.html"
|
||||||
|
>Near Field Communication</a> API guide.
|
||||||
|
</p>
|
||||||
|
<h2>Lessons</h2>
|
||||||
|
<dl>
|
||||||
|
<dt>
|
||||||
|
<b><a href="send-files.html">Sending Files to Another Device</a></b>
|
||||||
|
</dt>
|
||||||
|
<dd>Learn how to set up your app to send files to another device.</dd>
|
||||||
|
|
||||||
|
<dt>
|
||||||
|
<b><a href="receive-files.html">Receiving Files from Another Device</a></b>
|
||||||
|
</dt>
|
||||||
|
<dd>
|
||||||
|
Learn how to set up your app to receive files sent by another device.
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
|
||||||
|
|
||||||
313
docs/html/training/beam-files/receive-files.jd
Normal file
313
docs/html/training/beam-files/receive-files.jd
Normal file
@@ -0,0 +1,313 @@
|
|||||||
|
page.title=Receiving Files from Another Device
|
||||||
|
|
||||||
|
trainingnavtop=true
|
||||||
|
@jd:body
|
||||||
|
|
||||||
|
<div id="tb-wrapper">
|
||||||
|
<div id="tb">
|
||||||
|
|
||||||
|
<h2>This lesson teaches you to</h2>
|
||||||
|
<ol>
|
||||||
|
<li><a href="#IntentFilter">Respond to a Request to Display Data</a></li>
|
||||||
|
<li><a href="#RequestPermissions">Request File Permissions</a></li>
|
||||||
|
<li><a href="#GetFilePath">Get the Directory for Copied Files</a></li>
|
||||||
|
</ol>
|
||||||
|
<h2>You should also read</h2>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="{@docRoot}guide/topics/providers/content-provider-basics.html#ContentURIs"
|
||||||
|
>Content URIs</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="{@docRoot}guide/components/intents-filters.html">Intents and Intent Filters</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Notifications</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="{@docRoot}guide/topics/data/data-storage.html#filesExternal"
|
||||||
|
>Using the External Storage</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Android Beam file transfer copies files to a special directory on the receiving device. It also
|
||||||
|
scans the copied files using the Android Media Scanner and adds entries for media files to
|
||||||
|
the {@link android.provider.MediaStore} provider. This lesson shows you how to respond when the
|
||||||
|
file copy is complete, and how to locate the copied files on the receiving device.
|
||||||
|
</p>
|
||||||
|
<h2 id="IntentFilter">Respond to a Request to Display Data</h2>
|
||||||
|
<p>
|
||||||
|
When Android Beam file transfer finishes copying files to the receiving device, it posts a
|
||||||
|
notification containing an {@link android.content.Intent} with the action
|
||||||
|
{@link android.content.Intent#ACTION_VIEW ACTION_VIEW}, the MIME type of the first file that
|
||||||
|
was transferred, and a URI that points to the first file. When the user clicks the notification,
|
||||||
|
this intent is sent out to the system. To have your app respond to this intent, add an
|
||||||
|
<code><a href="{@docRoot}guide/topics/manifest/intent-filter-element.html"
|
||||||
|
><intent-filter></a></code> element for the
|
||||||
|
<code><a href="{@docRoot}guide/topics/manifest/activity-element.html"
|
||||||
|
><activity></a></code> element of the {@link android.app.Activity} that should respond.
|
||||||
|
In the <code><a href="{@docRoot}guide/topics/manifest/intent-filter-element.html"
|
||||||
|
><intent-filter></a></code> element, add the following child elements:
|
||||||
|
</p>
|
||||||
|
<dl>
|
||||||
|
<dt>
|
||||||
|
<code><a href="{@docRoot}guide/topics/manifest/action-element.html"
|
||||||
|
><action android:name="android.intent.action.VIEW" /></a></code>
|
||||||
|
</dt>
|
||||||
|
<dd>
|
||||||
|
Matches the {@link android.content.Intent#ACTION_VIEW ACTION_VIEW} intent sent from the
|
||||||
|
notification.
|
||||||
|
</dd>
|
||||||
|
<dt>
|
||||||
|
<code><a href="{@docRoot}guide/topics/manifest/category-element.html"
|
||||||
|
><category android:name="android.intent.category.CATEGORY_DEFAULT" /></a></code>
|
||||||
|
</dt>
|
||||||
|
<dd>
|
||||||
|
Matches an {@link android.content.Intent} that doesn't have an explicit category.
|
||||||
|
</dd>
|
||||||
|
<dt>
|
||||||
|
<code><a href="{@docRoot}guide/topics/manifest/data-element.html"
|
||||||
|
><data android:mimeType="<i>mime-type</i>" /></a></code>
|
||||||
|
</dt>
|
||||||
|
<dd>
|
||||||
|
Matches a MIME type. Specify only those MIME types that your app can handle.
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
<p>
|
||||||
|
For example, the following snippet shows you how to add an intent filter that
|
||||||
|
triggers the activity <code>com.example.android.nfctransfer.ViewActivity</code>:
|
||||||
|
</p>
|
||||||
|
<pre>
|
||||||
|
<activity
|
||||||
|
android:name="com.example.android.nfctransfer.ViewActivity"
|
||||||
|
android:label="Android Beam Viewer" >
|
||||||
|
...
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.VIEW"/>
|
||||||
|
<category android:name="android.intent.category.DEFAULT"/>
|
||||||
|
...
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
</pre>
|
||||||
|
<p class="note">
|
||||||
|
<strong>Note:</strong> Android Beam file transfer is not the only source of an
|
||||||
|
{@link android.content.Intent#ACTION_VIEW ACTION_VIEW} intent. Other apps on the receiving
|
||||||
|
device can also send an {@link android.content.Intent} with this action.
|
||||||
|
Handling this situation is discussed in the section <a href="#GetDirectory"
|
||||||
|
>Get the directory from a content URI</a>.
|
||||||
|
</p>
|
||||||
|
<h2 id="RequestPermissions">Request File Permissions</h2>
|
||||||
|
<p>
|
||||||
|
To read files that Android Beam file transfer copies to the device, request the permission
|
||||||
|
{@link android.Manifest.permission#READ_EXTERNAL_STORAGE READ_EXTERNAL_STORAGE}. For example:
|
||||||
|
</p>
|
||||||
|
<pre>
|
||||||
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /></pre>
|
||||||
|
<p>
|
||||||
|
If you want to copy transferred files to your app's own storage area, request the permission
|
||||||
|
{@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE WRITE_EXTERNAL_STORAGE} instead.
|
||||||
|
{@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE WRITE_EXTERNAL_STORAGE} includes
|
||||||
|
{@link android.Manifest.permission#READ_EXTERNAL_STORAGE READ_EXTERNAL_STORAGE}.
|
||||||
|
</p>
|
||||||
|
<p class="note">
|
||||||
|
<strong>Note:</strong> As of Android 4.2.2 (API level 17), the permission
|
||||||
|
{@link android.Manifest.permission#READ_EXTERNAL_STORAGE READ_EXTERNAL_STORAGE} is
|
||||||
|
only enforced if the user chooses to do so. Future versions of the platform may require this
|
||||||
|
permission in all cases. To ensure forward compatibility, request the permission now, before it
|
||||||
|
becomes required.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Since your app has control over its internal storage area, you don't need to request
|
||||||
|
write permission to copy a transferred file to your internal storage area.
|
||||||
|
</p>
|
||||||
|
<h2 id="GetFilePath">Get the Directory for Copied Files</h2>
|
||||||
|
<p>
|
||||||
|
Android Beam file transfer copies all the files in a single transfer to one directory
|
||||||
|
on the receiving device. The URI in the content {@link android.content.Intent} sent by the
|
||||||
|
Android Beam file transfer notification points to the first transferred file. However, your
|
||||||
|
app may also receive an {@link android.content.Intent#ACTION_VIEW ACTION_VIEW} intent from a
|
||||||
|
source other than Android Beam file transfer. To determine how you should handle the incoming
|
||||||
|
{@link android.content.Intent}, you need to examine its scheme and authority.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
To get the scheme for the URI, call {@link android.net.Uri#getScheme() Uri.getScheme()}. The
|
||||||
|
following code snippet shows you how to determine the scheme and handle the URI accordingly:
|
||||||
|
</p>
|
||||||
|
<pre>
|
||||||
|
public class MainActivity extends Activity {
|
||||||
|
...
|
||||||
|
// A File object containing the path to the transferred files
|
||||||
|
private File mParentPath;
|
||||||
|
// Incoming Intent
|
||||||
|
private Intent mIntent;
|
||||||
|
...
|
||||||
|
/*
|
||||||
|
* Called from onNewIntent() for a SINGLE_TOP Activity
|
||||||
|
* or onCreate() for a new Activity. For onNewIntent(),
|
||||||
|
* remember to call setIntent() to store the most
|
||||||
|
* current Intent
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private void handleViewIntent() {
|
||||||
|
...
|
||||||
|
// Get the Intent action
|
||||||
|
mIntent = getIntent();
|
||||||
|
String action = mIntent.getAction();
|
||||||
|
/*
|
||||||
|
* For ACTION_VIEW, the Activity is being asked to display data.
|
||||||
|
* Get the URI.
|
||||||
|
*/
|
||||||
|
if (TextUtils.equals(action, Intent.ACTION_VIEW)) {
|
||||||
|
// Get the URI from the Intent
|
||||||
|
Uri beamUri = mIntent.getData();
|
||||||
|
/*
|
||||||
|
* Test for the type of URI, by getting its scheme value
|
||||||
|
*/
|
||||||
|
if (TextUtils.equals(beamUri.getScheme(), "file")) {
|
||||||
|
mParentPath = handleFileUri(beamUri);
|
||||||
|
} else if (TextUtils.equals(
|
||||||
|
beamUri.getScheme(), "content")) {
|
||||||
|
mParentPath = handleContentUri(beamUri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
...
|
||||||
|
}
|
||||||
|
...
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
<h3>Get the directory from a file URI</h3>
|
||||||
|
<p>
|
||||||
|
If the incoming {@link android.content.Intent} contains a file URI, the URI contains the
|
||||||
|
absolute file name of a file, including the full directory path and file name. For Android Beam
|
||||||
|
file transfer, the directory path points to the location of the other transferred files, if
|
||||||
|
any. To get the directory path, get the path part of the URI, which contains all of the URI
|
||||||
|
except the <code>file:</code> prefix. Create a {@link java.io.File} from the path part, then
|
||||||
|
get the parent path of the {@link java.io.File}:
|
||||||
|
</p>
|
||||||
|
<pre>
|
||||||
|
...
|
||||||
|
public String handleFileUri(Uri beamUri) {
|
||||||
|
// Get the path part of the URI
|
||||||
|
String fileName = beamUri.getPath();
|
||||||
|
// Create a File object for this filename
|
||||||
|
File copiedFile = new File(fileName);
|
||||||
|
// Get a string containing the file's parent directory
|
||||||
|
return copiedFile.getParent();
|
||||||
|
}
|
||||||
|
...
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<h3 id="GetDirectory">Get the directory from a content URI</h3>
|
||||||
|
<p>
|
||||||
|
If the incoming {@link android.content.Intent} contains a content URI, the URI may point to a
|
||||||
|
directory and file name stored in the {@link android.provider.MediaStore} content provider. You
|
||||||
|
can detect a content URI for {@link android.provider.MediaStore} by testing the URI's
|
||||||
|
authority value. A content URI for {@link android.provider.MediaStore} may come from
|
||||||
|
Android Beam file transfer or from another app, but in both cases you can retrieve a directory
|
||||||
|
and file name for the content URI.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
You can also receive an incoming {@link android.content.Intent#ACTION_VIEW ACTION_VIEW}
|
||||||
|
intent containing a content URI for a content provider other than
|
||||||
|
{@link android.provider.MediaStore}. In this case, the content URI doesn't contain the
|
||||||
|
{@link android.provider.MediaStore} authority value, and the content URI usually doesn't point
|
||||||
|
to a directory.
|
||||||
|
</p>
|
||||||
|
<p class="note">
|
||||||
|
<strong>Note:</strong> For Android Beam file transfer, you receive a content URI in the
|
||||||
|
{@link android.content.Intent#ACTION_VIEW ACTION_VIEW} intent if the first incoming file
|
||||||
|
has a MIME type of "audio/*", "image/*", or "video/*", indicating that the file is media-
|
||||||
|
related. Android Beam file transfer indexes the media files it transfers by running Media
|
||||||
|
Scanner on the directory where it stores transferred files. Media Scanner writes its results
|
||||||
|
to the {@link android.provider.MediaStore} content provider, then it passes a content URI
|
||||||
|
for the first file back to Android Beam file transfer. This content URI is the one you
|
||||||
|
receive in the notification {@link android.content.Intent}. To get the directory
|
||||||
|
of the first file, you retrieve it from {@link android.provider.MediaStore} using the content
|
||||||
|
URI.
|
||||||
|
</p>
|
||||||
|
<h3>Determine the content provider</h3>
|
||||||
|
<p>
|
||||||
|
To determine if you can retrieve a file directory from the content URI, determine the
|
||||||
|
the content provider associated with the URI by calling
|
||||||
|
{@link android.net.Uri#getAuthority Uri.getAuthority()} to get the URI's authority. The
|
||||||
|
result has two possible values:
|
||||||
|
</p>
|
||||||
|
<dl>
|
||||||
|
<dt>
|
||||||
|
{@link android.provider.MediaStore#AUTHORITY MediaStore.AUTHORITY}
|
||||||
|
</dt>
|
||||||
|
<dd>
|
||||||
|
The URI is for a file or files tracked by {@link android.provider.MediaStore}. Retrieve the
|
||||||
|
full file name from {@link android.provider.MediaStore}, and get directory from the file
|
||||||
|
name.
|
||||||
|
</dd>
|
||||||
|
<dt>
|
||||||
|
Any other authority value
|
||||||
|
</dt>
|
||||||
|
<dd>
|
||||||
|
A content URI from another content provider. Display the data associated with the content
|
||||||
|
URI, but don't get the file directory.
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
<p>
|
||||||
|
To get the directory for a {@link android.provider.MediaStore} content URI,
|
||||||
|
run a query that specifies the incoming content URI for the {@link android.net.Uri} argument and
|
||||||
|
the column {@link android.provider.MediaStore.MediaColumns#DATA MediaColumns.DATA} for the
|
||||||
|
projection. The returned {@link android.database.Cursor} contains the full path and name for
|
||||||
|
the file represented by the URI. This path also contains all the other files that Android Beam
|
||||||
|
file transfer just copied to the device.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
The following snippet shows you how to test the authority of the content URI and retrieve the
|
||||||
|
the path and file name for the transferred file:
|
||||||
|
</p>
|
||||||
|
<pre>
|
||||||
|
...
|
||||||
|
public String handleContentUri(Uri beamUri) {
|
||||||
|
// Position of the filename in the query Cursor
|
||||||
|
int filenameIndex;
|
||||||
|
// File object for the filename
|
||||||
|
File copiedFile;
|
||||||
|
// The filename stored in MediaStore
|
||||||
|
String fileName;
|
||||||
|
// Test the authority of the URI
|
||||||
|
if (!TextUtils.equals(beamUri.getAuthority(), MediaStore.AUTHORITY)) {
|
||||||
|
/*
|
||||||
|
* Handle content URIs for other content providers
|
||||||
|
*/
|
||||||
|
// For a MediaStore content URI
|
||||||
|
} else {
|
||||||
|
// Get the column that contains the file name
|
||||||
|
String[] projection = { MediaStore.MediaColumns.DATA };
|
||||||
|
Cursor pathCursor =
|
||||||
|
getContentResolver().query(beamUri, projection,
|
||||||
|
null, null, null);
|
||||||
|
// Check for a valid cursor
|
||||||
|
if (pathCursor != null &&
|
||||||
|
pathCursor.moveToFirst()) {
|
||||||
|
// Get the column index in the Cursor
|
||||||
|
filenameIndex = pathCursor.getColumnIndex(
|
||||||
|
MediaStore.MediaColumns.DATA);
|
||||||
|
// Get the full file name including path
|
||||||
|
fileName = pathCursor.getString(filenameIndex);
|
||||||
|
// Create a File object for the filename
|
||||||
|
copiedFile = new File(fileName);
|
||||||
|
// Return the parent directory of the file
|
||||||
|
return new File(copiedFile.getParent());
|
||||||
|
} else {
|
||||||
|
// The query didn't work; return null
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
...
|
||||||
|
</pre>
|
||||||
|
<p>
|
||||||
|
To learn more about retrieving data from a content provider, see the section
|
||||||
|
<a href="{@docRoot}guide/topics/providers/content-provider-basics.html#SimpleQuery"
|
||||||
|
>Retrieving Data from the Provider</a>.
|
||||||
|
</p>
|
||||||
294
docs/html/training/beam-files/send-files.jd
Normal file
294
docs/html/training/beam-files/send-files.jd
Normal file
@@ -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>
|
||||||
@@ -423,7 +423,22 @@ include the action bar on devices running Android 2.1 or higher."
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="nav-section">
|
||||||
|
<div class="nav-section-header">
|
||||||
|
<a href="<?cs var:toroot ?>training/beam-files/index.html"
|
||||||
|
description=
|
||||||
|
"How to transfer files between devices using the NFC Android Beam feature."
|
||||||
|
>Sharing Files with NFC</a>
|
||||||
|
</div>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="<?cs var:toroot ?>training/beam-files/send-files.html"
|
||||||
|
>Sending Files to Another Device</a>
|
||||||
|
</li>
|
||||||
|
<li><a href="<?cs var:toroot ?>training/beam-files/receive-files.html"
|
||||||
|
>Receiving Files from Another Device</a></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
<li class="nav-section">
|
<li class="nav-section">
|
||||||
<div class="nav-section-header">
|
<div class="nav-section-header">
|
||||||
<a href="<?cs var:toroot ?>training/basics/network-ops/index.html"
|
<a href="<?cs var:toroot ?>training/basics/network-ops/index.html"
|
||||||
@@ -498,7 +513,7 @@ include the action bar on devices running Android 2.1 or higher."
|
|||||||
"How to design a robust conflict resolution strategy for apps that save data to the cloud."
|
"How to design a robust conflict resolution strategy for apps that save data to the cloud."
|
||||||
>Resolving Cloud Save Conflicts
|
>Resolving Cloud Save Conflicts
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-section">
|
<li class="nav-section">
|
||||||
<div class="nav-section-header">
|
<div class="nav-section-header">
|
||||||
@@ -1181,7 +1196,6 @@ include the action bar on devices running Android 2.1 or higher."
|
|||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<ul>
|
<ul>
|
||||||
|
|
||||||
<li>
|
<li>
|
||||||
<a href="<?cs var:toroot ?>training/articles/security-tips.html"
|
<a href="<?cs var:toroot ?>training/articles/security-tips.html"
|
||||||
description=
|
description=
|
||||||
|
|||||||
Reference in New Issue
Block a user