Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3bf92952 authored by Jan Althaus's avatar Jan Althaus Committed by Android (Google) Code Review
Browse files

Merge "Adding multiple action support to TextClassification"

parents 67d7c5ae 92d76838
Loading
Loading
Loading
Loading
+7 −0
Original line number Original line Diff line number Diff line
@@ -48693,19 +48693,26 @@ package android.view.inputmethod {
package android.view.textclassifier {
package android.view.textclassifier {
  public final class TextClassification {
  public final class TextClassification {
    method public int getActionCount();
    method public float getConfidenceScore(java.lang.String);
    method public float getConfidenceScore(java.lang.String);
    method public java.lang.String getEntity(int);
    method public java.lang.String getEntity(int);
    method public int getEntityCount();
    method public int getEntityCount();
    method public android.graphics.drawable.Drawable getIcon(int);
    method public android.graphics.drawable.Drawable getIcon();
    method public android.graphics.drawable.Drawable getIcon();
    method public android.content.Intent getIntent(int);
    method public android.content.Intent getIntent();
    method public android.content.Intent getIntent();
    method public java.lang.CharSequence getLabel(int);
    method public java.lang.CharSequence getLabel();
    method public java.lang.CharSequence getLabel();
    method public android.view.View.OnClickListener getOnClickListener(int);
    method public android.view.View.OnClickListener getOnClickListener();
    method public android.view.View.OnClickListener getOnClickListener();
    method public java.lang.String getText();
    method public java.lang.String getText();
  }
  }
  public static final class TextClassification.Builder {
  public static final class TextClassification.Builder {
    ctor public TextClassification.Builder();
    ctor public TextClassification.Builder();
    method public android.view.textclassifier.TextClassification.Builder addAction(android.content.Intent, java.lang.String, android.graphics.drawable.Drawable, android.view.View.OnClickListener);
    method public android.view.textclassifier.TextClassification build();
    method public android.view.textclassifier.TextClassification build();
    method public android.view.textclassifier.TextClassification.Builder clearActions();
    method public android.view.textclassifier.TextClassification.Builder setEntityType(java.lang.String, float);
    method public android.view.textclassifier.TextClassification.Builder setEntityType(java.lang.String, float);
    method public android.view.textclassifier.TextClassification.Builder setIcon(android.graphics.drawable.Drawable);
    method public android.view.textclassifier.TextClassification.Builder setIcon(android.graphics.drawable.Drawable);
    method public android.view.textclassifier.TextClassification.Builder setIntent(android.content.Intent);
    method public android.view.textclassifier.TextClassification.Builder setIntent(android.content.Intent);
+7 −0
Original line number Original line Diff line number Diff line
@@ -52389,19 +52389,26 @@ package android.view.inputmethod {
package android.view.textclassifier {
package android.view.textclassifier {
  public final class TextClassification {
  public final class TextClassification {
    method public int getActionCount();
    method public float getConfidenceScore(java.lang.String);
    method public float getConfidenceScore(java.lang.String);
    method public java.lang.String getEntity(int);
    method public java.lang.String getEntity(int);
    method public int getEntityCount();
    method public int getEntityCount();
    method public android.graphics.drawable.Drawable getIcon(int);
    method public android.graphics.drawable.Drawable getIcon();
    method public android.graphics.drawable.Drawable getIcon();
    method public android.content.Intent getIntent(int);
    method public android.content.Intent getIntent();
    method public android.content.Intent getIntent();
    method public java.lang.CharSequence getLabel(int);
    method public java.lang.CharSequence getLabel();
    method public java.lang.CharSequence getLabel();
    method public android.view.View.OnClickListener getOnClickListener(int);
    method public android.view.View.OnClickListener getOnClickListener();
    method public android.view.View.OnClickListener getOnClickListener();
    method public java.lang.String getText();
    method public java.lang.String getText();
  }
  }
  public static final class TextClassification.Builder {
  public static final class TextClassification.Builder {
    ctor public TextClassification.Builder();
    ctor public TextClassification.Builder();
    method public android.view.textclassifier.TextClassification.Builder addAction(android.content.Intent, java.lang.String, android.graphics.drawable.Drawable, android.view.View.OnClickListener);
    method public android.view.textclassifier.TextClassification build();
    method public android.view.textclassifier.TextClassification build();
    method public android.view.textclassifier.TextClassification.Builder clearActions();
    method public android.view.textclassifier.TextClassification.Builder setEntityType(java.lang.String, float);
    method public android.view.textclassifier.TextClassification.Builder setEntityType(java.lang.String, float);
    method public android.view.textclassifier.TextClassification.Builder setIcon(android.graphics.drawable.Drawable);
    method public android.view.textclassifier.TextClassification.Builder setIcon(android.graphics.drawable.Drawable);
    method public android.view.textclassifier.TextClassification.Builder setIntent(android.content.Intent);
    method public android.view.textclassifier.TextClassification.Builder setIntent(android.content.Intent);
+7 −0
Original line number Original line Diff line number Diff line
@@ -49249,19 +49249,26 @@ package android.view.inputmethod {
package android.view.textclassifier {
package android.view.textclassifier {
  public final class TextClassification {
  public final class TextClassification {
    method public int getActionCount();
    method public float getConfidenceScore(java.lang.String);
    method public float getConfidenceScore(java.lang.String);
    method public java.lang.String getEntity(int);
    method public java.lang.String getEntity(int);
    method public int getEntityCount();
    method public int getEntityCount();
    method public android.graphics.drawable.Drawable getIcon(int);
    method public android.graphics.drawable.Drawable getIcon();
    method public android.graphics.drawable.Drawable getIcon();
    method public android.content.Intent getIntent(int);
    method public android.content.Intent getIntent();
    method public android.content.Intent getIntent();
    method public java.lang.CharSequence getLabel(int);
    method public java.lang.CharSequence getLabel();
    method public java.lang.CharSequence getLabel();
    method public android.view.View.OnClickListener getOnClickListener(int);
    method public android.view.View.OnClickListener getOnClickListener();
    method public android.view.View.OnClickListener getOnClickListener();
    method public java.lang.String getText();
    method public java.lang.String getText();
  }
  }
  public static final class TextClassification.Builder {
  public static final class TextClassification.Builder {
    ctor public TextClassification.Builder();
    ctor public TextClassification.Builder();
    method public android.view.textclassifier.TextClassification.Builder addAction(android.content.Intent, java.lang.String, android.graphics.drawable.Drawable, android.view.View.OnClickListener);
    method public android.view.textclassifier.TextClassification build();
    method public android.view.textclassifier.TextClassification build();
    method public android.view.textclassifier.TextClassification.Builder clearActions();
    method public android.view.textclassifier.TextClassification.Builder setEntityType(java.lang.String, float);
    method public android.view.textclassifier.TextClassification.Builder setEntityType(java.lang.String, float);
    method public android.view.textclassifier.TextClassification.Builder setIcon(android.graphics.drawable.Drawable);
    method public android.view.textclassifier.TextClassification.Builder setIcon(android.graphics.drawable.Drawable);
    method public android.view.textclassifier.TextClassification.Builder setIntent(android.content.Intent);
    method public android.view.textclassifier.TextClassification.Builder setIntent(android.content.Intent);
+153 −35
Original line number Original line Diff line number Diff line
@@ -28,6 +28,7 @@ import android.view.textclassifier.TextClassifier.EntityType;


import com.android.internal.util.Preconditions;
import com.android.internal.util.Preconditions;


import java.util.ArrayList;
import java.util.List;
import java.util.List;


/**
/**
@@ -41,10 +42,10 @@ public final class TextClassification {
    static final TextClassification EMPTY = new TextClassification.Builder().build();
    static final TextClassification EMPTY = new TextClassification.Builder().build();


    @NonNull private final String mText;
    @NonNull private final String mText;
    @Nullable private final Drawable mIcon;
    @NonNull private final List<Drawable> mIcons;
    @Nullable private final String mLabel;
    @NonNull private final List<String> mLabels;
    @Nullable private final Intent mIntent;
    @NonNull private final List<Intent> mIntents;
    @Nullable private final OnClickListener mOnClickListener;
    @NonNull private final List<OnClickListener> mOnClickListeners;
    @NonNull private final EntityConfidence<String> mEntityConfidence;
    @NonNull private final EntityConfidence<String> mEntityConfidence;
    @NonNull private final List<String> mEntities;
    @NonNull private final List<String> mEntities;
    private int mLogType;
    private int mLogType;
@@ -52,18 +53,21 @@ public final class TextClassification {


    private TextClassification(
    private TextClassification(
            @Nullable String text,
            @Nullable String text,
            @Nullable Drawable icon,
            @NonNull List<Drawable> icons,
            @Nullable String label,
            @NonNull List<String> labels,
            @Nullable Intent intent,
            @NonNull List<Intent> intents,
            @Nullable OnClickListener onClickListener,
            @NonNull List<OnClickListener> onClickListeners,
            @NonNull EntityConfidence<String> entityConfidence,
            @NonNull EntityConfidence<String> entityConfidence,
            int logType,
            int logType,
            @NonNull String versionInfo) {
            @NonNull String versionInfo) {
        Preconditions.checkArgument(labels.size() == intents.size());
        Preconditions.checkArgument(icons.size() == intents.size());
        Preconditions.checkArgument(onClickListeners.size() == intents.size());
        mText = text;
        mText = text;
        mIcon = icon;
        mIcons = icons;
        mLabel = label;
        mLabels = labels;
        mIntent = intent;
        mIntents = intents;
        mOnClickListener = onClickListener;
        mOnClickListeners = onClickListeners;
        mEntityConfidence = new EntityConfidence<>(entityConfidence);
        mEntityConfidence = new EntityConfidence<>(entityConfidence);
        mEntities = mEntityConfidence.getEntities();
        mEntities = mEntityConfidence.getEntities();
        mLogType = logType;
        mLogType = logType;
@@ -109,35 +113,106 @@ public final class TextClassification {
    }
    }


    /**
    /**
     * Returns an icon that may be rendered on a widget used to act on the classified text.
     * Returns the number of actions that are available to act on the classified text.
     * @see #getIntent(int)
     * @see #getLabel(int)
     * @see #getIcon(int)
     * @see #getOnClickListener(int)
     */
    @IntRange(from = 0)
    public int getActionCount() {
        return mIntents.size();
    }

    /**
     * Returns one of the icons that maybe rendered on a widget used to act on the classified text.
     * @param index Index of the action to get the icon for.
     * @throws IndexOutOfBoundsException if the specified index is out of range.
     * @see #getActionCount() for the number of entities available.
     * @see #getIntent(int)
     * @see #getLabel(int)
     * @see #getOnClickListener(int)
     */
    @Nullable
    public Drawable getIcon(int index) {
        return mIcons.get(index);
    }

    /**
     * Returns an icon for the default intent that may be rendered on a widget used to act on the
     * classified text.
     */
     */
    @Nullable
    @Nullable
    public Drawable getIcon() {
    public Drawable getIcon() {
        return mIcon;
        return mIcons.isEmpty() ? null : mIcons.get(0);
    }
    }


    /**
    /**
     * Returns a label that may be rendered on a widget used to act on the classified text.
     * Returns one of the labels that may be rendered on a widget used to act on the classified
     * text.
     * @param index Index of the action to get the label for.
     * @throws IndexOutOfBoundsException if the specified index is out of range.
     * @see #getActionCount()
     * @see #getIntent(int)
     * @see #getIcon(int)
     * @see #getOnClickListener(int)
     */
    @Nullable
    public CharSequence getLabel(int index) {
        return mLabels.get(index);
    }

    /**
     * Returns a label for the default intent that may be rendered on a widget used to act on the
     * classified text.
     */
     */
    @Nullable
    @Nullable
    public CharSequence getLabel() {
    public CharSequence getLabel() {
        return mLabel;
        return mLabels.isEmpty() ? null : mLabels.get(0);
    }

    /**
     * Returns one of the intents that may be fired to act on the classified text.
     * @param index Index of the action to get the intent for.
     * @throws IndexOutOfBoundsException if the specified index is out of range.
     * @see #getActionCount()
     * @see #getLabel(int)
     * @see #getIcon(int)
     * @see #getOnClickListener(int)
     */
    @Nullable
    public Intent getIntent(int index) {
        return mIntents.get(index);
    }
    }


    /**
    /**
     * Returns an intent that may be fired to act on the classified text.
     * Returns the default intent that may be fired to act on the classified text.
     */
     */
    @Nullable
    @Nullable
    public Intent getIntent() {
    public Intent getIntent() {
        return mIntent;
        return mIntents.isEmpty() ? null : mIntents.get(0);
    }

    /**
     * Returns one of the OnClickListeners that may be triggered to act on the classified text.
     * @param index Index of the action to get the click listener for.
     * @throws IndexOutOfBoundsException if the specified index is out of range.
     * @see #getActionCount()
     * @see #getIntent(int)
     * @see #getLabel(int)
     * @see #getIcon(int)
     */
    @Nullable
    public OnClickListener getOnClickListener(int index) {
        return mOnClickListeners.get(index);
    }
    }


    /**
    /**
     * Returns an OnClickListener that may be triggered to act on the classified text.
     * Returns the default OnClickListener that may be triggered to act on the classified text.
     */
     */
    @Nullable
    @Nullable
    public OnClickListener getOnClickListener() {
    public OnClickListener getOnClickListener() {
        return mOnClickListener;
        return mOnClickListeners.isEmpty() ? null : mOnClickListeners.get(0);
    }
    }


    /**
    /**
@@ -160,8 +235,8 @@ public final class TextClassification {
    @Override
    @Override
    public String toString() {
    public String toString() {
        return String.format("TextClassification {"
        return String.format("TextClassification {"
                        + "text=%s, entities=%s, label=%s, intent=%s}",
                        + "text=%s, entities=%s, labels=%s, intents=%s}",
                mText, mEntityConfidence, mLabel, mIntent);
                mText, mEntityConfidence, mLabels, mIntents);
    }
    }


    /**
    /**
@@ -184,10 +259,10 @@ public final class TextClassification {
    public static final class Builder {
    public static final class Builder {


        @NonNull private String mText;
        @NonNull private String mText;
        @Nullable private Drawable mIcon;
        @NonNull private final List<Drawable> mIcons = new ArrayList<>();
        @Nullable private String mLabel;
        @NonNull private final List<String> mLabels = new ArrayList<>();
        @Nullable private Intent mIntent;
        @NonNull private final List<Intent> mIntents = new ArrayList<>();
        @Nullable private OnClickListener mOnClickListener;
        @NonNull private final List<OnClickListener> mOnClickListeners = new ArrayList<>();
        @NonNull private final EntityConfidence<String> mEntityConfidence =
        @NonNull private final EntityConfidence<String> mEntityConfidence =
                new EntityConfidence<>();
                new EntityConfidence<>();
        private int mLogType;
        private int mLogType;
@@ -216,26 +291,57 @@ public final class TextClassification {
        }
        }


        /**
        /**
         * Sets an icon that may be rendered on a widget used to act on the classified text.
         * Adds an action that may be performed on the classified text. The label and icon are used
         * for rendering of widgets that offer the intent. Actions should be added in order of
         * priority and the first one will be treated as the default.
         */
        public Builder addAction(
                Intent intent, @Nullable String label, @Nullable Drawable icon,
                @Nullable OnClickListener onClickListener) {
            mIntents.add(intent);
            mLabels.add(label);
            mIcons.add(icon);
            mOnClickListeners.add(onClickListener);
            return this;
        }

        /**
         * Removes all actions.
         */
        public Builder clearActions() {
            mIntents.clear();
            mOnClickListeners.clear();
            mLabels.clear();
            mIcons.clear();
            return this;
        }

        /**
         * Sets the icon for the default action that may be rendered on a widget used to act on the
         * classified text.
         */
         */
        public Builder setIcon(@Nullable Drawable icon) {
        public Builder setIcon(@Nullable Drawable icon) {
            mIcon = icon;
            ensureDefaultActionAvailable();
            mIcons.set(0, icon);
            return this;
            return this;
        }
        }


        /**
        /**
         * Sets a label that may be rendered on a widget used to act on the classified text.
         * Sets the label for the default action that may be rendered on a widget used to act on the
         * classified text.
         */
         */
        public Builder setLabel(@Nullable String label) {
        public Builder setLabel(@Nullable String label) {
            mLabel = label;
            ensureDefaultActionAvailable();
            mLabels.set(0, label);
            return this;
            return this;
        }
        }


        /**
        /**
         * Sets an intent that may be fired to act on the classified text.
         * Sets the intent for the default action that may be fired to act on the classified text.
         */
         */
        public Builder setIntent(@Nullable Intent intent) {
        public Builder setIntent(@Nullable Intent intent) {
            mIntent = intent;
            ensureDefaultActionAvailable();
            mIntents.set(0, intent);
            return this;
            return this;
        }
        }


@@ -249,10 +355,12 @@ public final class TextClassification {
        }
        }


        /**
        /**
         * Sets an OnClickListener that may be triggered to act on the classified text.
         * Sets the OnClickListener for the default action that may be triggered to act on the
         * classified text.
         */
         */
        public Builder setOnClickListener(@Nullable OnClickListener onClickListener) {
        public Builder setOnClickListener(@Nullable OnClickListener onClickListener) {
            mOnClickListener = onClickListener;
            ensureDefaultActionAvailable();
            mOnClickListeners.set(0, onClickListener);
            return this;
            return this;
        }
        }


@@ -265,12 +373,22 @@ public final class TextClassification {
            return this;
            return this;
        }
        }


        /**
         * Ensures that we have at we have storage for the default action.
         */
        private void ensureDefaultActionAvailable() {
            if (mIntents.isEmpty()) mIntents.add(null);
            if (mLabels.isEmpty()) mLabels.add(null);
            if (mIcons.isEmpty()) mIcons.add(null);
            if (mOnClickListeners.isEmpty()) mOnClickListeners.add(null);
        }

        /**
        /**
         * Builds and returns a {@link TextClassification} object.
         * Builds and returns a {@link TextClassification} object.
         */
         */
        public TextClassification build() {
        public TextClassification build() {
            return new TextClassification(
            return new TextClassification(
                    mText, mIcon, mLabel, mIntent, mOnClickListener, mEntityConfidence,
                    mText, mIcons, mLabels, mIntents, mOnClickListeners, mEntityConfidence,
                    mLogType, mVersionInfo);
                    mLogType, mVersionInfo);
        }
        }
    }
    }
+81 −37
Original line number Original line Diff line number Diff line
@@ -29,6 +29,7 @@ import android.net.Uri;
import android.os.LocaleList;
import android.os.LocaleList;
import android.os.ParcelFileDescriptor;
import android.os.ParcelFileDescriptor;
import android.provider.Browser;
import android.provider.Browser;
import android.provider.ContactsContract;
import android.text.Spannable;
import android.text.Spannable;
import android.text.TextUtils;
import android.text.TextUtils;
import android.text.method.WordIterator;
import android.text.method.WordIterator;
@@ -356,7 +357,16 @@ final class TextClassifierImpl implements TextClassifier {
        final String type = getHighestScoringType(classifications);
        final String type = getHighestScoringType(classifications);
        builder.setLogType(IntentFactory.getLogType(type));
        builder.setLogType(IntentFactory.getLogType(type));


        final Intent intent = IntentFactory.create(mContext, type, text.toString());
        final List<Intent> intents = IntentFactory.create(mContext, type, text.toString());
        for (Intent intent : intents) {
            extendClassificationWithIntent(intent, builder);
        }

        return builder.setVersionInfo(getVersionInfo()).build();
    }

    /** Extends the classification with the intent if it can be resolved. */
    private void extendClassificationWithIntent(Intent intent, TextClassification.Builder builder) {
        final PackageManager pm;
        final PackageManager pm;
        final ResolveInfo resolveInfo;
        final ResolveInfo resolveInfo;
        if (intent != null) {
        if (intent != null) {
@@ -367,30 +377,29 @@ final class TextClassifierImpl implements TextClassifier {
            resolveInfo = null;
            resolveInfo = null;
        }
        }
        if (resolveInfo != null && resolveInfo.activityInfo != null) {
        if (resolveInfo != null && resolveInfo.activityInfo != null) {
            builder.setIntent(intent)
                    .setOnClickListener(TextClassification.createStartActivityOnClickListener(
                            mContext, intent));

            final String packageName = resolveInfo.activityInfo.packageName;
            final String packageName = resolveInfo.activityInfo.packageName;
            CharSequence label;
            Drawable icon;
            if ("android".equals(packageName)) {
            if ("android".equals(packageName)) {
                // Requires the chooser to find an activity to handle the intent.
                // Requires the chooser to find an activity to handle the intent.
                builder.setLabel(IntentFactory.getLabel(mContext, type));
                label = IntentFactory.getLabel(mContext, intent);
                icon = null;
            } else {
            } else {
                // A default activity will handle the intent.
                // A default activity will handle the intent.
                intent.setComponent(new ComponentName(packageName, resolveInfo.activityInfo.name));
                intent.setComponent(new ComponentName(packageName, resolveInfo.activityInfo.name));
                Drawable icon = resolveInfo.activityInfo.loadIcon(pm);
                icon = resolveInfo.activityInfo.loadIcon(pm);
                if (icon == null) {
                if (icon == null) {
                    icon = resolveInfo.loadIcon(pm);
                    icon = resolveInfo.loadIcon(pm);
                }
                }
                builder.setIcon(icon);
                label = resolveInfo.activityInfo.loadLabel(pm);
                CharSequence label = resolveInfo.activityInfo.loadLabel(pm);
                if (label == null) {
                if (label == null) {
                    label = resolveInfo.loadLabel(pm);
                    label = resolveInfo.loadLabel(pm);
                }
                }
                builder.setLabel(label != null ? label.toString() : null);
            }
            }
            builder.addAction(
                    intent, label != null ? label.toString() : null, icon,
                    TextClassification.createStartActivityOnClickListener(mContext, intent));
        }
        }
        return builder.setVersionInfo(getVersionInfo()).build();
    }
    }


    private static int getHintFlags(CharSequence text, int start, int end) {
    private static int getHintFlags(CharSequence text, int start, int end) {
@@ -477,10 +486,11 @@ final class TextClassifierImpl implements TextClassifier {
                    if (results.length > 0) {
                    if (results.length > 0) {
                        final String type = getHighestScoringType(results);
                        final String type = getHighestScoringType(results);
                        if (matches(type, linkMask)) {
                        if (matches(type, linkMask)) {
                            final Intent intent = IntentFactory.create(
                            // For links without disambiguation, we simply use the default intent.
                            final List<Intent> intents = IntentFactory.create(
                                    context, type, text.substring(selectionStart, selectionEnd));
                                    context, type, text.substring(selectionStart, selectionEnd));
                            if (hasActivityHandler(context, intent)) {
                            if (!intents.isEmpty() && hasActivityHandler(context, intents.get(0))) {
                                final ClickableSpan span = createSpan(context, intent);
                                final ClickableSpan span = createSpan(context, intents.get(0));
                                spans.add(new SpanSpec(selectionStart, selectionEnd, span));
                                spans.add(new SpanSpec(selectionStart, selectionEnd, span));
                            }
                            }
                        }
                        }
@@ -564,7 +574,7 @@ final class TextClassifierImpl implements TextClassifier {
            };
            };
        }
        }


        private static boolean hasActivityHandler(Context context, @Nullable Intent intent) {
        private static boolean hasActivityHandler(Context context, Intent intent) {
            if (intent == null) {
            if (intent == null) {
                return false;
                return false;
            }
            }
@@ -625,20 +635,32 @@ final class TextClassifierImpl implements TextClassifier {


        private IntentFactory() {}
        private IntentFactory() {}


        @Nullable
        @NonNull
        public static Intent create(Context context, String type, String text) {
        public static List<Intent> create(Context context, String type, String text) {
            final List<Intent> intents = new ArrayList<>();
            type = type.trim().toLowerCase(Locale.ENGLISH);
            type = type.trim().toLowerCase(Locale.ENGLISH);
            text = text.trim();
            text = text.trim();
            switch (type) {
            switch (type) {
                case TextClassifier.TYPE_EMAIL:
                case TextClassifier.TYPE_EMAIL:
                    return new Intent(Intent.ACTION_SENDTO)
                    intents.add(new Intent(Intent.ACTION_SENDTO)
                            .setData(Uri.parse(String.format("mailto:%s", text)));
                            .setData(Uri.parse(String.format("mailto:%s", text))));
                    intents.add(new Intent(Intent.ACTION_INSERT_OR_EDIT)
                                    .setType(ContactsContract.Contacts.CONTENT_ITEM_TYPE)
                                    .putExtra(ContactsContract.Intents.Insert.EMAIL, text));
                    break;
                case TextClassifier.TYPE_PHONE:
                case TextClassifier.TYPE_PHONE:
                    return new Intent(Intent.ACTION_DIAL)
                    intents.add(new Intent(Intent.ACTION_DIAL)
                            .setData(Uri.parse(String.format("tel:%s", text)));
                            .setData(Uri.parse(String.format("tel:%s", text))));
                    intents.add(new Intent(Intent.ACTION_INSERT_OR_EDIT)
                            .setType(ContactsContract.Contacts.CONTENT_ITEM_TYPE)
                            .putExtra(ContactsContract.Intents.Insert.PHONE, text));
                    intents.add(new Intent(Intent.ACTION_SENDTO)
                            .setData(Uri.parse(String.format("smsto:%s", text))));
                    break;
                case TextClassifier.TYPE_ADDRESS:
                case TextClassifier.TYPE_ADDRESS:
                    return new Intent(Intent.ACTION_VIEW)
                    intents.add(new Intent(Intent.ACTION_VIEW)
                            .setData(Uri.parse(String.format("geo:0,0?q=%s", text)));
                            .setData(Uri.parse(String.format("geo:0,0?q=%s", text))));
                    break;
                case TextClassifier.TYPE_URL:
                case TextClassifier.TYPE_URL:
                    final String httpPrefix = "http://";
                    final String httpPrefix = "http://";
                    final String httpsPrefix = "https://";
                    final String httpsPrefix = "https://";
@@ -649,28 +671,50 @@ final class TextClassifierImpl implements TextClassifier {
                    } else {
                    } else {
                        text = httpPrefix + text;
                        text = httpPrefix + text;
                    }
                    }
                    return new Intent(Intent.ACTION_VIEW, Uri.parse(text))
                    intents.add(new Intent(Intent.ACTION_VIEW, Uri.parse(text))
                            .putExtra(Browser.EXTRA_APPLICATION_ID, context.getPackageName());
                            .putExtra(Browser.EXTRA_APPLICATION_ID, context.getPackageName()));
                default:
                    break;
                    return null;
            }
            }
            return intents;
        }
        }


        @Nullable
        @Nullable
        public static String getLabel(Context context, String type) {
        public static String getLabel(Context context, @Nullable Intent intent) {
            type = type.trim().toLowerCase(Locale.ENGLISH);
            if (intent == null || intent.getAction() == null) {
            switch (type) {
                return null;
                case TextClassifier.TYPE_EMAIL:
            }
                    return context.getString(com.android.internal.R.string.email);
            switch (intent.getAction()) {
                case TextClassifier.TYPE_PHONE:
                case Intent.ACTION_DIAL:
                    return context.getString(com.android.internal.R.string.dial);
                    return context.getString(com.android.internal.R.string.dial);
                case TextClassifier.TYPE_ADDRESS:
                case Intent.ACTION_SENDTO:
                    switch (intent.getScheme()) {
                        case "mailto":
                            return context.getString(com.android.internal.R.string.email);
                        case "smsto":
                            return context.getString(com.android.internal.R.string.sms);
                        default:
                            return null;
                    }
                case Intent.ACTION_INSERT_OR_EDIT:
                    switch (intent.getDataString()) {
                        case ContactsContract.Contacts.CONTENT_ITEM_TYPE:
                            return context.getString(com.android.internal.R.string.add_contact);
                        default:
                            return null;
                    }
                case Intent.ACTION_VIEW:
                    switch (intent.getScheme()) {
                        case "geo":
                            return context.getString(com.android.internal.R.string.map);
                            return context.getString(com.android.internal.R.string.map);
                case TextClassifier.TYPE_URL:
                        case "http": // fall through
                        case "https":
                            return context.getString(com.android.internal.R.string.browse);
                            return context.getString(com.android.internal.R.string.browse);
                        default:
                        default:
                            return null;
                            return null;
                    }
                    }
                default:
                    return null;
            }
        }
        }


        @Nullable
        @Nullable
Loading