Android Application Development (copying and pasting through clipboardmanager and clipdata)

Source: Internet
Author: User

Http://iandroiddev.com/post/2012-06-06/40028637105

When developing some system applications, we will use the android clipboard function, such as copying text files or other formats to the clipboard or obtaining data from the clipboard.On the Android platform, each common application runs in its own process space. Compared with Win32, the inter-process transmission between Android applications mainly includes IPC and clipboard. Of course, today we will talk about the simplest clipboardmanager. You can directly transmit data using a clipboard. The entire implementation is relatively simple. Pay attention to the type determination in the clipboard.

The system provides a convenient interface for us to use. The following text information is copied as follows:

 
// Obtain the clipboard Management Service clipboardmanager CM = (clipboardmanager) context. getsystemservice (context. clipboard_service); // Copy text data to the clipboard cm. settext (Message); // read the Clipboard data cm. gettext ();
 
Public void setclipboard (string text) {clipboardmanager clipboard = (clipboardmanager) getsystemservice (context. clipboard_service); clipboard. settext (text);} Public String getclipboard () {clipboardmanager clipboard = (clipboardmanager) getsystemservice (context. clipboard_service); Return clipboard. gettext (). tostring ();}

ClipDataCut data in the clipboard. It has one or more item instances, each of which can contain one or more data items. Clipdata contains clipdescription, which is used to describe the important metadata of the clipboard content. In particular, getdescription (). getmimetype (INT) must return the correct MIME type. To correctly set the MIME type of the clipboard content, we recommend that you use newplaintext (charsequence, charsequence), newuri (contentresolver, charsequence, Uri), newintent (charsequence, intent) to construct clipdata. The instance of each item can be one of the three data types: Text, intent, and Uri. For details, see clipdata. Item

Paste data

To obtain data from the clipboard, applyProgramData must be correctly parsed; If cipdata. item contains information of the text or intent type. It must be noted that the text can only be parsed into text. Intent is usually used for shortcuts or other action types. If you only want to obtain the text content, you can use item. the coercetotext () method is forcibly obtained, so that the MIME type is not required. It should be forcibly converted to text for all items.

