十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
喜欢的小伙伴欢迎关注,我会定期分享Android知识点及解析,还会不断更新的BATJ面试专题,欢迎大家前来探讨交流,如有好的文章也欢迎投稿。
创新互联公司是一家专注于网站设计制作、成都网站设计与策划设计,义乌网站建设哪家好?创新互联公司做网站,专注于网站建设10年,网设计领域的专业建站公司;建站业务涵盖:义乌等地区。义乌做网站价格咨询:13518219792
在拨号盘中输入*#*#
#*#*
后,APP 可以监控到这些输入,然后做相应的动作,比如启动应用,是不是有点骚。
下面看下这个骚操作是如何实现的。
cdn.xitu.io/2019/7/15/16bf36d0c72336f9?imageslim">
DialtactsActivity 中有个 showDialpadFragment 方法,用来加载显示拨号盘,因此入口就从 showDialpadFragment 看起,基于 Android P 分析。
private void showDialpadFragment(boolean animate) { //…… final FragmentTransaction ft = getFragmentManager().beginTransaction(); if (dialpadFragment == null) { dialpadFragment = new DialpadFragment(); ft.add(R.id.dialtacts_container, dialpadFragment, TAG_DIALPAD_FRAGMENT); } else { ft.show(dialpadFragment); } //…… }
具体实现在 DialpapFragment 中,看到 DialpapFragment 实现了 TextWatcher,TextWatcher 有 3 个重要方法,分别为:beforeTextChanged,onTextChanged 和 afterTextChanged,重点看 afterTextChanged 方法。
public class DialpadFragment extends Fragment implements View.OnClickListener, View.OnLongClickListener, View.OnKeyListener, AdapterView.OnItemClickListener, TextWatcher, PopupMenu.OnMenuItemClickListener, DialpadKeyButton.OnPressedListener { //…… @Override public void afterTextChanged(Editable input) { // When DTMF dialpad buttons are being pressed, we delay SpecialCharSequenceMgr sequence, // since some of SpecialCharSequenceMgr's behavior is too abrupt for the "touch-down" // behavior. if (!digitsFilledByIntent && SpecialCharSequenceMgr.handleChars(getActivity(), input.toString(), digits)) { // A special sequence was entered, clear the digits digits.getText().clear(); } if (isDigitsEmpty()) { digitsFilledByIntent = false; digits.setCursorVisible(false); } if (dialpadQueryListener != null) { dialpadQueryListener.onDialpadQueryChanged(digits.getText().toString()); } updateDeleteButtonEnabledState(); } //…… }
这里调用了 SpecialCharSequenceMgr 辅助工具类的 handleChars 方法,看这个方法。
public static boolean handleChars(Context context, String input, EditText textField) { // get rid of the separators so that the string gets parsed correctly String dialString = PhoneNumberUtils.stripSeparators(input); if (handleDeviceIdDisplay(context, dialString) || handleRegulatoryInfoDisplay(context, dialString) || handlePinEntry(context, dialString) || handleAdnEntry(context, dialString, textField) || handleSecretCode(context, dialString)) { return true; } if (MotorolaUtils.handleSpecialCharSequence(context, input)) { return true; } return false; }
handleChars 方法中,会对各种特殊的 secret code 进行匹配处理,这里我们看 handleSecretCode。
static boolean handleSecretCode(Context context, String input) {
// Secret code specific to OEMs should be handled first.
if (TranssionUtils.isTranssionSecretCode(input)) {
TranssionUtils.handleTranssionSecretCode(context, input);
return true;
}
// Secret codes are accessed by dialing *#*##*#* or "*##"
if (input.length() > 8 && input.startsWith("*#*#") && input.endsWith("#*#*")) {
String secretCode = input.substring(4, input.length() - 4);
TelephonyManagerCompat.handleSecretCode(context, secretCode);
return true;
}
return false;
}
再看下 TelephonyManagerCompat.handleSecretCode 方法。
public static void handleSecretCode(Context context, String secretCode) { // Must use system service on O+ to avoid using broadcasts, which are not allowed on O+. if (BuildCompat.isAtLeastO()) { if (!TelecomUtil.isDefaultDialer(context)) { LogUtil.e( "TelephonyManagerCompat.handleSecretCode", "not default dialer, cannot send special code"); return; } context.getSystemService(TelephonyManager.class).sendDialerSpecialCode(secretCode); } else { // System service call is not supported pre-O, so must use a broadcast for N-. Intent intent = new Intent(SECRET_CODE_ACTION, Uri.parse("android_secret_code://" + secretCode)); context.sendBroadcast(intent); } }
可以看到在拨号中接收到*#*#
#*#*
这样的指令时,程序会对外发送广播,这就意味着我们能够接收这个广播然后可以做我们想做的事情。
接下来我们看看这个接受广播代码是怎么写。
首先在 AndroidManifest 文件中注册广播接收器。
接收广播,启动应用。
public class SecretCodeReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (intent != null && SECRET_CODE_ACTION.equals(intent.getAction())){ Intent i = new Intent(Intent.ACTION_MAIN); i.setClass(context, MainActivity.class); i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(i); } } }
这样只要在拨号中输入*#*#1010#*#*
就能启动相应的应用程序,OK,收功。
觉得文章不错的小伙伴帮忙点点赞加关注哦 ,有什么问题的话也欢迎大家前来探讨交流。