Tutorial details

Android: Copy-paste with Intent and support for HTML | App Code for Sale | Preview

Android: Copy-paste with Intent and support for HTML | Android Tutorial

How to use copy and paste feature.

Overview PAGE TOP

Android provides support for copy and paste feature using ClipBoardManager. The developer.android.com provides a brief description along with an image which helps to understand the Copy-paste framework.

“To copy data, an application puts a ClipData object on the ClipboardManager global clipboard. The ClipData contains one or more ClipData.Item objects and one ClipDescription object. To paste data, an application gets the ClipData, gets its MIME type from the ClipDescription, and gets the data either from the ClipData.Item or from the content provider referred to by ClipData.Item.”

copy_paste_framework.png

This tutorial covers the latest feature introduced in JellyBean, supporting the styled text. We will cover the methods listed below.

HTML supported methods PAGE TOP

  • ClipData.newHtmlText() with clipboard**
  • Intent.putExtra() with Intent.EXTRAHTMLTEXT**
  • Intent.setClipData() with newHtmlText() method**

Project Information : Meta-data about the project.

Platform Version : Android API Level 16.

IDE : Eclipse Helios Service Release 2

Emulator : Android 4.1(API 16)

Prerequisite : Preliminary knowledge of Android application framework and Intent.

Example source code PAGE TOP

To start with, create project by Eclipse > File> New Project>Android Application Project. The following dialog box will appear. Fill the required field, i.e Application Name, Project Name and Package. Now press the next button.

oooo.png

Once the dialog box appears, select the BlankActivity and click the next button.

pppppppp.png

Fill the Activity Name and Layout file name in the dialog box shown below and hit the finish button.

llllll.png

This process setups the basic project files. Now we are going to add view components in the layout activity_jbclipboard.xml file. You can modify the layout file using either Graphical Layout editor or xml editor. In this layout, we will add four buttons, namely copy, paste, send html Intent, and send clipdata intent and attach onClick methods with CopyHtml, pasteHtml, sendHtmlIntent and sendClipdataIntent buttons, respectively. These methods will be defined in JBClipboard class. We will also include two radio buttons i.e Paste HTML and Paste Text. These radio buttons help to select the required type of text to be extracted from the clipboard. We also have three EditViews to show the text. The first Editview contains the Styled text, the second one shows either HTML or text string. The third one shows the Coerce HTML string. The layout file is shown below.

01  <LinearLayout xmlns:android='http://schemas.android.com/apk/res/android'
02      xmlns:tools='http://schemas.android.com/tools'
03      android:layout_width='match_parent'
04      android:layout_height='match_parent'
05      android:orientation='vertical'>
06  
07      <EditText
08          android:id='@+id/etCopy'
09          android:layout_width='fill_parent'
10          android:layout_height='wrap_content'
11          android:padding='@dimen/padding_medium'
12          android:gravity='top'  
13          android:scrollHorizontally='false'
14          android:inputType='textMultiLine'
15           />
16      <RadioGroup
17         android:id='@+id/rbgTextHTML'
18         android:orientation='horizontal'
19         android:layout_width='fill_parent'
20         android:layout_height='wrap_content'
21         >
22           <RadioButton
23             android:id='@+id/rbHtml'
24             android:layout_weight='.5'
25             android:layout_width='0dp'
26             android:layout_height='wrap_content'
27             android:checked='true'
28             android:text='@string/rbHtml'/>
29         <RadioButton
30             android:id='@+id/rbText'
31             android:layout_weight='.5'
32             android:layout_width='0dp'
33             android:layout_height='wrap_content'
34             android:text='@string/rbText'/>
35        
36     </RadioGroup>
37      <LinearLayout
38          android:layout_width='match_parent'
39          android:layout_height='wrap_content'
40          android:orientation='horizontal'>
41     <Button
42         android:layout_width='0dp'
43         android:layout_height='wrap_content'
44         android:layout_weight='.5'
45         android:onClick='copyHtml'
46         android:text='@string/btCopy'/>
47     <Button
48         android:layout_width='0dp'
49         android:layout_height='wrap_content'
50         android:layout_weight='.5'
51         android:onClick='pasteHtml'
52         android:text='@string/btPaste'/>
53     </LinearLayout>
54     <LinearLayout android:layout_width='fill_parent'
55         android:layout_height='wrap_content'
56         android:orientation='horizontal'>
57         <Button
58             android:layout_width='0dp'
59             android:layout_weight='.5'
60             android:layout_height='wrap_content'
61             android:onClick='sendHtmlIntent'
62             android:text='@string/btSendHtmlIntent'/>
63         <Button
64             android:layout_width='0dp'
65             android:layout_weight='.5'
66             android:layout_height='wrap_content'
67             android:onClick='sendClipdataIntent'
68             android:text='@string/btSendClipdataIntent'/>
69     </LinearLayout>
70     <TextView
71         android:layout_width='fill_parent'
72         android:layout_height='wrap_content'
73         android:text='@string/tvCopiedText'/>
74     <EditText
75         android:id='@+id/etPaste'
76         android:layout_width='fill_parent'
77         android:layout_height='wrap_content'
78         android:inputType='textMultiLine'
79          android:gravity='top'  
80          android:scrollHorizontally='false'
81         />
82     <TextView
83         android:layout_width='fill_parent'
84         android:layout_height='wrap_content'
85         android:text='@string/tvcoerceText'/>
86     <EditText
87         android:id='@+id/etPasteCoerceText'
88         android:layout_width='fill_parent'
89         android:layout_height='wrap_content'
90         android:gravity='top'  
91         android:scrollHorizontally='false'
92         android:inputType='textMultiLine'/>
93  </LinearLayout>

