web-dev-qa-db-ja.com

電話番号のandroid:autoLinkが機能しない場合がある

ローカル電話番号が852112222または(8 5)211 2222のシンプルなTextViewを持っています。

クリック可能にする必要があるため、当然Android:autoLink="all"
しかし、何らかの理由で、同じ電話番号がすべてのデバイスで「リンク」されていないことを理解できません。

プレーンなGenymotionデバイスでは機能しませんでした。私の個人用OnePlus2デバイスでは動作しました。さまざまなデバイスでたくさんテストしました-運はありません。

問題は何でしょうか?
ユーザーアカウントの設定? Android version?ORM?他に何か?

20
Martynas Jurkus

これが私の調査です。

新しいプロジェクトを作成し、_Android:autoLink="all"_のテキストビューに_activity_main.xml_を追加しました。 Android Studioの開発者に感謝します。プレビューを見ることができ、興味深いものを見つけました:

  • _12345_はリンクされていません
  • _123456_はリンクされていません
  • _1234567_リンクされた
  • _12345678_リンクされた
  • _123456789_はリンクされていません
  • _1234567890_いいね
  • _12345678901_リンクされた
  • _123456789012_はリンクされていません

結果は私の電話で同じです。だから私はソースコードを調べ、キーワードautolinkを検索しました、そして私はこれを見つけました:

_private void setText(CharSequence text, BufferType type,
                     boolean notifyBefore, int oldlen) {

    ...
    // unconcerned code above

    if (mAutoLinkMask != 0) {
        Spannable s2;

        if (type == BufferType.EDITABLE || text instanceof Spannable) {
            s2 = (Spannable) text;
        } else {
            s2 = mSpannableFactory.newSpannable(text);
        }

        if (Linkify.addLinks(s2, mAutoLinkMask)) {
            text = s2;
            type = (type == BufferType.EDITABLE) ? BufferType.EDITABLE : BufferType.SPANNABLE;

            /*
             * We must go ahead and set the text before changing the
             * movement method, because setMovementMethod() may call
             * setText() again to try to upgrade the buffer type.
             */
            mText = text;

            // Do not change the movement method for text that support text selection as it
            // would prevent an arbitrary cursor displacement.
            if (mLinksClickable && !textCanBeSelected()) {
                setMovementMethod(LinkMovementMethod.getInstance());
            }
        }
    }

    ...
    // unconcerned code above
}
_

したがって、キーワードはLinkifyです。 addLinksの場合:

_public static final boolean addLinks(@NonNull Spannable text, @LinkifyMask int mask) {
    ...

    if ((mask & PHONE_NUMBERS) != 0) {
        gatherTelLinks(links, text);
    }

    ...
}

private static final void gatherTelLinks(ArrayList<LinkSpec> links, Spannable s) {
    PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
    Iterable<PhoneNumberMatch> matches = phoneUtil.findNumbers(s.toString(),
            Locale.getDefault().getCountry(), Leniency.POSSIBLE, Long.MAX_VALUE);
    for (PhoneNumberMatch match : matches) {
        LinkSpec spec = new LinkSpec();
        spec.url = "tel:" + PhoneNumberUtils.normalizeNumber(match.rawString());
        spec.start = match.start();
        spec.end = match.end();
        links.add(spec);
    }
}
_

その後、何か問題が発生しました。SDKにはPhoneNumberUtilがなく、具体的には以下の3つのクラスがあります。

_import com.Android.i18n.phonenumbers.PhoneNumberMatch;
import com.Android.i18n.phonenumbers.PhoneNumberUtil;
import com.Android.i18n.phonenumbers.PhoneNumberUtil.Leniency;
_

とりあえず、最初の理由が浮上しました:Locale.getDefault().getCountry()
それで、設定に行き、言語を見つけ、中国語を選択しました。結果は以下のとおりです。

  • _12345_リンクされた
  • _123456_リンクされた
  • _1234567_リンクされた
  • _12345678_リンクされた
  • _123456789_リンクされた
  • _1234567890_リンクされた
  • _12345678901_リンクされた
  • _123456789012_リンクされた

次に、_com.Android.i18n.phonenumbers_のパッケージについて、これを見つけました:
https://Android.googlesource.com/platform/external/libphonenumber/+/ics-factoryrom-2-release/Java/src/com/Android/i18n/phonenumbers
興味がある場合は、上のリンクを確認してください。 URLに注意してください:_ics-factoryrom-2-release_。だから私はこれがプラットフォーム依存であることを強く疑います。

解決策として、 CleverAndroid が適切であり、LinkMovementMethodを完全に制御することは適切なオプションです。

18
Chris Wong

次のようにしてください

TextView userInput= (TextView) view.findViewById(R.id.textView);

if(userInput != null){
     Linkify.addLinks(userInput, Patterns.PHONE,"tel:",Linkify.sPhoneNumberMatchFilter,Linkify.sPhoneNumberTransformFilter);
     userInput.setMovementMethod(LinkMovementMethod.getInstance());
}

そしてまた

Android:autoLink

あなたのxmlファイルから

7
Harsh Agrawal

国コードを追加するだけをお勧めします。問題がすべて解決されます。

Android:autoLink="phone"
Android:text="+91-8000000000"

番号の前に国コードを追加すると、他の一時的な解決策は不要になります。

5
miPlodder

以下のコードを試してください。プログラムで属性を設定します。

アクティビティ

package custom.com.Android_lab;

