45edbb701a
Change-Id: Idad8840dec02150733f23cfefdeaf152a260f63a
148 lines
5.4 KiB
Plaintext
148 lines
5.4 KiB
Plaintext
page.title=Requesting a Shared File
|
|
|
|
trainingnavtop=true
|
|
@jd:body
|
|
|
|
|
|
<div id="tb-wrapper">
|
|
<div id="tb">
|
|
|
|
<h2>This lesson teaches you to</h2>
|
|
<ol>
|
|
<li><a href="#SendRequest">Send a Request for the File</a></li>
|
|
<li><a href="#OpenFile">Access the Requested File</a>
|
|
</ol>
|
|
|
|
<h2>You should also read</h2>
|
|
<ul>
|
|
<li>
|
|
<a href="{@docRoot}guide/components/intents-filters.html">Intents and Intent Filters</a>
|
|
</li>
|
|
<li>
|
|
<a href="{@docRoot}guide/topics/providers/content-provider-basics.html#SimpleQuery"
|
|
>Retrieving Data from the Provider</a>
|
|
</li>
|
|
</ul>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<p>
|
|
When an app wants to access a file shared by another app, the requesting app (the client)
|
|
usually sends a request to the app sharing the files (the server). In most cases, the request
|
|
starts an {@link android.app.Activity} in the server app that displays the files it can share.
|
|
The user picks a file, after which the server app returns the file's content URI to the
|
|
client app.
|
|
</p>
|
|
<p>
|
|
This lesson shows you how a client app requests a file from a server app, receives the file's
|
|
content URI from the server app, and opens the file using the content URI.
|
|
</p>
|
|
|
|
<h2 id="SendRequest">Send a Request for the File</h2>
|
|
<p>
|
|
To request a file from the server app, the client app calls
|
|
{@link android.app.Activity#startActivityForResult startActivityForResult} with an
|
|
{@link android.content.Intent} containing the action such as
|
|
{@link android.content.Intent#ACTION_PICK ACTION_PICK} and a MIME type that the client app
|
|
can handle.
|
|
</p>
|
|
<p>
|
|
For example, the following code snippet demonstrates how to send an
|
|
{@link android.content.Intent} to a server app in order to start the
|
|
{@link android.app.Activity} described in <a href="share-file.html#SendURI"
|
|
>Sharing a File</a>:
|
|
</p>
|
|
<pre>
|
|
public class MainActivity extends Activity {
|
|
private Intent mRequestFileIntent;
|
|
private ParcelFileDescriptor mInputPFD;
|
|
...
|
|
@Override
|
|
protected void onCreate(Bundle savedInstanceState) {
|
|
super.onCreate(savedInstanceState);
|
|
setContentView(R.layout.activity_main);
|
|
mRequestFileIntent = new Intent(Intent.ACTION_PICK);
|
|
mRequestFileIntent.setType("image/jpg");
|
|
...
|
|
}
|
|
...
|
|
protected void requestFile() {
|
|
/**
|
|
* When the user requests a file, send an Intent to the
|
|
* server app.
|
|
* files.
|
|
*/
|
|
startActivityForResult(mRequestFileIntent, 0);
|
|
...
|
|
}
|
|
...
|
|
}
|
|
</pre>
|
|
<h2 id="OpenFile">Access the Requested File</h2>
|
|
<p>
|
|
The server app sends the file's content URI back to the client app in an
|
|
{@link android.content.Intent}. This {@link android.content.Intent} is passed to the client
|
|
app in its override of {@link android.app.Activity#onActivityResult onActivityResult()}. Once
|
|
the client app has the file's content URI, it can access the file by getting its
|
|
{@link java.io.FileDescriptor}.
|
|
</p>
|
|
<p>
|
|
<p>
|
|
File security is preserved in this process because the content URI is the only piece of data
|
|
that the client app receives. Since this URI doesn't contain a directory path, the client app
|
|
can't discover and open any other files in the server app. Only the client app gets access to
|
|
the file, and only for the permissions granted by the server app. The permissions are temporary,
|
|
so once the client app's task stack is finished, the file is no longer accessible outside the
|
|
server app.
|
|
</p>
|
|
<p>
|
|
The next snippet demonstrates how the client app handles the
|
|
{@link android.content.Intent} sent from the server app, and how the client app gets the
|
|
{@link java.io.FileDescriptor} using the content URI:
|
|
</p>
|
|
<pre>
|
|
/*
|
|
* When the Activity of the app that hosts files sets a result and calls
|
|
* finish(), this method is invoked. The returned Intent contains the
|
|
* content URI of a selected file. The result code indicates if the
|
|
* selection worked or not.
|
|
*/
|
|
@Override
|
|
public void onActivityResult(int requestCode, int resultCode,
|
|
Intent returnIntent) {
|
|
// If the selection didn't work
|
|
if (resultCode != RESULT_OK) {
|
|
// Exit without doing anything else
|
|
return;
|
|
} else {
|
|
// Get the file's content URI from the incoming Intent
|
|
Uri returnUri = returnIntent.getData();
|
|
/*
|
|
* Try to open the file for "read" access using the
|
|
* returned URI. If the file isn't found, write to the
|
|
* error log and return.
|
|
*/
|
|
try {
|
|
/*
|
|
* Get the content resolver instance for this context, and use it
|
|
* to get a ParcelFileDescriptor for the file.
|
|
*/
|
|
mInputPFD = getContentResolver().openFileDescriptor(returnUri, "r");
|
|
} catch (FileNotFoundException e) {
|
|
e.printStackTrace();
|
|
Log.e("MainActivity", "File not found.");
|
|
return;
|
|
}
|
|
// Get a regular file descriptor for the file
|
|
FileDescriptor fd = mInputPFD.getFileDescriptor();
|
|
...
|
|
}
|
|
}
|
|
</pre>
|
|
<p>
|
|
The method {@link android.content.ContentResolver#openFileDescriptor openFileDescriptor()}
|
|
returns a {@link android.os.ParcelFileDescriptor} for the file. From this object, the client
|
|
app gets a {@link java.io.FileDescriptor} object, which it can then use to read the file.
|
|
</p>
|