Now we need to add two more layout files for two different activities. Let’s define the first Layout file by Eclipse > File > Android XML file. Eventually we get the following dialog box. Make sure that the Layout resource type is selected. Name the layout file as activity_htmlintent and then click finish.

hhhhh.png

Add two TextViews for showing text tags and two EditTexts view for showing the HTML and text strings. This layout file will be attached with HTMLIntentActivity.java which gets invoked once “text/html” type intent is broadcasted. The content of the activity_htmlintent.xml is given below:

01  <LinearLayout xmlns:android='http://schemas.android.com/apk/res/android'
02      android:layout_width='match_parent'
03      android:layout_height='match_parent'
04      android:orientation='vertical' >
05      <TextView
06          android:layout_width='match_parent'
07          android:layout_height='wrap_content'
08          android:text='@string/tvIntentHtml' />
09      <EditText
10          android:id='@+id/etHtml'
11          android:layout_width='match_parent'
12          android:layout_height='wrap_content'
13          android:inputType='textMultiLine'
14          android:padding='@dimen/padding_medium'
15          android:scrollHorizontally='false' />
16      <TextView
17          android:layout_width='match_parent'
18          android:layout_height='wrap_content'
19          android:text='@string/tvIntentText' />
20      <EditText
21          android:id='@+id/etText'
22          android:layout_width='match_parent'
23          android:layout_height='wrap_content'
24          android:inputType='textMultiLine'
25          android:padding='@dimen/padding_medium'
26          android:scrollHorizontally='false' />
27  </LinearLayout>

Now we will define another layout file called activity_clipdataintent.xml. Follow the similar steps given above to generate the layout xml file. This file is similar to the above file and contains two EditView and two TextViewThe. The content of the file is given below. This layout file will be attached to the ClipdataIntentActivity class which gets invoked when an intent with Clipdata object is passed.

01  <LinearLayout xmlns:android='http://schemas.android.com/apk/res/android'
02      android:layout_width='match_parent'
03      android:layout_height='match_parent'
04      android:orientation='vertical' >
05  
06      <TextView
07          android:layout_width='match_parent'
08          android:layout_height='wrap_content'
09          android:text='@string/tvIntentClipdataHtml' />
10  
11      <EditText
12          android:id='@+id/etClipBoardHtml'
13          android:layout_width='match_parent'
14          android:layout_height='wrap_content'
15          android:inputType='textMultiLine'
16          android:padding='@dimen/padding_medium'
17          android:scrollHorizontally='false' />
18  
19      <TextView
20          android:layout_width='match_parent'
21          android:layout_height='wrap_content'
22          android:text='@string/tvIntentClipdataText' />
23  
24      <EditText
25          android:id='@+id/etClipBoardText'
26          android:layout_width='match_parent'
27          android:layout_height='wrap_content'
28          android:inputType='textMultiLine'
29          android:padding='@dimen/padding_medium'
30          android:scrollHorizontally='false' />
31  </LinearLayout>

You may have notice there are string resources have been used in the layout file. Define this string constants in string.xml as shown below.