import Android.app.Activity;
import Android.os.Bundle;
import Android.text.util.Linkify;
import Android.widget.TextView;

/**
 * You can use Activity or AppCompatActivity
 */
public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        // local phone number 852112222 or (8 5) 211 2222.

        // Tested OK!
        TextView textView1 = (TextView) findViewById(R.id.textv1);
        textView1.setAutoLinkMask(Linkify.PHONE_NUMBERS);
        textView1.setText("852112222");

        // Tested OK!
        TextView textView2 = (TextView) findViewById(R.id.textv2);
        textView2.setAutoLinkMask(Linkify.PHONE_NUMBERS);
        textView2.setText("(85) 211-2222");

        // Tested Failed!
        // Reason : Need to apply setAutoLinkMask prior to apply setText
        TextView textView3 = (TextView) findViewById(R.id.textv3);
        textView3.setText("852112222");
        textView2.setAutoLinkMask(Linkify.PHONE_NUMBERS);

    }
}   

ビュー

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:id="@+id/activity_main"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:orientation="vertical">

    <TextView
        Android:id="@+id/textv1"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content" />

    <TextView
        Android:id="@+id/textv2"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content" />

    <TextView
        Android:id="@+id/textv3"
        Android:layout_width="match_parent"
        Android:layout_height="55dp" />

</LinearLayout>   

enter image description here

テストデバイス

  1. Android 7.1
  2. Genymotion。 4.1.1-API 16
5
young

自動リンクを使用すると、多くの不整合が発生します。もしあなたが製品版で働いているなら。常にLinkMovementMethodを使用してSpannableStringBuilderを使用してください。テキストの表示方法を適切に制御できます。

以下のスニペットが役立つ場合があります。

String phone = "your phone number";
String message = "Phone number is: ";

Spannable span = new SpannableString(String.format("%s\n%s",message, phone));
ForegroundColorSpan color = new ForegroundColorSpan(Res.color(R.color.blue));
ClickableSpan click = new ClickableSpan() {
    @Override
        public void onClick(View widget) {
            Navigator.dialer("your phone number");
        }
        public void updateDrawState(TextPaint ds) {// override updateDrawState
            ds.setUnderlineText(false); // set to false to remove underline
        }
    };

span.setSpan(color, message.length(), message.length() + phone.length() + 1, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
span.setSpan(click, message.length(), message.length() + phone.length() + 1, Spanned.SPAN_INCLUSIVE_INCLUSIVE);

changesMessageLabel.setText(span);
changesMessageLabel.setMovementMethod(LinkMovementMethod.getInstance());
4
CleverAndroid

Harsh Agrawal 電話番号が3桁で11桁以上の場合、私にとってはうまくいきました。 例: 123 456 78910

TextView textView = findViewById(R.id.text_view);
textView.setText("123 456 78910");
Linkify.addLinks(textView, Patterns.PHONE, "tel:", Linkify.sPhoneNumberMatchFilter,
            Linkify.sPhoneNumberTransformFilter);

Linkify.addLinks機能するテキストを設定した後。

ご了承ください Linkify.addLinksはすでにテキストビューでsetMovementMethodを呼び出しています。

4
fluxeon

電話番号のユニバーサルパターンを作成し、次にLinkifyマスクを追加します(Kotlin、拡張機能):

fun TextView.makeLinkedable(){
    val pattern = Pattern.compile("""([\d|\(][\h|\(\d{3}\)|\.|\-|\d]{4,}\d)""",
 Pattern.CASE_INSENSITIVE)
    LinkifyCompat.addLinks(this, Linkify.ALL)
    LinkifyCompat.addLinks(this, pattern, "tel://", null, null, null)
    setLinkTextColor(ContextCompat.getColor(context, R.color.blue))
}

すべてのデバイスで機能するはずです

4
Iliya Mashin

一部の番号はautoLink = "phone"で受け入れられません

したがって、ClickViewにclickListenerを追加してPhone Intentを直接呼び出すことができます。

電話をクラス属性として宣言します。

private String phone = "1234567890";

アクティビティのonCreate()メソッドで:

//...
TextView  tvPhoneTelefone = (TextView) findViewById(R.id.tv_telefone);
tvPhone.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        Intent callIntent = new Intent(Intent.ACTION_DIAL);
        callIntent.setData(Uri.parse("tel:" + phone ));
        startActivity(callIntent);
    }
});

これは任意の数で機能するはずです。

0
Derzu

特定の電話オートリンクについては、使用する必要があります

Android:autoLink="phone"

詳しくは textview autolink を参照してください

0
Ready Android

Iliya Mashinの答え が私にとって最良の解決策でした。

私はそれをJavaに適合させ、最後に少なくとも4つの数字を指定しました(そのため、3つの数字「xxxxx-xxx」で終わるいくつかの郵便番号をリンクしません))ので、そうしない場合この特定の制限が必要な場合は、末尾の「{4、}」を削除してください)。

    LinkifyCompat.addLinks(textView, Linkify.ALL); // This will use the usual linkify for any other format
    Pattern pattern = Pattern.compile("([\\d|\\(][\\h|\\(\\d{3}\\)|\\.|\\-|\\d]{4,}\\d{4,})", Pattern.CASE_INSENSITIVE);
    LinkifyCompat.addLinks(textView, pattern, "tel://", null, null, null); // this adds the format for all kinds of phone number

数字だけをリンクしたい場合は、最初の行( "Linkify.ALL"のある行)を削除してください。

0
Isan Campos