In the development of some system applications, we will use the Android Clipboard features, such as text files, or other formats to copy the contents of the Clipboard or from the Clipboard to get data and other operations. Each regular application in the Android platform runs in its own process space, and the inter-process transfer between Android is mainly IPC and clipboard relative to Win32. Of course today we say the simplest clipboardmanager. The use of the Clipboard allows for direct data transfer. The whole implementation is relatively simple, pay attention to the type judgment in the shearing plate.
Very simple to use, the system provides us with a very convenient interface, the following text information is copied as follows:
Get Clipboard Management Service Clipboardmanager cm = (Clipboardmanager) context.getsystemservice (context.clipboard_service);// Copy the text data to the Clipboard cm.settext (message);//Read 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 (); }
Clipdata cuts data on behalf of the Clipboard. It has one or more item instances, each of which can hold one or more data items. The clipdata contains Clipdescription, which is used to describe the important metadata of the clipped content. In particular, GetDescription (). GetMimeType (INT) must return the correct MIME type. In order to correctly set the MIME type of the clip content, it is recommended to use Newplaintext (charsequence,charsequence), Newuri (Contentresolver,charsequence, URI), Newintent (charsequence, Intent) constructs clipdata. An instance of each item can be one of three big data types: Text,intent,uri. For more information, see Clipdata.item
Paste Data
In order to get data from the Clipboard, the application must parse the data correctly If Cipdata.item contains information that is text or intent type, one thing to note: text can only be parsed as text, intent is usually used for shortcuts or other action types, and if you just want to get text, you can force it through the Item.coercetotext () method. , so that you do not need to consider MIME types, and all item will be cast to text.
Complex data types are typically pasted using URLs. Allows the recipient to obtain data from the ContentProvider in a URI manner. You need to fill in the correct MIME type when clipping; such as: Newuri (Contentresolver,charsequence,uri) so that can be handled correctly.
The following is an example of Notepad application pasting. When you accept data from the Clipboard, if the Clipboard contains a URI reference for an existing note, copy its structure to a new note based on the URI, otherwise by taking the text content as a new note:
/** * A helper method that replaces the note's data with the contents of the Clipboard. */private final void Performpaste () {//Gets a handle to The Clipboard Manager clipboardmanager Clipboard = (clipboardmanager) getsystemservice (context.clipboard_se Rvice); 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 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 the item actually is a URI, and that the UR I//is a content URI pointing to a provider whose MIME type are the same//as the MIME type supported by th e Note 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 is needed null Use the default sort order); If the Cursor is not NULL, and it contains at least a record//(Movetofirst () returns True), then this GE TS 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's to text. if (text = = null) {text = Item.coercetotext (this). ToString (); }//Updates the current note with the retrieved titl E and text. Updatenote (text, title); }}
Many applications can handle multiple types of data, such as: E_Mail applications want users to paste pictures or other binaries as attachments. This is required through Contentresolver's Getstreamtypes (Uri, String) and Opentypedassetfiledescriptor (Uri,string,android.os.bundle) method is processed. This requires the client to detect a specific content URI to process the data in a streaming manner.
The following is the implementation of Item.coercetotext:
Public Charsequence Coercetotext (context context) {//If this Item has a explicit textual value, simply return that. if (mText! = null) {return mText; }//If This Item has a URI of value, try using that. if (MUri! = null) {//First see if the URI can ope Ned as a plain text stream//(of any sub-type). If So, the 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 have 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 a Intent, then we can jus T turn that//into text. 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 ""; }
Copying data
As the source data for replication, the application constructs clipped data that is easily accepted for parsing. If you want to copy a text, Intent, or URI, the simple way is to use Clipdata.item to contain the corresponding type data;
Complex data types require support for describing and generating accepted data in a contentprovide manner, and the common solution is to copy the data in a URI, with a complex structure of data, and only an application that understands the results can accept such data;
For applications that do not have an inherent knowledge of data structures, any acceptable stream type can be used. This is obtained by implementing the ContentProvider Getstreamtypes (uri,string) and Opentypedassetfile (URI string, Android.os.Bundle) methods.
Back to the Notepad application example, it is going to copy the content to the URI of the passed
/** * This describes the MIME types that is 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 is supported. * The application can convert such a note to a plain text stream. * * @param uri the URI to analyze * @param mimetypefilter the MIME type to check for. This method is 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, 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 BAS Ed on the incoming URI pattern. */Switch (SurimaTcher.match (URI)) {//If the pattern is for notes or L ive folders, return null. Data streams is 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 are Text/plain, then return//Text/plain Case 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 (URI, String, Bundle, Object, * Pipe DataWriter)} 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 the * data with the This MIME type. * @param opts Additional options supplied by the caller. Can is interpreted as * desired by the content 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 Fileno tfoundexception {//Checks to see if the MIME type filter Matches a supported MIME type. string[] mimetypes = Getstreamtypes (URI, Mimetypefilter); 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,//Ge TS a projection containing the note ' s ID, title,//and contents nul L,//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, Assetfi Ledescriptor.unknown_length); }//If the MIME type is not supported, return a read-only Handle to the file. Return Super.opentypedassetfile (URI, Mimetypefilter, opts);} /** * Implementation of {@link Android.content.ContentProvider.PipeDat Awriter} to perform the actual work of converting the data in one of the cursors to a * stream of data for the client to Rea d. */@Overridepublic void Writedatatopipe (parcelfiledescriptor output, Uri Uri, String MimeType, Bundle opts, curso R c) {//We currently only support 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 (Unsupportedencodingexception 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 simply constructed UPI:
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 U RI getcontentresolver (), //resolver to retrieve URI info "Note", //label for the clip Noteuri) c11/>//the URI ); Returns to the caller and skips further processing. return true;
Note If the paste operation requires text (such as pasting into the programmer), the Coercetotext (context) method notifies the content provider to convert the URI to a URL;