01  <resources>
02  
03      <string name='app_name'>JellyBeanClipboard</string>
04      <string name='menu_settings'>Settings</string>
05      <string name='title_activity_jbclipboard'>JBClipboard</string>
06      <string name='title_activity_htmlintent'>Html Intent Activity</string>
07      <string name='title_activity_clipdataintent'>ClipData Intent Activity</string>
08      <!-- CDATA tag is required otherwise you can't have the html text
09         properly parsed in Textview  -->
10     <string name='tvHtml'><![CDATA[<b>Link:</b> <a href='http://www.code4reference.com'>Code4Reference</a>]]></string>
11      
12     <!-- Text string for button -->
13     <string name='btCopy'>Copy</string>
14     <string name='btPaste'>Paste</string>
15     <string name='btSendHtmlIntent'>send HTML Intent</string>
16     <string name='btSendClipdataIntent'>send ClipData Intent</string>
17      
18     <!-- Text string for RadioButton -->
19     <string name='rbHtml'>Paste Html</string>
20     <string name='rbText'>Paste Text</string>
21      
22     <!-- Text string for Text View -->
23     <string name='tvCopiedText'><b><i>Copied text</i></b></string>
24     <string name='tvcoerceText'><b><i>Copied coerce Text</i></b></string>
25      <string name='tvIntentText'><b><i>Intent Text</i></b></string>
26     <string name='tvIntentHtml'><b><i>Intent Html</i></b></string>
27     <string name='tvIntentClipdataText'><b><i>Intent Clipdata Text</i></b></string>
28     <string name='tvIntentClipdataHtml'><b><i>Intent Clipdata Html</i></b></string>
29  </resources>

Once we are done with the layout files, it’s time to define the activity classes. Let’s define the main activity called JBClipboard. This activity has various methods which use the HTML supported APIs. The embedded comments will help to understand the code.