Complex data types are usually pasted using URLs. The receiver is allowed to retrieve data from contentprovider in Uri mode. You must enter the correct MIME type during pasting, for example, newuri (contentresolver, charsequence, Uri.

The following is an example of notepad app pasting. When receiving data from the clipboard, if the Clipboard contains a URI reference of an existing NOTE, copy its structure to the new note according to the URI, otherwise, use the obtained text content as the new note content:

/*** A helper method that replaces the note's data with the contents of the clipboard. */private final void initialize mpaste () {// gets a handle to the clipboard manager clipboardmanager clipboard = (clipboardmanager) getsystemservice (context. clipboard_service); // gets a content resolver instance contentresolver Cr = getcontentresolver (); // gets the Clipboard data from the clipboard clipdata clip = Clipboard. getprimaryclip (); If (clip! = NULL) {string text = NULL; String title = NULL; // gets the first item from the Clipboard data clipdata. item = clip. getitemat (0); // tries to get the item's contents as a URI pointing to a note URI uri = item. geturi (); // tests to see that the item actually is an Uri, and that the URI // is a content URI pointing to a provider whose MIME type is the same // as the MIME type supported by the not E pad provider. If (Uri! = NULL & notepad. notes. content_item_type.equals (Cr. getType (URI) {// The clipboard holds a reference to data with a note MIME type. this copies it. cursor orig = CR. query (Uri, // URI for the content provider projection, // get the columns referred to in the projection null, // no selection variables null, // no selection variables, so no criteria are needed null // use the default sort order ); // If the cursor is not null, and it contains at least one record // (movetofirst () returns true), then this gets the note data from it. If (orig! = NULL) {If (orig. movetofirst () {int colnoteindex = mcursor. getcolumnindex (notepad. notes. column_name_note); int coltitleindex = mcursor. getcolumnindex (notepad. notes. column_name_title); text = orig. getstring (colnoteindex); Title = orig. getstring (coltitleindex);} // closes the cursor. orig. close () ;}// if the contents of the clipboard wasn't a reference to a note, then // This converts whatever it is to text. if (text = NULL) {text = item. coercetotext (this ). tostring ();} // updates the current note with the retrieved title and text. updatenote (text, title );}}

 

Many applications can process multiple types of data. For example, the e_mail application wants users to paste images or other binary files as attachments. This requires the contentresolver's getstreamtypes (Uri, string) and opentypedassetfiledescriptor (Uri, String, Android. OS. Bundle) methods. This requires the client to detect a specific content URI to process data in a stream.

The following figure shows the implementation of item. coercetotext:

Public charsequence coercetotext (context) {// if this item has an explicit textual value, simply return that. If (mtext! = NULL) {return mtext;} // if this item has a URI value, try using that. If (muri! = NULL) {// first see if the URI can be opened as a plain text stream // (of any sub-type ). if so, this is the best textual // representation for it. fileinputstream stream = NULL; try {// ask for a stream of the desired type. assetfiledescriptor descr = context. getcontentresolver (). opentypedassetfiledescriptor (muri, "text/*", null); stream = descr. createinputstream (); inputstreamreader reader = New inputstreamreader (stream, "UTF-8"); // got it... copy the stream into a local string and return it. stringbuilder builder = new stringbuilder (128); char [] buffer = new char [8192]; int Len; while (LEN = reader. read (buffer)> 0) {builder. append (buffer, 0, Len);} return builder. tostring ();} catch (filenotfoundexception e) {// unable to open content URI as text... not really an // error, just Something to ignore .} catch (ioexception e) {// something bad has happened. log. W ("clippeddata", "Failure loading text", e); Return e. tostring ();} finally {If (stream! = NULL) {try {stream. close () ;}catch (ioexception e) {}}// if we couldn't open the URI as a stream, then the URI itself // probably serves fairly well as a textual representation. return muri. tostring ();} // finally, if all we have is an intent, then we can just turn that // into text. not the most user-friendly thing, but it's something. if (mintent! = NULL) {return mintent. touri (intent. uri_intent_scheme);} // shouldn't get here, but just in case... return "";}

 

Copy Data

As the source data for replication, the application needs to construct scissors that are easily parsed. To copy a file containing text, intent, or Uri, you can use clipdata. item to include the corresponding type of data;

Complex data types require that you describe and generate accepted data in contentprovide mode. A common solution is to copy data in Uri mode. a uri consists of complex data structures, only applications that understand such results can accept such data;

Any acceptable data stream type can be used for applications that do not have internal data structure knowledge. This is obtained by implementing the getstreamtypes (Uri, string) and opentypedassetfile (URI string, Android. OS. Bundle) Methods of contentprovider.

Return to the example of the notepad application. The content to be copied is transmitted as a URI.

/*** This describes the MIME types that are supported for opening a note * URI as a stream. */static clipdescription note_stream_types = new clipdescription (null, new string [] {clipdescription. mimetype_text_plain});/*** returns the types of available data streams. URIs to specific notes are supported. * The application can convert such a note to a plain text stream. ** @ Param Uri the URI to Nalyze * @ Param mimetypefilter the MIME type to check. this method only returns a data stream * type for MIME types that match the filter. currently, only text/plain MIME types match. * @ return a data stream MIME type. currently, only text/plan is returned. * @ throws illegalargumentexception if the URI pattern doesn't match any supported patterns. * // @ overridepublic string [] getstreamtypes (URI Uri, string mimetypefilter) {/*** chooses the data stream type based on the incoming URI pattern. */switch (surimatcher. match (URI) {// if the pattern is for notes or live folders, return null. data streams are not // supported for this type of Uri. case Notes: Case live_folder_notes: return NULL; // if the pattern is for note IDs and the mime filter is text/plain, then return // text/plain ca Se note_id: Return note_stream_types.filtermimetypes (mimetypefilter); // If the URI pattern doesn't match any permitted patterns, throws an exception. default: Throw new illegalargumentexception ("unknown Uri" + URI);}/*** returns a stream of data for each supported stream type. this method does a query on the * Incoming Uri, then uses * {@ link android. content. contentprovider # openpipehelper (UR I, String, bundle, object, * pipedatawriter)} to start another thread in which to convert the data into a stream. ** @ Param Uri the URI pattern that points to the data stream * @ Param mimetypefilter a string containing a MIME type. this method tries to get a stream of * data with this mime type. * @ Param opts additional options supplied by the caller. can be interpreted as * desired by the conten T provider. * @ return assetfiledescriptor a handle to the file. * @ throws filenotfoundexception if there is no file associated with the incoming Uri. * // @ overridepublic assetfiledescriptor opentypedassetfile (URI Uri, string mimetypefilter, bundle opts) throws filenotfoundexception {// checks to see if the MIME type filter matches a supported MIME type. string [] mimetypes = getstreamtypes (Uri, mime Typefilter); // If the MIME type is supported if (mimetypes! = NULL) {// retrieves the note for this URI. uses the query method defined for this provider, // rather than using the database query method. cursor c = query (Uri, // The URI of a note read_note_projection, // gets a projection containing the note's ID, title, // and contents null, // no WHERE clause, get all matching records null, // since there is no WHERE clause, no selection criteria null // Use the default sort order (modification date, // descending); // If the query fails or the cursor is empty, stop if (C = NULL |! C. movetofirst () {// If the cursor is empty, simply close the cursor and return if (C! = NULL) {C. close ();} // If the cursor is null, throw an exception throw new filenotfoundexception ("unable to query" + URI );} // start a new thread that pipes the stream data back to the caller. return new assetfiledescriptor (openpipehelper (Uri, mimetypes [0], opts, C, this), 0, assetfiledescriptor. unknown_length);} // If the MIME type is not supported, return a read-only handle to the file. re Turn super. opentypedassetfile (Uri, mimetypefilter, opts);}/*** Implementation of {@ link android. content. contentprovider. pipedatawriter} * to perform the actual work of converting the data in one of cursors to a * stream of data for the client to read. * // @ overridepublic void writedatatopipe (parcelfiledescriptor output, Uri, string mimetype, bundle opts, cursor c) {// we currently only suppor T conversion-to-text from a single note entry, // so no need for cursor data type checking here. fileoutputstream fout = new fileoutputstream (output. getfiledescriptor (); printwriter PW = NULL; try {PW = new printwriter (New outputstreamwriter (fout, "UTF-8"); PW. println (C. getstring (read_note_title_index); PW. println (""); PW. println (C. getstring (read_note_note_index);} catch (unsupportedencoding Exception e) {log. W (TAG, "Ooops", e) ;}finally {C. Close (); If (PW! = NULL) {PW. Flush () ;}try {fout. Close () ;}catch (ioexception e ){}}}

 

 

The not copy operation is now a simple UPI construction:

 
Case R. id. context_copy: // gets a handle to the clipboard service. clipboardmanager clipboard = (clipboardmanager) getsystemservice (context. clipboard_service); // copies the notes URI to the clipboard. in effect, this copies the note itself clipboard. setprimaryclip (clipdata. newuri (// new clipboard item holding a URI getcontentresolver (), // resolver to retrieve URI Info "NOTE", // label for the clip noteuri) // The URI ); // returns to the caller and skips further processing. return true;

 

Note: If the pasting operation requires text (for example, pasting to the programmer) in coercetotext (context) mode, the content provider will be notified to convert the URI to a URL;

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.