2016-11-24 5 views
7

У меня есть простой TextView с местным номером телефона 852112222 или (8 5) 211 2222.андроид: Автоссылка номера телефонов не всегда работает

Мне нужно, чтобы это было интерактивными, поэтому, естественно, я использовал android:autoLink="all".
Но по какой-то причине я не понимаю, что тот же номер телефона не «привязан» ко всем устройствам.

На обычном устройстве Genymotion оно не работает. На моем личном устройстве OnePlus2 это сработало. Протестировано на связке на разных устройствах - не повезло.

В чем может быть проблема?
Настройки учетной записи пользователя? Версия для Android? ORM? Что-то другое?

ответ

8

Вот мое расследование.
Я создал новый проект и добавил android:autoLink="all" в текстовое изображение в activity_main.xml. Поблагодарив за вклад разработчика Android Studio, я мог видеть предварительный просмотр. И я нашел что-то необычное.

  • 12345 не связан
  • 123456 не связаны
  • 1234567связанных
  • 12345678связанных
  • 123456789 не связан
  • 1234567890 не likned
  • 12345678901связаны
  • 123456789012 не связаны

Может быть, это diffent на моем телефоне, но это был тот же самый результат выше. Поэтому я заглянул в исходный файл, обыскал keywork 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, а именно эти три класса ниже.

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
Если вас заинтересовало данное предложение, перейдите по ссылке выше. Но позаботьтесь о самой ссылке, ics-factoryrom-2-release. Поэтому я очень сомневаюсь, что это Платформа-зависимая.

Для решения, @CleverAndroid является правильным, полный контроль над LinkMovementMethod является хорошим вариантом.

1

Для телефона автоссылку конкретнее вы должны использовать

android:autoLink="phone" 

Для более см: textview autolink

+0

Почему? android: autoLink = «телефон» тоже должен работать. И он работает на некоторых устройствах. И это не вопрос. –

5

Можете ли вы попробовать ниже код. Установите атрибут программно.

активность

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
+0

Еще один результат. На некоторых устройствах такое же число связано с другим, это не так. И это не имеет значения, если я использую 'Linkify.PHONE_NUMBERS' или' Linkify.ALL' –

+0

Все, кажется, работает отлично. Дайте мне знать ваши отзывы. – young

+0

Взял ваш пример кода - не повезло. http://imgur.com/cSLuOdt Используются те же устройства, даже другие версии SDK. Тот же результат. –

4

Я видел много несоответствий при использовании автоматической ссылки. Если вы вообще работаете над версией prod. Всегда используйте SpannableStringBuilder с LinkMovementMethod. У вас есть хороший контроль над тем, как текст должен отображаться.

Ниже представлен фрагмент ниже.

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

Я хотел бы предложить вам просто добавить код страны и все ваша проблема будет решена,

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

Если добавить код страны перед номером, то нет необходимости в других временных решений.

+0

Это сработает. Несмотря на то, что телефонные номера являются введенными пользователем, и не является обычной практикой вводить коды стран при вводе номера той же страны, поэтому я не могу принудительно проверить их. –

+0

Добавление кода страны поможет разработчику решить будущие проблемы, когда его приложение для Android будет использоваться во всем мире. В этом случае пользователь не сможет выполнить вызов из-за отсутствия кода страны (недопустимый номер). Итак, почему бы не добавить его заранее для решения будущих проблем, и этот подход даже поможет разработчику добавить другие временные решения, чтобы сделать работу 'android: autoLink'. – miPlodder