最近遇到了一个问题如标题所述,其实有空格就无匹配结果其实是正常的,但是为啥拨号盘EditText会在号码中自动插入空格才是问题的关键。
其实无论是T9搜索还是空格的添加都和TextWatcher有关。
第一个TextWatcher
packages/apps/Dialer/src/com/android/dialer/DialtactsActivity.java protected void onCreate(Bundle savedInstanceState) {
...
mDigitsEditText.addTextChangedListener(mPhoneSearchQueryTextListener);
...
}
DialtactsActivity中添加了EditText的第一个TextWatcher,这个Watcher中负责T9搜索。
第二个TextWatcher
packages/apps/Dialer/src/com/android/dialer/dialpad/DialpadFragment.java
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) {
...
mDigits.addTextChangedListener(this);
...
}
fragment中的负责UI更新,例如拨号盘UI中的删除按键只有在EditText不为空的情况下才能点击。
第三个TextWatcher
第三个最为隐蔽,在Dialer中的代码中其实搜索不到的,但是它实际还是在DialpadFragment初始化的。
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) {
...
PhoneNumberFormatter.setPhoneNumberFormattingTextWatcher(getActivity(), mDigits);
...
}
packages/apps/ContactsCommon/src/com/android/contacts/common/util/PhoneNumberFormatter.java
public static final void setPhoneNumberFormattingTextWatcher(Context context,
TextView textView) {
new TextWatcherLoadAsyncTask(GeoUtil.getCurrentCountryIso(context), textView)
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null);
}
private static class TextWatcherLoadAsyncTask extends
AsyncTask<Void, Void, PhoneNumberFormattingTextWatcher> {
private final String mCountryCode;
private final TextView mTextView;
public TextWatcherLoadAsyncTask(String countryCode, TextView textView) {
mCountryCode = countryCode;
mTextView = textView;
}
@Override
protected PhoneNumberFormattingTextWatcher doInBackground(Void... params) {
return new PhoneNumberFormattingTextWatcherEx(mCountryCode); //后台生成TextWatcher对象
}
@Override
protected void onPostExecute(PhoneNumberFormattingTextWatcher watcher) {
if (watcher == null || isCancelled()) {
return; // May happen if we cancel the task.
}
mTextView.addTextChangedListener(watcher); //添加TextWatcher
}
}
packages/apps/ContactsCommon/src/com/mediatek/contacts/util/PhoneNumberFormattingTextWatcherEx.java
public class PhoneNumberFormattingTextWatcherEx extends
PhoneNumberFormattingTextWatcher {
protected static boolean sSelfChanged = false; //这个类其实就是增加了一个成员,但是看不出这个成员有啥作用
protected PhoneNumberFormattingTextWatcherEx() {}
public PhoneNumberFormattingTextWatcherEx(String countryCode) {
super(countryCode);
}
@Override
public void afterTextChanged(Editable s) {
sSelfChanged = true;
super.afterTextChanged(s); //调用基类方法
sSelfChanged = false;
}
}
frameworks/base/telephony/java/android/telephony/PhoneNumberFormattingTextWatcher.java
不再贴代码,就是在afterTextChanged中格式化了号码,即添加了空格(中国区是添加空格,某些地区是添加“-”分隔符)。
根源
根本原因是对google原生代码的修改,原生中DialtactsActivity的TextWatcher其实是给另外一个EditText使用的,在修改代码中把EditText改为了同一个导致这个问题。而且这样的写法会导致TextWatcher的多次反复调用,所以修改原生代码要慎重啊。