快上网专注成都网站设计 成都网站制作 成都网站建设
成都网站建设公司服务热线:028-86922220

网站建设知识

十年网站开发经验 + 多家企业客户 + 靠谱的建站团队

量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决

Android装逼技术之暗码启动应用-创新互联

前言

喜欢的小伙伴欢迎关注,我会定期分享Android知识点及解析,还会不断更新的BATJ面试专题,欢迎大家前来探讨交流,如有好的文章也欢迎投稿。

企业建站必须是能够以充分展现企业形象为主要目的,是企业文化与产品对外扩展宣传的重要窗口,一个合格的网站不仅仅能为公司带来巨大的互联网上的收集和信息发布平台,创新互联面向各种领域:成都公路钻孔机成都网站设计公司营销型网站建设解决方案、网站设计等建站排名服务。

什么是暗码?

在拨号盘中输入*#*##*#*后,APP 可以监控到这些输入,然后做相应的动作,比如启动应用,是不是有点骚。

下面看下这个骚操作是如何实现的。

效果预览

源码

DialtactsActivity#showDialpadFragment

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 方法。

DialpadFragment#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 方法,看这个方法。

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。

SpecialCharSequenceMgr#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 方法。

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,收功。

觉得文章不错的小伙伴帮忙点点赞加关注哦 ,有什么问题的话也欢迎大家前来探讨交流。

另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。


文章题目:Android装逼技术之暗码启动应用-创新互联
本文地址:http://6mz.cn/article/dgideo.html