前言

喜欢的小伙伴欢迎关注,我会定期分享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#afterTextChangedpublic 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#handleCharspublic 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#handleSecretCodestatic 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#handleSecretCodepublic 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 文件中注册广播接收器。

android:name=".SecretCodeReceiver">

接收广播,启动应用。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,收功。

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

android中暂停服务,Android 装逼技术之暗码启动应用相关推荐

  1. Android 装逼技术之暗码启动应用

    作者:吴小龙同學 | 公众号:吴小龙同學 什么是暗码? 在拨号盘中输入*#*#<code>#*#*后,APP 可以监控到这些输入,然后做相应的动作,比如启动应用,是不是有点骚. 下面看下这 ...

  2. android中暂停服务,Android暂停服务,线程,Asynctask?使用postdelayed的处理程序呢?...

    我有后台服务(Service→Thread→Timer→Asynctask). Timer每5秒执行一次Asynctask.如果Asynctask返回true,则发送通知.Android暂停服务,线程 ...

  3. Android 系统(125)---Android通过Dialer实现暗码启动

    Android通过Dialer实现暗码启动 目前接触比较多的就是通过dialer应用来启动/触发暗码. 本文以Dialer为例, 1.经过调试定位,发现拨号盘接对应的Activity为Dialtact ...

  4. android中服务播放音乐,为什么我们需要Android中的服务?音乐播放也可以通过后台线程完成...

    采访中有人问我这个问题.我不确定这是否是问这个问题的合适论坛,因为它不涉及任何代码,而是对android概念的理解. 问题是"当所有事情都可以通过Android中的后台线程完成时,为什么我们 ...

  5. Android 中的数据储存方案, 持久化技术

    为什么80%的码农都做不了架构师?>>>    Android 中储存数据的方法主要有三种: 1,文件储存. 2,SharedPreference储存. 3,数据库储存. 1. 文件 ...

  6. Android _自定义芝麻积分(装逼神器)

    本文由陈朝勇原创. 陈朝勇的博客地址: http://blog.csdn.net/ccy0122 本篇文章是我的一个算是做注释的一个博客,废话不多说,开始我们的神器开发. 首先看下我们的效果图, 1. ...

  7. android开机优化服务,Android开机速度优化简单回顾

    Android的开机速度,基本上没人说快的,通常移植完系统后,马上要看的事情就是优化开机时间,以下是简单回忆以下以前做优化的那些事. 开机时间都花在哪? 优化开机时间,通常做的首先是那有有没有BUG, ...

  8. 21条精通程序员装逼技术

    1. 电脑一定不能盖机箱盖,用来表示自己拆装机小CASE且经常升级自己用了四五年的破电脑<br><br> 2. 桌上必须散放各种内存条 优盘 或者拆开的光驱硬盘报废的CPU等 ...

  9. android四大组件 服务,Android四大组件之Service

    Service Service(服务)是一个可以在后台执行长时间运行操作而不使用用户界面的应用组件.服务可由其他应用组件启动,而且即使用户切换到其他应用,服务仍将在后台继续运行. 此外,组件可以绑定到 ...

最新文章

  1. TTL电平、CMOS电平、RS232电平的区别
  2. AribaWeb 框架学习系列之一
  3. 【福利】快来参与抽奖获得《C语言程序设计》
  4. HTML5:一些部件
  5. 从长板和咏春看单板滑雪固定器角度选择
  6. npm ERR! Unexpected end of JSON input while parsing near '...on:0.10.3,direc to'
  7. 【ArcGIS Pro微课1000例】0002:ArcGIS Pro 2.5二三维联动显示
  8. 【操作系统复习】操作系统的特征
  9. display none 隐藏后怎么显示_display:none与visibility:hidden的区别?
  10. linux合并第一列相同的行,linux – 合并重复的行并在最后添加“N / A...
  11. 马来西亚国家银行暂无发行央行数字货币计划
  12. BatchNormalization 优点
  13. python2升级python3
  14. 现代控制理论课程实验三:一阶倒立摆的LQR控制器设计
  15. 电感电容串联起什么作用
  16. 读《卧底经济学》有感
  17. FESCO数字一体化建设项目简介
  18. web展示萤石云视频
  19. 中首清算|大数据助力灵活用工保驾护航
  20. matlab 卡丹 公式,卡丹公式欺骗了五百年所有数学家

热门文章

  1. java创建一个不可变对象_使用不可变对象创建值对象
  2. lagom的微服务框架_微服务有麻烦吗? Lagom在这里为您提供帮助。 试试吧!
  3. 记录日志的测试软件_教程:测试期间的日志记录
  4. stateless_Spring Stateless State Security第3部分:JWT +社会认证
  5. akka应用_处理Akka应用程序中的每个事件
  6. lucene 多个分词查找_使用Lucene的新FreeTextSuggester查找长尾建议
  7. Java的最新发展– 2018年4月下旬
  8. Java 8 –按值对HashMap进行升序和降序排序
  9. ibm aix_IBM AIX:Java进程大小监视
  10. 基于javafx的五子棋_JavaFX中基于表达式的PathTransitions