如何将“复制到剪贴板”添加到自定义Intent Chooser?

时间:2014-07-14 13:28:32

标签: android share clipboard

According to this solution,我想添加"复制到剪贴板"自定义共享对话框中的操作 - 与默认操作共享提供程序中的操作相同。

enter image description here

我所尝试的是添加if clausule语句,单词packageName.contains("clipboard")但没有成功。

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));
    }

整个代码均来自https://stackoverflow.com/a/18068122/619673

adb shell pm list packages返回了我的包名列表,但没有这个短语。

我可以以某种方式获取剪贴板的包名称,将其添加到我的共享提供商的自定义列表中吗?

这是一个例子,"复制到剪贴板"选项:

enter image description here

3 个答案:

答案 0 :(得分:9)

诀窍是实际上没有用于剪贴板的内置包(一些应用程序通过使用适当的intent-filter创建这样的包,在系统范围内提供 Copy to Clipboard 选项)。

但是,由于您正在手动创建选择器选项 ,因此您可以添加您自己的意图来处理复制到剪贴板操作。例如,像这样:

... 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 ...

ShareToClipboardActivity是您自己的活动,其中(至少)这是:

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();
    }
}

请注意,这是一个简单的示例:您可能需要LabeledIntent的可绘制和字符串资源,以及可能在ShareToClipboardActivity中显示Toast消息,使用旧{{1}如果定位到API 11之前,& c。

答案 1 :(得分:4)

<强>更新 我的解决方案依赖于另一个应用程序包,我意识到它可能不是正确的方法。因此,建议您定义自己的Activity,它将使用ClipboardManager处理复制和粘贴功能,如另一个答案here中所示。

原始答案

Clipboard活动详情:

  • 包名:com.google.android.apps.docs
  • 活动名称:com.google.android.apps.docs.app.SendTextToClipboardActivity

关注Intent代码将启动并执行clipboard活动。

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);

您可以在if添加intent时添加适当的intentList子句。

答案 2 :(得分:0)

工作解决方案

可能很大,但理解起来很简单。此解决方案仅显示列表中的包,按优先级排序。还有一些示例如何从意图列表中更改文本。

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
    }
}

基于:https://gist.github.com/mediavrog/5625602