blob: b34f0fa04f8cb5fe5c228dc173c7c1a2eafc4677 [file] [log] [blame]
Scott Mainc059fa42011-02-14 14:20:22 -08001page.title=Copy and Paste
Scott Main64461bf2013-04-11 19:32:08 -07002page.tags="clipboardmanager","clipdata","input"
Joe Malindd05f182011-01-19 14:33:23 -08003@jd:body
4<div id="qv-wrapper">
5 <div id="qv">
6 <h2>Quickview</h2>
7 <ul>
8 <li>
9 A clipboard-based framework for copying and pasting data.
10 </li>
11 <li>
12 Supports both simple and complex data, including text strings, complex data
13 structures, text and binary stream data, and application assets.
14 </li>
15 <li>
16 Copies and pastes simple text directly to and from the clipboard.
17 </li>
18 <li>
19 Copies and pastes complex data using a content provider.
20 </li>
21 <li>
22 Requires API 11.
23 </li>
24 </ul>
25 <h2>In this document</h2>
26 <ol>
27 <li>
28 <a href="#Clipboard">The Clipboard Framework</a>
29 </li>
30 <li>
31 <a href="#ClipboardClasses">Clipboard Classes</a>
32 <ol>
33 <li>
34 <a href="#ClipboardManager">ClipboardManager</a>
35 </li>
36 <li>
37 <a href="#ClipClasses">
38 ClipData, ClipDescription, and ClipData.Item
39 </a>
40 </li>
41 <li>
42 <a href="#ClipDataMethods">ClipData convenience methods</a>
43 </li>
44 <li>
45 <a href="#CoerceToText">Coercing the clipboard data to text</a>
46 </li>
47 </ol>
48 </li>
49 <li>
50 <a href="#Copying">Copying to the Clipboard</a>
51 </li>
52 <li>
53 <a href="#Pasting">Pasting from the Clipboard</a>
54 <ol>
55 <li>
56 <a href="#PastePlainText">Pasting plain text</a>
57 </li>
58 <li>
59 <a href="#PasteContentUri">Pasting data from a content URI</a>
60 </li>
61 <li>
62 <a href="#PasteIntent">Pasting an Intent</a>
63 </li>
64 </ol>
65 </li>
66 <li>
67 <a href="#Provider">Using Content Providers to Copy Complex Data</a>
68 <ol>
69 <li>
70 <a href="#Encoding">Encoding an identifier on the URI</a>
71 </li>
72 <li>
73 <a href="#Records">Copying data structures</a>
74 </li>
75 <li>
76 <a href="#Streams">Copying data streams</a>
77 </li>
78 </ol>
79 </li>
80 <li>
81 <a href="#DataDesign">Designing Effective Copy/Paste Functionality</a>
82 </li>
83 </ol>
84 <h2>Key classes</h2>
85 <ol>
86 <li>
87 {@link android.content.ClipboardManager ClipboardManager}
88 </li>
89 <li>
90 {@link android.content.ClipData ClipData}
91 </li>
92 <li>
93 {@link android.content.ClipData.Item ClipData.Item}
94 </li>
95 <li>
96 {@link android.content.ClipDescription ClipDescription}
97 </li>
98 <li>
99 {@link android.net.Uri Uri}
100 </li>
101 <li>
102 {@link android.content.ContentProvider}
103 </li>
104 <li>
105 {@link android.content.Intent Intent}
106 </li>
107 </ol>
108 <h2>Related Samples</h2>
109 <ol>
110 <li>
111 <a href="{@docRoot}resources/samples/NotePad/index.html">
112 Note Pad sample application</a>
113 </li>
114 </ol>
115 <h2>See also</h2>
116 <ol>
117 <li>
118 <a href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a>
119 </li>
120 </ol>
121 </div>
122</div>
123<p>
124 Android provides a powerful clipboard-based framework for copying and pasting. It
125 supports both simple and complex data types, including text strings, complex data
126 structures, text and binary stream data, and even application assets. Simple text data is stored
127 directly in the clipboard, while complex data is stored as a reference that the pasting
128 application resolves with a content provider. Copying and pasting works both within an
129 application and between applications that implement the framework.
130</p>
131
132<p>
133 Since a part of the framework uses content providers, this topic assumes some
134 familiarity with the Android Content Provider API, which is described in the topic
135 <a href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a>.
136</p>
137<h2 id="Clipboard">The Clipboard Framework</h2>
138<p>
139 When you use the clipboard framework, you put data into a clip object, and then
140 put the clip object on the system-wide clipboard. The clip object can take one of three forms:
141</p>
142 <dl>
143 <dt>Text</dt>
144 <dd>
145 A text string. You put the string directly into the clip object, which you then put onto
146 the clipboard. To paste the string, you get the clip object from the clipboard and copy
147 the string to into your application's storage.
148 </dd>
149 <dt>URI</dt>
150 <dd>
151 A {@link android.net.Uri} object representing any form of URI. This is primarily for
152 copying complex data from a content provider. To copy data, you put a
153 {@link android.net.Uri} object into a clip object and put the clip object onto
154 the clipboard. To paste the data, you get the clip object, get the
155 {@link android.net.Uri} object, resolve it to a data source such as a content provider,
156 and copy the data from the source into your application's storage.
157 </dd>
158 <dt>Intent</dt>
159 <dd>
160 An {@link android.content.Intent}. This supports copying application shortcuts. To copy
161 data, you create an Intent, put it into a clip object, and put the clip object onto the
162 clipboard. To paste the data, you get the clip object and then copy the Intent object
163 into your application's memory area.
164 </dd>
165 </dl>
166<p>
167 The clipboard holds only one clip object at a time. When an application puts a clip object on
168 the clipboard, the previous clip object disappears.
169</p>
170<p>
171 If you want to allow users to paste data into your application, you don't have to handle all
172 types of data. You can examine the data on the clipboard before you give users the option to
173 paste it. Besides having a certain data form, the clip object also contains metadata that tells
174 you what MIME type or types are available. This metadata helps you decide if your application
175 can do something useful with the clipboard data. For example, if you have an application that
176 primarily handles text you may want to ignore clip objects that contain a URI or Intent.
177</p>
178<p>
179 You may also want to allow users to paste text regardless of the form of data on the
180 clipboard. To do this, you can force the clipboard data into a text representation, and then
181 paste this text. This is described in the section <a href="#CoerceToText">Coercing the
182 clipboard to text</a>.
183</p>
184<h2 id="ClipboardClasses">Clipboard Classes</h2>
185<p>
186 This section describes the classes used by the clipboard framework.
187</p>
188<h3 id="ClipboardManager">ClipboardManager</h3>
189<p>
190 In the Android system, the system clipboard is represented by the global
191 {@link android.content.ClipboardManager} class. You do not instantiate this
192 class directly; instead, you get a reference to it by invoking
193 {@link android.content.Context#getSystemService(String) getSystemService(CLIPBOARD_SERVICE)}.
194</p>
195<h3 id="ClipClasses">ClipData, ClipData.Item, and ClipDescription</h3>
196<p>
197 To add data to the clipboard, you create a {@link android.content.ClipData} object that
198 contains both a description of the data and the data itself. The clipboard holds only one
199 {@link android.content.ClipData} at a time. A {@link android.content.ClipData} contains a
200 {@link android.content.ClipDescription} object and one or more
201 {@link android.content.ClipData.Item} objects.
202</p>
203<p>
204 A {@link android.content.ClipDescription} object contains metadata about the clip. In
205 particular, it contains an array of available MIME types for the clip's data. When you put a
206 clip on the clipboard, this array is available to pasting applications, which can examine it to
207 see if they can handle any of available the MIME types.
208</p>
209<p>
210 A {@link android.content.ClipData.Item} object contains the text, URI, or Intent data:
211</p>
212<dl>
213 <dt>Text</dt>
214 <dd>
215 A {@link java.lang.CharSequence}.
216 </dd>
217 <dt>URI</dt>
218 <dd>
219 A {@link android.net.Uri}. This usually contains a content provider URI, although any
220 URI is allowed. The application that provides the data puts the URI on the clipboard.
221 Applications that want to paste the data get the URI from the clipboard and use it to
222 access the content provider (or other data source) and retrieve the data.
223 </dd>
224 <dt>Intent</dt>
225 <dd>
226 An {@link android.content.Intent}. This data type allows you to copy an application shortcut
227 to the clipboard. Users can then paste the shortcut into their applications for later use.
228 </dd>
229</dl>
230<p>
231 You can add more than one {@link android.content.ClipData.Item} object to a clip. This allows
232 users to copy and paste multiple selections as a single clip. For example, if you have a list
233 widget that allows the user to select more than one item at a time, you can copy all the items
234 to the clipboard at once. To do this, you create a separate
235 {@link android.content.ClipData.Item} for each list item, and then you add the
236 {@link android.content.ClipData.Item} objects to the {@link android.content.ClipData} object.
237</p>
238<h3 id="ClipDataMethods">ClipData convenience methods</h3>
239<p>
240 The {@link android.content.ClipData} class provides static convenience methods for creating
241 a {@link android.content.ClipData} object with a single {@link android.content.ClipData.Item}
242 object and a simple {@link android.content.ClipDescription} object:
243</p>
244<dl>
245 <dt>
246{@link android.content.ClipData#newPlainText(CharSequence,CharSequence) newPlainText(label, text)}
247 </dt>
248 <dd>
249 Returns a {@link android.content.ClipData} object whose single
250 {@link android.content.ClipData.Item} object contains a text string. The
251 {@link android.content.ClipDescription} object's label is set to <code>label</code>.
252 The single MIME type in {@link android.content.ClipDescription} is
253 {@link android.content.ClipDescription#MIMETYPE_TEXT_PLAIN}.
254 <p>
255 Use
256{@link android.content.ClipData#newPlainText(CharSequence,CharSequence) newPlainText()}
257 to create a clip from a text string.
258 </dd>
259 <dt>
260{@link android.content.ClipData#newUri(ContentResolver, CharSequence, Uri) newUri(resolver, label, URI)}
261 </dt>
262 <dd>
263 Returns a {@link android.content.ClipData} object whose single
264 {@link android.content.ClipData.Item} object contains a URI. The
265 {@link android.content.ClipDescription} object's label is set to <code>label</code>.
266 If the URI is a content URI ({@link android.net.Uri#getScheme() Uri.getScheme()} returns
267 <code>content:</code>), the method uses the {@link android.content.ContentResolver} object
268 provided in <code>resolver</code> to retrieve the available MIME types from the
269 content provider and store them in {@link android.content.ClipDescription}. For a URI that
270 is not a <code>content:</code> URI, the method sets the MIME type to
271 {@link android.content.ClipDescription#MIMETYPE_TEXT_URILIST}.
272 <p>
273 Use
274{@link android.content.ClipData#newUri(ContentResolver, CharSequence, Uri) newUri()}
275 to create a clip from a URI, particularly a <code>content:</code> URI.
276 </p>
277 </dd>
278 <dt>
279 {@link android.content.ClipData#newIntent(CharSequence, Intent) newIntent(label, intent)}
280 </dt>
281 <dd>
282 Returns a {@link android.content.ClipData} object whose single
283 {@link android.content.ClipData.Item} object contains an {@link android.content.Intent}.
284 The {@link android.content.ClipDescription} object's label is set to <code>label</code>.
285 The MIME type is set to {@link android.content.ClipDescription#MIMETYPE_TEXT_INTENT}.
286 <p>
287 Use
288{@link android.content.ClipData#newIntent(CharSequence, Intent) newIntent()}
289 to create a clip from an Intent object.
290 </dd>
291</dl>
292<h3 id="CoerceToText">Coercing the clipboard data to text</h3>
293<p>
294 Even if your application only handles text, you can copy non-text data from the
295 clipboard by converting it with the method
296 {@link android.content.ClipData.Item#coerceToText(Context) ClipData.Item.coerceToText()}.
297</p>
298<p>
299 This method converts the data in {@link android.content.ClipData.Item} to text and
300 returns a {@link java.lang.CharSequence}. The value that
301 {@link android.content.ClipData.Item#coerceToText(Context) ClipData.Item.coerceToText()}
302 returns is based on the form of data in {@link android.content.ClipData.Item}:
303</p>
304<dl>
305 <dt><em>Text</em></dt>
306 <dd>
307 If {@link android.content.ClipData.Item} is text
308 ({@link android.content.ClipData.Item#getText()} is not null),
309 {@link android.content.ClipData.Item#coerceToText(Context) coerceToText()} returns the
310 text.
311 </dd>
312 <dt><em>URI</em></dt>
313 <dd>
314 If {@link android.content.ClipData.Item} is a URI
315 ({@link android.content.ClipData.Item#getUri()} is not null),
316 {@link android.content.ClipData.Item#coerceToText(Context) coerceToText()} tries to use
317 it as a content URI:
318 <ul>
319 <li>
320 If the URI is a content URI and the provider can return a text stream,
321 {@link android.content.ClipData.Item#coerceToText(Context) coerceToText()} returns
322 a text stream.
323 </li>
324 <li>
325 If the URI is a content URI but the provider does not offer a text stream,
326 {@link android.content.ClipData.Item#coerceToText(Context) coerceToText()} returns
327 a representation of the URI. The representation is the same as that returned by
328 {@link android.net.Uri#toString() Uri.toString()}.
329 </li>
330 <li>
331 If the URI is not a content URI,
332 {@link android.content.ClipData.Item#coerceToText(Context) coerceToText()} returns
333 a representation of the URI. The representation is the same as that returned by
334 {@link android.net.Uri#toString() Uri.toString()}.
335 </li>
336 </ul>
337 </dd>
338 <dt><em>Intent</em></dt>
339 <dd>
340 If {@link android.content.ClipData.Item} is an Intent
341 ({@link android.content.ClipData.Item#getIntent()} is not null),
342 {@link android.content.ClipData.Item#coerceToText(Context) coerceToText()} converts it to
343 an Intent URI and returns it. The representation is the same as that returned by
344 {@link android.content.Intent#toUri(int) Intent.toUri(URI_INTENT_SCHEME)}.
345 </dd>
346</dl>
347<p>
348 The clipboard framework is summarized in Figure 1. To copy data, an application puts a
349 {@link android.content.ClipData} object on the {@link android.content.ClipboardManager} global
350 clipboard. The {@link android.content.ClipData} contains one or more
351 {@link android.content.ClipData.Item} objects and one
352 {@link android.content.ClipDescription} object. To paste data, an application gets the
353 {@link android.content.ClipData}, gets its MIME type from the
354 {@link android.content.ClipDescription}, and gets the data either from
355 the {@link android.content.ClipData.Item} or from the content provider referred to by
356 {@link android.content.ClipData.Item}.
357</p>
358 <a name="framework"></a>
359 <img
360 src="{@docRoot}images/ui/clipboard/copy_paste_framework.png"
361 alt="A block diagram of the copy and paste framework" height="400px" id="figure1" />
362<p class="img-caption">
363 <strong>Figure 1.</strong> The Android clipboard framework
364</p>
365<h2 id="Copying">Copying to the Clipboard</h2>
366<p>
367 As described previously, to copy data to the clipboard you get a handle to the global
368 {@link android.content.ClipboardManager} object, create a {@link android.content.ClipData}
369 object, add a {@link android.content.ClipDescription} and one or more
370 {@link android.content.ClipData.Item} objects to it, and add the finished
371 {@link android.content.ClipData} object to the {@link android.content.ClipboardManager} object.
372 This is described in detail in the following procedure:
373</p>
374<ol>
375 <li>
376 If you are copying data using a content URI, set up a content
377 provider.
378 <p>
379 The <a href="{@docRoot}resources/samples/NotePad/index.html">
380 Note Pad</a> sample application is an example of using a content provider for
381 copying and pasting. The
382<a href="{@docRoot}resources/samples/NotePad/src/com/example/android/notepad/NotePadProvider.html">
383 NotePadProvider</a> class implements the content provider. The
384<a href="{@docRoot}resources/samples/NotePad/src/com/example/android/notepad/NotePad.html">
385 NotePad</a> class defines a contract between the provider and other applications,
386 including the supported MIME types.
387 </p>
388 </li>
389 <li>
390 Get the system clipboard:
391<pre>
392
393...
394
395// if the user selects copy
396case R.id.menu_copy:
397
398// Gets a handle to the clipboard service.
399ClipboardManager clipboard = (ClipboardManager)
400 getSystemService(Context.CLIPBOARD_SERVICE);
401</pre>
402 </li>
403 <li>
404 <p>
405 Copy the data to a new {@link android.content.ClipData} object:
406 </p>
407 <ul>
408 <li>
409 <h4>For text</h4>
410<pre>
411// Creates a new text clip to put on the clipboard
412ClipData clip = ClipData.newPlainText(&quot;simple text&quot;,&quot;Hello, World!&quot;);
413</pre>
414 </li>
415 <li>
416 <h4>For a URI</h4>
417 <p>
418 This snippet constructs a URI by encoding a record ID onto the content URI
419 for the provider. This technique is covered in more detail
420 in the section <a href="#Encoding">Encoding an identifier on the URI</a>:
421 </p>
422<pre>
423// Creates a Uri based on a base Uri and a record ID based on the contact's last name
424// Declares the base URI string
425private static final String CONTACTS = &quot;content:&#47;&#47;com.example.contacts&quot;;
426
427// Declares a path string for URIs that you use to copy data
428private static final String COPY_PATH = &quot;/copy&quot;;
429
430// Declares the Uri to paste to the clipboard
431Uri copyUri = Uri.parse(CONTACTS + COPY_PATH + &quot;/&quot; + lastName);
432
433...
434
435// Creates a new URI clip object. The system uses the anonymous getContentResolver() object to
436// get MIME types from provider. The clip object's label is &quot;URI&quot;, and its data is
437// the Uri previously created.
438ClipData clip = ClipData.newUri(getContentResolver(),&quot;URI&quot;,copyUri);
439</pre>
440 </li>
441 <li>
442 <h4>For an Intent</h4>
443 <p>
444 This snippet constructs an Intent for an application
445 and then puts it in the clip object:
446 </p>
447<pre>
448// Creates the Intent
449Intent appIntent = new Intent(this, com.example.demo.myapplication.class);
450
451...
452
453// Creates a clip object with the Intent in it. Its label is &quot;Intent&quot; and its data is
454// the Intent object created previously
455ClipData clip = ClipData.newIntent(&quot;Intent&quot;,appIntent);
456</pre>
457 </li>
458 </ul>
459 </li>
460 <li>
461 Put the new clip object on the clipboard:
462<pre>
463// Set the clipboard's primary clip.
464clipboard.setPrimaryClip(clip);
465</pre>
466 </li>
467</ol>
468<h2 id="Pasting">Pasting from the Clipboard</h2>
469<p>
470 As described previously, you paste data from the clipboard by getting the global clipboard
471 object, getting the clip object, looking at its data, and if possible copying the data from
472 the clip object to your own storage. This section describes in detail how to do this for
473 the three forms of clipboard data.
474</p>
475<h3 id="PastePlainText">Pasting plain text</h3>
476<p>
477 To paste plain text, first get the global clipboard and verify that it can return plain text.
478 Then get the clip object and copy its text to your own storage using
479 {@link android.content.ClipData.Item#getText()}, as described in the following procedure:
480</p>
481<ol>
482 <li>
483 Get the global {@link android.content.ClipboardManager} object using
484 {@link android.content.Context#getSystemService(String) getSystemService(CLIPBOARD_SERVICE)}. Also
485 declare a global variable to contain the pasted text:
486<pre>
487ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
488
489String pasteData = &quot;&quot;;
490
491</pre>
492 </li>
493 <li>
494 Next, determine if you should enable or disable the &quot;paste&quot; option in the
495 current Activity. You should verify that the clipboard contains a clip and that you
496 can handle the type of data represented by the clip:
497<pre>
498// Gets the ID of the &quot;paste&quot; menu item
499MenuItem mPasteItem = menu.findItem(R.id.menu_paste);
500
501// If the clipboard doesn't contain data, disable the paste menu item.
502// If it does contain data, decide if you can handle the data.
503if (!(clipboard.hasPrimaryClip())) {
504
505 mPasteItem.setEnabled(false);
506
507 } else if (!(clipboard.getPrimaryClipDescription().hasMimeType(MIMETYPE_TEXT_PLAIN))) {
508
509 // This disables the paste menu item, since the clipboard has data but it is not plain text
510 mPasteItem.setEnabled(false);
511 } else {
512
513 // This enables the paste menu item, since the clipboard contains plain text.
514 mPasteItem.setEnabled(true);
515 }
516}
517</pre>
518 </li>
519 <li>
520 Copy the data from the clipboard. This point in the program is only reachable if the
521 &quot;paste&quot; menu item is enabled, so you can assume that the clipboard contains
522 plain text. You do not yet know if it contains a text string or a URI that points to plain
523 text. The following snippet tests this, but it only shows the code for handling plain text:
524<pre>
525// Responds to the user selecting &quot;paste&quot;
526case R.id.menu_paste:
527
528// Examines the item on the clipboard. If getText() does not return null, the clip item contains the
529// text. Assumes that this application can only handle one item at a time.
530 ClipData.Item item = clipboard.getPrimaryClip().getItemAt(0);
531
532// Gets the clipboard as text.
533pasteData = item.getText();
534
535// If the string contains data, then the paste operation is done
536if (pasteData != null) {
537 return;
538
539// The clipboard does not contain text. If it contains a URI, attempts to get data from it
540} else {
541 Uri pasteUri = item.getUri();
542
543 // If the URI contains something, try to get text from it
544 if (pasteUri != null) {
545
546 // calls a routine to resolve the URI and get data from it. This routine is not
547 // presented here.
548 pasteData = resolveUri(Uri);
549 return;
550 } else {
551
552 // Something is wrong. The MIME type was plain text, but the clipboard does not contain either
553 // text or a Uri. Report an error.
554 Log.e(&quot;Clipboard contains an invalid data type&quot;);
555 return;
556 }
557}
558</pre>
559 </li>
560</ol>
561<h3 id="PasteContentUri">Pasting data from a content URI</h3>
562<p>
563 If the {@link android.content.ClipData.Item} object contains a content URI and you
564 have determined that you can handle one of its MIME types, create a
565 {@link android.content.ContentResolver} and then call the appropriate content provider
566 method to retrieve the data.
567</p>
568<p>
569 The following procedure describes how to get data from a content provider based on a
570 content URI on the clipboard. It checks that a MIME type that the application can use
571 is available from the provider:
572</p>
573<ol>
574 <li>
575 Declare a global variable to contain the MIME type:
576<pre>
577// Declares a MIME type constant to match against the MIME types offered by the provider
578public static final String MIME_TYPE_CONTACT = &quot;vnd.android.cursor.item/vnd.example.contact&quot;
579</pre>
580 </li>
581 <li>
582 Get the global clipboard. Also get a content resolver so you can access the content
583 provider:
584<pre>
585// Gets a handle to the Clipboard Manager
586ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
587
588// Gets a content resolver instance
589ContentResolver cr = getContentResolver();
590</pre>
591 </li>
592 <li>
593 Get the primary clip from the clipboard, and get its contents as a URI:
594<pre>
595// Gets the clipboard data from the clipboard
596ClipData clip = clipboard.getPrimaryClip();
597
598if (clip != null) {
599
600 // Gets the first item from the clipboard data
601 ClipData.Item item = clip.getItemAt(0);
602
603 // Tries to get the item's contents as a URI
604 Uri pasteUri = item.getUri();
605</pre>
606 </li>
607 <li>
608 Test to see if the URI is a content URI by calling
609 {@link android.content.ContentResolver#getType(Uri) getType(Uri)}. This method returns
610 null if <code>Uri</code> does not point to a valid content provider:
611<pre>
612 // If the clipboard contains a URI reference
613 if (pasteUri != null) {
614
615 // Is this a content URI?
616 String uriMimeType = cr.getType(pasteUri);
617</pre>
618 </li>
619 <li>
620 Test to see if the content provider supports a MIME type that the current application
621 understands. If it does, call
622 {@link android.content.ContentResolver#query(Uri, String[], String, String[], String)
623 ContentResolver.query()} to get the data. The return value is a
624 {@link android.database.Cursor}:
625<pre>
626 // If the return value is not null, the Uri is a content Uri
627 if (uriMimeType != null) {
628
629 // Does the content provider offer a MIME type that the current application can use?
630 if (uriMimeType.equals(MIME_TYPE_CONTACT)) {
631
632 // Get the data from the content provider.
633 Cursor pasteCursor = cr.query(uri, null, null, null, null);
634
635 // If the Cursor contains data, move to the first record
636 if (pasteCursor != null) {
637 if (pasteCursor.moveToFirst()) {
638
639 // get the data from the Cursor here. The code will vary according to the
640 // format of the data model.
641 }
642 }
643
644 // close the Cursor
645 pasteCursor.close();
646 }
647 }
648 }
649}
650</pre>
651 </li>
652</ol>
653<h3 id="PasteIntent">Pasting an Intent</h3>
654<p>
655 To paste an Intent, first get the global clipboard. Examine the
656 {@link android.content.ClipData.Item} object to see if it contains an Intent. Then call
657 {@link android.content.ClipData.Item#getIntent()} to copy the Intent to your own storage.
658 The following snippet demonstrates this:
659</p>
660<pre>
661// Gets a handle to the Clipboard Manager
662ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
663
664// Checks to see if the clip item contains an Intent, by testing to see if getIntent() returns null
665Intent pasteIntent = clipboard.getPrimaryClip().getItemAt(0).getIntent();
666
667if (pasteIntent != null) {
668
669 // handle the Intent
670
671} else {
672
673 // ignore the clipboard, or issue an error if your application was expecting an Intent to be
674 // on the clipboard
675}
676</pre>
677<h2 id="Provider">Using Content Providers to Copy Complex Data</h2>
678<p>
679 Content providers support copying complex data such as database records or file streams.
680 To copy the data, you put a content URI on the clipboard. Pasting applications then get this
681 URI from the clipboard and use it to retrieve database data or file stream descriptors.
682</p>
683<p>
684 Since the pasting application only has the content URI for your data, it needs to know which
685 piece of data to retrieve. You can provide this information by encoding an identifier for the
686 data on the URI itself, or you can provide a unique URI that will return the data you want to
687 copy. Which technique you choose depends on the organization of your data.
688</p>
689<p>
690 The following sections describe how to set up URIs, how to provide complex data, and how to
691 provide file streams. The descriptions assume that you are familiar with the general principles
692 of content provider design.
693</p>
694<h3 id="Encoding">Encoding an identifier on the URI</h3>
695<p>
696 A useful technique for copying data to the clipboard with a URI is to encode an identifier for
697 the data on the URI itself. Your content provider can then get the identifier from the URI and
698 use it to retrieve the data. The pasting application doesn't have to know that the identifier
699 exists; all it has to do is get your &quot;reference&quot; (the URI plus the identifier) from
700 the clipboard, give it your content provider, and get back the data.
701</p>
702<p>
703 You usually encode an identifier onto a content URI by concatenating it to the end of the URI.
704 For example, suppose you define your provider URI as the following string:
705</p>
706<pre>
707&quot;content://com.example.contacts&quot;
708</pre>
709<p>
710 If you want to encode a name onto this URI, you would use the following snippet:
711</p>
712<pre>
713String uriString = &quot;content:&#47;&#47;com.example.contacts&quot; + &quot;/&quot; + &quot;Smith&quot;
714
715// uriString now contains content://com.example.contacts/Smith.
716
717// Generates a uri object from the string representation
718Uri copyUri = Uri.parse(uriString);
719</pre>
720<p>
721 If you are already using a content provider, you may want to add a new URI path that indicates
722 the URI is for copying. For example, suppose you already have the following URI paths:
723</p>
724<pre>
725&quot;content://com.example.contacts&quot;/people
726&quot;content://com.example.contacts&quot;/people/detail
727&quot;content://com.example.contacts&quot;/people/images
728</pre>
729<p>
730 You could add another path that is specific to copy URIs:
731</p>
732<pre>
733&quot;content://com.example.contacts/copying&quot;
734</pre>
735<p>
736 You could then detect a &quot;copy&quot; URI by pattern-matching and handle it with code that
737 is specific for copying and pasting.
738</p>
739<p>
740 You normally use the encoding technique if you're already using a content provider, internal
741 database, or internal table to organize your data. In these cases, you have multiple pieces of
742 data you want to copy, and presumably a unique identifier for each piece. In response to a
743 query from the pasting application, you can look up the data by its identifier and return it.
744</p>
745<p>
746 If you don't have multiple pieces of data, then you probably don't need to encode an identifier.
747 You can simply use a URI that is unique to your provider. In response to a query, your provider
748 would return the data it currently contains.
749</p>
750<p>
751 Getting a single record by ID is used in the
752 <a href="{@docRoot}resources/samples/NotePad/index.html">Note Pad</a> sample application to
753 open a note from the notes list. The sample uses the <code>_id</code> field from an SQL
754 database, but you can have any numeric or character identifier you want.
755</p>
756<h3 id="Records">Copying data structures</h3>
757<p>
758 You set up a content provider for copying and pasting complex data as a subclass of the
759 {@link android.content.ContentProvider} component. You should also encode the URI you put on
760 the clipboard so that it points to the exact record you want to provide. In addition, you
761 have to consider the existing state of your application:
762</p>
763<ul>
764 <li>
765 If you already have a content provider, you can add to its functionality. You may only
766 need to modify its
767{@link android.content.ContentResolver#query(Uri, String[], String, String[], String) query()}
768 method to handle URIs coming from applications that want to paste data. You will
769 probably want to modify the method to handle a &quot;copy&quot; URI pattern.
770 </li>
771 <li>
772 If your application maintains an internal database, you may
773 want to move this database into a content provider to facilitate copying from it.
774 </li>
775 <li>
776 If you are not currently using a database, you can implement a simple content provider
777 whose sole purpose is to offer data to applications that are pasting from the
778 clipboard.
779 </li>
780</ul>
781<p>
782In the content provider, you will want to override at least the following methods:
783</p>
784<dl>
785 <dt>
786{@link android.content.ContentResolver#query(Uri, String[], String, String[], String) query()}
787 </dt>
788 <dd>
789 Pasting applications will assume that they can get your data by using this method with
790 the URI you put on the clipboard. To support copying, you should have this method
791 detect URIs that contain a special &quot;copy&quot; path. Your application can then
792 create a &quot;copy&quot; URI to put on the clipboard, containing the copy path and
793 a pointer to the exact record you want to copy.
794 </dd>
795 <dt>
796 {@link android.content.ContentProvider#getType(Uri) getType()}
797 </dt>
798 <dd>
799 This method should return the MIME type or types for the data you intend to copy. The method
800 {@link android.content.ClipData#newUri(ContentResolver, CharSequence, Uri) newUri()} calls
801 {@link android.content.ContentProvider#getType(Uri) getType()} in order to put the MIME
802 types into the new {@link android.content.ClipData} object.
803 <p>
804 MIME types for complex data are described in the topic
805 <a href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a>.
806 </p>
807 </dd>
808</dl>
809<p>
810 Notice that you don't have to have any of the other content provider methods such as
811 {@link android.content.ContentProvider#insert(Uri, ContentValues) insert()} or
812 {@link android.content.ContentProvider#update(Uri, ContentValues, String, String[]) update()}.
813 A pasting application only needs to get your supported MIME types and copy data from your
814 provider. If you already have these methods, they won't interfere with copy operations.
815</p>
816<p>
817 The following snippets demonsrate how to set up your application to copy complex data:
818</p>
819<ol>
820 <li>
821 <p>
822 In the global constants for your application,
823 declare a base URI string and a path that identifies URI strings you are
824 using to copy data. Also declare a MIME type for the copied data:
825 </p>
826<pre>
827// Declares the base URI string
828private static final String CONTACTS = &quot;content:&#47;&#47;com.example.contacts&quot;;
829
830// Declares a path string for URIs that you use to copy data
831private static final String COPY_PATH = &quot;/copy&quot;;
832
833// Declares a MIME type for the copied data
834public static final String MIME_TYPE_CONTACT = &quot;vnd.android.cursor.item/vnd.example.contact&quot;
835</pre>
836 </li>
837 <li>
838 In the Activity from which users copy data,
839 set up the code to copy data to the clipboard. In response to a copy request, put
840 the URI on the clipboard:
841<pre>
842public class MyCopyActivity extends Activity {
843
844 ...
845
846// The user has selected a name and is requesting a copy.
847case R.id.menu_copy:
848
849 // Appends the last name to the base URI
850 // The name is stored in &quot;lastName&quot;
851 uriString = CONTACTS + COPY_PATH + &quot;/&quot; + lastName;
852
853 // Parses the string into a URI
854 Uri copyUri = Uri.parse(uriString);
855
856 // Gets a handle to the clipboard service.
857 ClipboardManager clipboard = (ClipboardManager)
858 getSystemService(Context.CLIPBOARD_SERVICE);
859
860 ClipData clip = ClipData.newUri(getContentResolver(), &quot;URI&quot;, copyUri);
861
862 // Set the clipboard's primary clip.
863 clipboard.setPrimaryClip(clip);
864</pre>
865 </li>
866
867 <li>
868 <p>
869 In the global scope of your content provider, create a URI matcher and add a URI
870 pattern that will match URIs you put on the clipboard:
871 </p>
872<pre>
873public class MyCopyProvider extends ContentProvider {
874
875 ...
876
877// A Uri Match object that simplifies matching content URIs to patterns.
878private static final UriMatcher sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH);
879
880// An integer to use in switching based on the incoming URI pattern
881private static final int GET_SINGLE_CONTACT = 0;
882
883...
884
885// Adds a matcher for the content URI. It matches
886// &quot;content://com.example.contacts/copy/*&quot;
887sUriMatcher.addURI(CONTACTS, "names/*", GET_SINGLE_CONTACT);
888</pre>
889 </li>
890 <li>
891 <p>
892 Set up the
893 {@link android.content.ContentProvider#query(Uri, String[], String, String[], String) query()}
894 method. This method can handle different URI patterns, depending on how you code it, but
895 only the pattern for the clipboard copying operation is shown:
896 </p>
897<pre>
898// Sets up your provider's query() method.
899public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
900 String sortOrder) {
901
902 ...
903
904 // Switch based on the incoming content URI
905 switch (sUriMatcher.match(uri)) {
906
907 case GET_SINGLE_CONTACT:
908
909 // query and return the contact for the requested name. Here you would decode
910 // the incoming URI, query the data model based on the last name, and return the result
911 // as a Cursor.
912
913 ...
914
915}
916</pre>
917 </li>
918 <li>
919 <p>
920 Set up the {@link android.content.ContentProvider#getType(Uri) getType()} method to
921 return an appropriate MIME type for copied data:
922 </p>
923<pre>
924// Sets up your provider's getType() method.
925public String getType(Uri uri) {
926
927 ...
928
929 switch (sUriMatcher.match(uri)) {
930
931 case GET_SINGLE_CONTACT:
932
933 return (MIME_TYPE_CONTACT);
934</pre>
935 </li>
936</ol>
937<p>
938 The section <a href="#PasteContentUri">Pasting data from a content URI</a>
939 describes how to get a content URI from the clipboard and use it to get and paste data.
940</p>
941<h3 id="Streams">Copying data streams</h3>
942<p>
943 You can copy and paste large amounts of text and binary data as streams. The data can have
944 forms such as the following:
945</p>
946 <ul>
947 <li>
948 Files stored on the actual device.
949 </li>
950 <li>
951 Streams from sockets.
952 </li>
953 <li>
954 Large amounts of data stored in a provider's underlying database system.
955 </li>
956 </ul>
957<p>
958 A content provider for data streams provides access to its data with a file descriptor object
959 such as {@link android.content.res.AssetFileDescriptor} instead of a
960 {@link android.database.Cursor} object. The pasting application reads the data stream using
961 this file descriptor.
962</p>
963<p>
964 To set up your application to copy a data stream with a provider, follow these steps:
965</p>
966<ol>
967 <li>
968 Set up a content URI for the data stream you are putting on the clipboard. Options
969 for doing this include the following:
970 <ul>
971 <li>
972 Encode an identifier for the data stream onto the URI,
973 as described in the section
974 <a href="#Encoding">Encoding an identifier on the URI</a>, and then maintain a
975 table in your provider that contains identifiers and the corresponding stream name.
976 </li>
977 <li>
978 Encode the stream name directly on the URI.
979 </li>
980 <li>
981 Use a unique URI that always returns the current stream from the provider. If you
982 use this option, you have to remember to update your provider to point to a
983 different stream whenever you copy the stream to the clipboard via the URI.
984 </li>
985 </ul>
986 </li>
987 <li>
988 Provide a MIME type for each type of data stream you plan to offer. Pasting applications
989 need this information to determine if they can paste the data on the clipboard.
990 </li>
991 <li>
992 Implement one of the {@link android.content.ContentProvider} methods that returns
993 a file descriptor for a stream. If you encode identifiers on the content URI, use this
994 method to determine which stream to open.
995 </li>
996 <li>
997 To copy the data stream to the clipboard, construct the content URI and place it
998 on the clipboard.
999 </li>
1000</ol>
1001<p>
1002 To paste a data stream, an application gets the clip from the clipboard, gets the URI, and
1003 uses it in a call to a {@link android.content.ContentResolver} file descriptor method that
1004 opens the stream. The {@link android.content.ContentResolver} method calls the corresponding
1005 {@link android.content.ContentProvider} method, passing it the content URI. Your provider
1006 returns the file descriptor to {@link android.content.ContentResolver} method. The pasting
1007 application then has the responsibility to read the data from the stream.
1008</p>
1009<p>
1010 The following list shows the most important file descriptor methods for a content provider.
1011 Each of these has a corresponding {@link android.content.ContentResolver} method with the
1012 string &quot;Descriptor&quot; appended to the method name; for example, the
1013 {@link android.content.ContentResolver} analog of
1014 {@link android.content.ContentProvider#openAssetFile(Uri, String) openAssetFile()} is
1015{@link android.content.ContentResolver#openAssetFileDescriptor(Uri, String) openAssetFileDescriptor()}:
1016</p>
1017<dl>
1018 <dt>
1019{@link android.content.ContentProvider#openTypedAssetFile(Uri,String,Bundle) openTypedAssetFile()}
1020 </dt>
1021 <dd>
1022 This method should return an asset file descriptor, but only if the provided MIME type is
1023 supported by the provider. The caller (the application doing the pasting) provides a MIME
1024 type pattern. The content provider (of the application that has copied a URI to the
1025 clipboard) returns an {@link android.content.res.AssetFileDescriptor} file handle if it
1026 can provide that MIME type, or throws an exception if it can not.
1027 <p>
1028 This method handles subsections of files. You can use it to read assets that the
1029 content provider has copied to the clipboard.
1030 </p>
1031 </dd>
1032 <dt>
1033 {@link android.content.ContentProvider#openAssetFile(Uri, String) openAssetFile()}
1034 </dt>
1035 <dd>
1036 This method is a more general form of
1037{@link android.content.ContentProvider#openTypedAssetFile(Uri,String,Bundle) openTypedAssetFile()}.
1038 It does not filter for allowed MIME types, but it can read subsections of files.
1039 </dd>
1040 <dt>
1041 {@link android.content.ContentProvider#openFile(Uri, String) openFile()}
1042 </dt>
1043 <dd>
1044 This is a more general form of
1045 {@link android.content.ContentProvider#openAssetFile(Uri, String) openAssetFile()}. It can't
1046 read subsections of files.
1047 </dd>
1048</dl>
1049<p>
1050 You can optionally use the
1051{@link android.content.ContentProvider#openPipeHelper(Uri, String, Bundle, T, ContentProvider.PipeDataWriter) openPipeHelper()}
1052 method with your file descriptor method. This allows the pasting application to read the
1053 stream data in a background thread using a pipe. To use this method, you need to implement the
1054 {@link android.content.ContentProvider.PipeDataWriter} interface. An example of doing this is
1055 given in the <a href="{@docRoot}resources/samples/NotePad/index.html">Note Pad</a> sample
1056 application, in the <code>openTypedAssetFile()</code> method of
1057 <code>NotePadProvider.java</code>.
1058</p>
1059<h2 id="DataDesign">Designing Effective Copy/Paste Functionality</h2>
1060<p>
1061 To design effective copy and paste functionality for your application, remember these
1062 points:
1063</p>
1064 <ul>
1065 <li>
1066 At any time, there is only one clip on the clipboard. A new copy operation by
1067 any application in the system overwrites the previous clip. Since the user may
1068 navigate away from your application and do a copy before returning, you can't assume
1069 that the clipboard contains the clip that the user previously copied in <em>your</em>
1070 application.
1071 </li>
1072 <li>
1073 The intended purpose of multiple {@link android.content.ClipData.Item}
1074 objects per clip is to support copying and pasting of multiple selections rather than
1075 different forms of reference to a single selection. You usually want all of the
1076 {@link android.content.ClipData.Item} objects in a clip to have the same form, that is,
1077 they should all be simple text, content URI, or {@link android.content.Intent}, but not
1078 a mixture.
1079 </li>
1080 <li>
1081 When you provide data, you can offer different MIME representations. Add the MIME types
1082 you support to the {@link android.content.ClipDescription}, and then
1083 implement the MIME types in your content provider.
1084 </li>
1085 <li>
1086 When you get data from the clipboard, your application is responsible for checking the
1087 available MIME types and then deciding which one, if any, to use. Even if there is a
1088 clip on the clipboard and the user requests a paste, your application is not required
1089 to do the paste. You <em>should</em> do the paste if the MIME type is compatible. You
1090 may choose to coerce the data on the clipboard to text using
1091 {@link android.content.ClipData.Item#coerceToText(Context) coerceToText()} if you
1092 choose. If your application supports more than one of the available MIME types, you can
1093 allow the user to choose which one to use.
1094 </li>
1095 </ul>