summaryrefslogtreecommitdiffstats
path: root/docs/html/training/secure-file-sharing/request-file.jd
diff options
context:
space:
mode:
Diffstat (limited to 'docs/html/training/secure-file-sharing/request-file.jd')
-rw-r--r--docs/html/training/secure-file-sharing/request-file.jd147
1 files changed, 147 insertions, 0 deletions
diff --git a/docs/html/training/secure-file-sharing/request-file.jd b/docs/html/training/secure-file-sharing/request-file.jd
new file mode 100644
index 0000000..116701d
--- /dev/null
+++ b/docs/html/training/secure-file-sharing/request-file.jd
@@ -0,0 +1,147 @@
+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;
+ ...
+ &#64;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.
+ */
+ &#64;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>