Reputation: 12304
According to this solution, I would like to add "copy to clipboard" action in custom share dialog - the same as in the default action share provider.
What I have tried was adding to if clausule statement, word packageName.contains("clipboard")
but without success.
String packageName = ri.activityInfo.packageName;
if(packageName.contains("android.email")) {
emailIntent.setPackage(packageName);
} else if(packageName.contains("twitter") || packageName.contains("facebook") || packageName.contains("mms") || packageName.contains("android.gm")) {
Intent intent = new Intent();
intent.setComponent(new ComponentName(packageName, ri.activityInfo.name));
intent.setAction(Intent.ACTION_SEND);
intent.setType("text/plain");
if(packageName.contains("twitter")) {
intent.putExtra(Intent.EXTRA_TEXT, resources.getString(R.string.share_twitter));
} else if(packageName.contains("facebook")) {
intent.putExtra(Intent.EXTRA_TEXT, resources.getString(R.string.share_facebook));
} else if(packageName.contains("mms")) {
intent.putExtra(Intent.EXTRA_TEXT, resources.getString(R.string.share_sms));
} else if(packageName.contains("android.gm")) {
intent.putExtra(Intent.EXTRA_TEXT, Html.fromHtml(resources.getString(R.string.share_email_gmail)));
intent.putExtra(Intent.EXTRA_SUBJECT, resources.getString(R.string.share_email_subject));
intent.setType("message/rfc822");
}
intentList.add(new LabeledIntent(intent, packageName, ri.loadLabel(pm), ri.icon));
}
The whole code is used from https://stackoverflow.com/a/18068122/619673 .
adb shell pm list packages
returned me list of packagenames but without this phrase.
Can I somehow get packagename of clipboard to add it to my custom list of shared providers?
Here is an example with that "copy to clipboard" option:
Upvotes: 6
Views: 9094
Reputation: 17615
Update:
My solution is dependent on another application package and I realized it might not be the correct approach. Hence would suggest to define your own Activity
which will handle copy and paste functionality using ClipboardManager
, as suggested in another answer here.
Original Answer
Clipboard
activity details:
com.google.android.apps.docs
com.google.android.apps.docs.app.SendTextToClipboardActivity
Following Intent
code will start and execute the clipboard
activity.
Intent i = new Intent();
i.setComponent(new ComponentName("com.google.android.apps.docs", "com.google.android.apps.docs.app.SendTextToClipboardActivity"));
i.setAction(Intent.ACTION_SEND);
i.setType("text/plain");
i.putExtra(Intent.EXTRA_TEXT, "text to copy to clipboard");
startActivity(i);
You can add appropriate if
clause while adding this intent
to the intentList
.
Upvotes: 7
Reputation: 12304
might be quite big but it is quite simple to understand. This solution shows only packages from my list, sort by priority. There is also example how to change text from the list of intents.
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("text/plain");
shareIntent.putExtra(Intent.EXTRA_TEXT, mUrl);
shareIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, mTitle);
PackageManager pm = getActivity().getPackageManager();
IntentChoserBuilder.createChoserIntent(this, shareIntent, pm, mUrl, mTitle);
//intent choser class
public class IntentChoserBuilder {
public static final String TAG = IntentChoserBuilder.class.getSimpleName();
public static final Map<String, Integer> PRIORITY = new HashMap<String, Integer>();
public static final String ANDROID_EMAIL = "com.google.android.email";
public static final String FACEBOOK = "com.facebook.katana";
public static final String MMS = "com.android.mms";
public static final String ANDROID_GM = "com.google.android.gm";
public static final String APPS_PLUS = "com.google.android.apps.plus";
public static final String TWITTER = "com.twitter.android";
public static final String CLIPBOARD = "com.google.android.apps.docs";
public static final String WHATSAPP = "com.whatsapp";
//static fields for custom sorting
static {
PRIORITY.put(CLIPBOARD, 0);//
PRIORITY.put(FACEBOOK, 1);
PRIORITY.put(TWITTER, 2);
PRIORITY.put(APPS_PLUS, 3);
PRIORITY.put(ANDROID_EMAIL, 4);
PRIORITY.put(ANDROID_GM, 5);
PRIORITY.put(MMS, 6);//
PRIORITY.put(WHATSAPP, 7);
}
public static void createChoserIntent(Fragment fragment, Intent prototype, final PackageManager pm, String EXTRA_TEXT, String EXTRA_SUBJECT) {
String[] forbiddenChoices = new String[]{CLIPBOARD, FACEBOOK, TWITTER, APPS_PLUS, ANDROID_EMAIL, ANDROID_GM, MMS, WHATSAPP};
List<Intent> targetedShareIntents = new ArrayList<Intent>();
List<HashMap<String, String>> intentMetaInfo = new ArrayList<HashMap<String, String>>();
Intent chooserIntent = null;
Intent dummy = new Intent(prototype.getAction());
dummy.setType(prototype.getType());
List<ResolveInfo> resInfo = pm.queryIntentActivities(dummy, 0);
if (!resInfo.isEmpty()) {
for (ResolveInfo resolveInfo : resInfo) {
if (!Arrays.asList(forbiddenChoices).contains(resolveInfo.activityInfo.packageName))
continue;
//todo hack to ignore word DYSK (remove duplicated option `copy to clipboard`, working for PL language)
if (String.valueOf(resolveInfo.activityInfo.loadLabel(pm)).equals("Dysk"))
continue;
HashMap<String, String> info = new HashMap<String, String>();
info.put("packageName", resolveInfo.activityInfo.packageName);
info.put("className", resolveInfo.activityInfo.name);
info.put("simpleName", String.valueOf(resolveInfo.activityInfo.loadLabel(pm)));
intentMetaInfo.add(info);
}
if (!intentMetaInfo.isEmpty()) {
Collections.sort(intentMetaInfo, new Comparator<HashMap<String, String>>() {
@Override
public int compare(HashMap<String, String> map1, HashMap<String, String> map2) {
int m1 = getLabeledIntentPriority(map1.get("packageName"));
int m2 = getLabeledIntentPriority(map2.get("packageName"));
if (m1 < m2)
return -1;
else if (m1 > m2)
return 1;
else
return 0;
}
});
for (HashMap<String, String> metaInfo : intentMetaInfo) {
Intent targetedShareIntent = (Intent) prototype.clone();
if (metaInfo.get("packageName").equals(CLIPBOARD)) {
targetedShareIntent.setPackage(metaInfo.get("packageName"));
targetedShareIntent.setClassName(metaInfo.get("packageName"), metaInfo.get("className"));
LabeledIntent labeledIntent = new LabeledIntent(targetedShareIntent, fragment.getActivity().getPackageName(), "Example how to change text for for copy link", R.drawable.launcher_copy_link);
targetedShareIntents.add(labeledIntent);
} else {
targetedShareIntent.setPackage(metaInfo.get("packageName"));
targetedShareIntent.setClassName(metaInfo.get("packageName"), metaInfo.get("className"));
targetedShareIntents.add(targetedShareIntent);
}
}
chooserIntent = Intent.createChooser(targetedShareIntents.remove(targetedShareIntents.size() - 1), fragment.getString(R.string.sharee));
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetedShareIntents.toArray(new Parcelable[]{}));
}
}
fragment.startActivity(Intent.createChooser(chooserIntent, fragment.getString(R.string.podziel_sie)));
}
private static int getLabeledIntentPriority(String packageName) {
if (packageName.equalsIgnoreCase(ANDROID_EMAIL))
return PRIORITY.get(ANDROID_EMAIL);
else if (packageName.equalsIgnoreCase(FACEBOOK))
return PRIORITY.get(FACEBOOK);
else if (packageName.equalsIgnoreCase(MMS))
return PRIORITY.get(MMS);
else if (packageName.equalsIgnoreCase(ANDROID_GM))
return PRIORITY.get(ANDROID_GM);
else if (packageName.equalsIgnoreCase(APPS_PLUS))
return PRIORITY.get(APPS_PLUS);
else if (packageName.equalsIgnoreCase(TWITTER))
return PRIORITY.get(TWITTER);
else if (packageName.equalsIgnoreCase(WHATSAPP))
return PRIORITY.get(WHATSAPP);
else if (packageName.equalsIgnoreCase(CLIPBOARD))
return PRIORITY.get(CLIPBOARD);
else
return 1000;//none
}
}
Based on: https://gist.github.com/mediavrog/5625602
Upvotes: 0
Reputation: 55360
The trick is that there is actually no built-in package for the clipboard (some apps provide the Copy to Clipboard option system-wide by creating such a package with the appropriate intent-filter).
However, since you're creating the chooser's options manually, you can add your own intent to handle the copy to clipboard operation. For example, like this:
... create the intentList, as before ...
// Add a custom intent to handle the "copy to clipboard" option.
Intent copyToClipboard = new Intent(this, ShareToClipboardActivity.class);
copyToClipboard.putExtra(Intent.EXTRA_TEXT, "text to copy to clipboard");
// Wrap it with a LabeledIntent and add it to the list of choosable ones.
LabeledIntent labeledCopyToClipboard = new LabeledIntent(copyToClipboard, getPackageName(), "Copy!", 0);
intentList.add(labeledCopyToClipboard);
... convert intentList to array and show chooser, as before ...
Where ShareToClipboardActivity
is your own activity, which does (at least) this:
public class ShareToClipboardActivity extends Activity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
CharSequence text = getIntent().getCharSequenceExtra(Intent.EXTRA_TEXT);
ClipboardManager clipboardManager = (ClipboardManager)getSystemService(CLIPBOARD_SERVICE);
clipboardManager.setPrimaryClip(ClipData.newPlainText(null, text));
finish();
}
}
Note that this is a bare-bones example: you would probably want drawable and string resources for the LabeledIntent
, as well as possibly showing a Toast message in ShareToClipboardActivity
, use the old ClipboardManager
if targeting pre-API 11, &c.
Upvotes: 13