001 package com.code4reference.rakesh.jellybeanclipboard;
002 
003 import android.app.Activity;
004 import android.content.ClipData;
005 import android.content.ClipDescription;
006 import android.content.ClipboardManager;
007 import android.content.Context;
008 import android.content.Intent;
009 import android.os.Bundle;
010 import android.text.Html;
011 import android.text.Spannable;
012 import android.view.View;
013 import android.widget.EditText;
014 import android.widget.RadioButton;
015 import android.widget.Toast;
016 
017 import com.example.jellybeanclipboard.R;
018 
019 public class JBClipboard extends Activity {
020 
021  EditText etCopy;
022  EditText etPaste;
023  EditText etPasteCoerceText;
024  RadioButton rbText;
025  RadioButton rbHtml;
026  ClipboardManager mClipboard;
027 
028  ClipboardManager.OnPrimaryClipChangedListener mPrimaryChangeListener = newClipboardManager.OnPrimaryClipChangedListener() {
029   /**
030    * This method is a callback. It get called when the primary clip
031    * on the clipboard changes.
032    */
033   public void onPrimaryClipChanged() {
034    //Toast message will appear whenever the clipboad
035    //primary data changes.
036    Utility.showToastMessage(getApplicationContext(),
037      'Primary clipdata changed', Toast.LENGTH_SHORT);
038   }
039  };
040 
041  @Override
042  public void onCreate(Bundle savedInstanceState) {
043   super.onCreate(savedInstanceState);
044   setContentView(R.layout.activity_jbclipboard);
045   etCopy = (EditText) findViewById(R.id.etCopy);
046   etPaste = (EditText) findViewById(R.id.etPaste);
047   etPasteCoerceText = (EditText) findViewById(R.id.etPasteCoerceText);
048   etCopy.setText(Html.fromHtml(getString(R.string.tvHtml)));
049   rbText = (RadioButton) findViewById(R.id.rbText);
050   rbHtml = (RadioButton) findViewById(R.id.rbHtml);
051   mClipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
052   mClipboard.addPrimaryClipChangedListener(mPrimaryChangeListener);
053  }
054 
055  /**
056   * This method gets called when 'Copy' button get pressed.
057   * @param view
058   */
059  public void copyHtml(View view) {
060   String htmlText = getHtmltxt(etCopy);
061   String plainText = getOnlyText(etCopy);
062   mClipboard.setPrimaryClip(ClipData.newHtmlText('HTML Text', plainText,
063     htmlText));
064 
065  }
066  /**
067   * This method gets called when 'Paste' button get pressed.
068   * @param view
069   */
070  public void pasteHtml(View view) {
071   // Check if there is primary clip exsiting.
072   // If it does then echeck the mime type to make sure
073   // it has HTML content.
074   if (mClipboard.hasPrimaryClip()
075     && mClipboard.getPrimaryClipDescription().hasMimeType(
076       ClipDescription.MIMETYPE_TEXT_HTML)) {
077    // Get the very first item from the clip.
078    ClipData.Item item = mClipboard.getPrimaryClip().getItemAt(0);
079 
080    // If 'Paste HTML' radio button is selected then paste
081    // HTML in the Textview.
082    if (rbHtml.isChecked()) {
083     etPaste.setText(item.getHtmlText());
084    } else {
085     // Paste the only text version.
086     etPaste.setText(item.getText());
087    }
088    // Paste the CoerceText .
089    etPasteCoerceText.setText(item.coerceToText(this));
090   }
091  }
092  /**
093   * This method gets called when 'send Html Intent' button get pressed.
094   * @param view
095   */
096  public void sendHtmlIntent(View view) {
097   // This kind of intent can be handle by this application
098   // Or other application which handle text/html type Intent
099   Intent intent = new Intent(Intent.ACTION_SEND);
100 
101   String htmlText = getHtmltxt(etCopy);
102   String text = getOnlyText(etCopy);
103   intent.putExtra(Intent.EXTRA_HTML_TEXT, htmlText);
104   intent.putExtra(Intent.EXTRA_TEXT, text);
105   intent.setType('text/html');
106   startActivity(Intent.createChooser(intent, null));
107  }
108 
109  /**
110   * This method gets called when 'send Clipdata Intent' button get pressed.
111   *
112   * @param view
113   */
114  public void sendClipdataIntent(View view) {
115   String htmlText = getHtmltxt(etCopy);
116   String plainText = getOnlyText(etCopy);
117   Intent intent = new Intent(this, ClipdataIntentActivity.class);
118                 //create a clipdata object with HTML text.
119                 //and associate with the intent.
120   intent.setClipData(ClipData.newHtmlText(
121     'HTML text in Intent's clipdata', plainText, htmlText));
122                 //Start the activity which can handle clipData object.
123   startActivity(intent);
124  }
125  @Override
126     protected void onDestroy() {
127         super.onDestroy();
128         //Remove the ClipChanged Listener to save the resources.
129         mClipboard.removePrimaryClipChangedListener(mPrimaryChangeListener);
130     }
131  /**
132   * This method gets the EditText object and returns the HTML text. It
133   * can be called only with EditTexts having spannable object with
134   * the HTML text.
135   *
136   * @param editText
137   * @return
138   */
139  private String getHtmltxt(EditText editText) {
140                 //get the spannable object from EditText
141   Spannable spannable = (Spannable) editText.getText();
142                 //return the HTML text from spannable object.
143   return Html.toHtml(spannable);
144  }
145 
146  /**
147   * This method takes the EditText object which has spannable object with HTML
148   * text and returns the simple text without HTML tags.
149   *
150   * @param editText
151   * @return
152   */
153  private String getOnlyText(EditText editText) {
154   return editText.getText().toString();
155  }
156 }

Now we are going to define HTMLIntentActivitywhich handles intent with HTML text. The intended intent will be triggered by the main activity (JBClibboard)

01  package com.code4reference.rakesh.jellybeanclipboard;
02  
03  import com.example.jellybeanclipboard.R;
04  
05  import android.app.Activity;
06  import android.content.Intent;
07  import android.os.Bundle;
08  import android.widget.EditText;
09  
10  public class HtmlIntentActivity extends Activity {
11  
12   private EditText etHtml;
13   private EditText etText;
14   @Override
15   protected void onCreate(Bundle savedInstanceState) {
16    super.onCreate(savedInstanceState);
17    setContentView(R.layout.activity_htmlintent);
18    etHtml = (EditText) findViewById(R.id.etHtml);
19    etText = (EditText) findViewById(R.id.etText);
20  
21    //Get the intent that started this activity
22    Intent intent = getIntent();
23                  //Make sure intent and its type is not null.
24    if (intent != null && intent.getType() != null
25      && intent.getType().equals('text/html')) {
26     //This contition will full-fill when this application receive the
27     //intent who's type is 'test/html'. In this application sendHtmlIntent
28     //method sends this type of Intent.
29     Bundle bundle = intent.getExtras();
30     if(bundle != null){
31      etHtml.setText(bundle.getCharSequence(Intent.EXTRA_HTML_TEXT));
32      etText.setText(bundle.getCharSequence(Intent.EXTRA_TEXT));
33     }
34    }
35   }
36  }

Now we will define another activity called ClipdataIntentActivity which handles the Intent having clilpdata object. The content of the ClipdataIntentActivity class is given below.

01  package com.code4reference.rakesh.jellybeanclipboard;
02  
03  import android.app.Activity;
04  import android.content.ClipboardManager;
05  import android.content.Intent;
06  import android.os.Bundle;
07  import android.widget.EditText;
08  import android.widget.Toast;
09  import android.content.ClipData;
10  import android.content.ClipDescription;
11  
12  import com.example.jellybeanclipboard.R;
13  
14  public class ClipdataIntentActivity extends Activity {
15   private EditText etHtml;
16   private EditText etText;
17   ClipboardManager mClipboard;
18  
19   @Override
20   protected void onCreate(Bundle savedInstanceState) {
21    super.onCreate(savedInstanceState);
22    setContentView(R.layout.activity_clipdataintent);
23    etHtml = (EditText) findViewById(R.id.etClipBoardHtml);
24    etText = (EditText) findViewById(R.id.etClipBoardText);
25  
26    //Get the intent that started this activity
27    Intent intent = getIntent();
28    if (intent != null) {
29     ClipData clipdata = intent.getClipData();
30                          //Make sure clipdata object is not null and it has HTML MIME type.
31     if (clipdata != null
32       && clipdata.getDescription().hasMimeType(
33         ClipDescription.MIMETYPE_TEXT_HTML)) {
34  
35      ClipData.Item item = clipdata.getItemAt(0);
36      etHtml.setText(item.getHtmlText());
37      etText.setText(item.getText());
38     } else {
39      Utility.showToastMessage(this,
40        'Intent clipdata doesn't have HTML', Toast.LENGTH_SHORT);
41     }
42  
43    }
44   }
45  
46  }

Create another class called Utility. It contains method to display the toast message. As you may have noticed that this function is static, so there is no need to create an object to invoke this method. It’s always a good idea to put the utility methods in a separate file and access this file in different places. In this way your code will be organized.

01  package com.code4reference.rakesh.jellybeanclipboard;
02  
03  import android.content.Context;
04  import android.widget.Toast;
05  
06  public class Utility {
07  
08   public static void showToastMessage(Context context, String message, int duration){
09    Toast.makeText(context, message, duration).show();
10   }
11  }

And finally define the Anroid Manifest file which basically provides Application information to the Android system. Here, you should notice that the HtmlIntentActivity Activity has an intent filter and specifies the Intent type as “text/html”. It basically means that the activity can handle intent whose type is text/html. Remaining part of the file is simple and easy to understand.

01  <manifest xmlns:android='http://schemas.android.com/apk/res/android'
02      package='com.example.jellybeanclipboard'
03      android:versionCode='1'
04      android:versionName='1.0' >
05  
06      <uses-sdk
07          android:minSdkVersion='16'
08          android:targetSdkVersion='16' />
09  
10      <application
11          android:icon='@drawable/ic_launcher'
12          android:label='@string/app_name'
13          android:theme='@style/AppTheme' >
14          <activity
15              android:name='com.code4reference.rakesh.jellybeanclipboard.JBClipboard'
16              android:label='@string/title_activity_jbclipboard' >
17              <intent-filter>
18                  <action android:name='android.intent.action.MAIN' />
19                  <category android:name='android.intent.category.LAUNCHER' />
20              </intent-filter>
21          </activity>
22          <activityandroid:name='com.code4reference.rakesh.jellybeanclipboard.ClipdataIntentActivity'
23              android:label='@string/title_activity_clipdataintent' >
24          </activity>
25          <activity android:name='com.code4reference.rakesh.jellybeanclipboard.HtmlIntentActivity'
26              android:label='@string/title_activity_htmlintent' >
27              <intent-filter>
28                  <action android:name='android.intent.action.SEND' />
29                  <category android:name='android.intent.category.DEFAULT' />
30                  <!-- This activity will get launched when proper Intent type will match.
31                  In this case Intent type is 'text/html' -->
32                  <data android:mimeType='text/html' />
33              </intent-filter>
34          </activity>
35      </application>
36  
37  </manifest>

Once you are done with the coding, just execute it. You can launch this application on your android device or emulator. Make sure that the Android version is 16(Jelly Bean) or higher, only then this application will work. Screen-shots of the applications are shown below.

okp.JPG

You can get the source code here at github.

Happy coding and don’t forget to share!

Reference PAGE TOP

http://www.javacodegeeks.com/2012/09/android-copy-paste-with-intent-and.html

0 Comments Leave a comment

Please login in order to leave a comment.

Newest first
!

Sign-in to your Chupamobile Account.

The Easiest way to Launch your next App or Game.

Join Chupamobile and get instant access to thousands of ready made App and Game Templates.

Creating an account means you’re okay with Chupamobile’s Terms of Service and Privacy Policy.