Android 裝逼技術之暗碼啟動應用

什么是暗碼旺坠?

在撥號盤中輸入*#*#<code>#*#*后,APP 可以監(jiān)控到這些輸入然遏,然后做相應的動作贫途,比如啟動應用,是不是有點騷啦鸣。

下面看下這個騷操作是如何實現(xiàn)的潮饱。

效果預覽

image

源碼

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);
  }
  //……
}

具體實現(xiàn)在 DialpapFragment 中中狂,看到 DialpapFragment 實現(xiàn)了 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();
    }
    //……
}

這里調(diào)用了 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 *#*#<code>#*#* or "*#<code_starting_with_number>#"
  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);
  }
}

可以看到在撥號中接收到*#*#<code>#*#* 這樣的指令時蹲嚣,程序會對外發(fā)送廣播递瑰,這就意味著我們能夠接收這個廣播然后可以做我們想做的事情祟牲。

接下來我們看看這個接受廣播代碼是怎么寫。

應用

首先在 AndroidManifest 文件中注冊廣播接收器抖部。

<receiver
    android:name=".SecretCodeReceiver">
    <intent-filter>
        <action android:name="android.provider.Telephony.SECRET_CODE" />
        <data android:scheme="android_secret_code" android:host="1010"  />
    </intent-filter>
</receiver>

接收廣播说贝,啟動應用。

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

公眾號

我的公眾號:吳小龍同學哗总,歡迎關注交流~


?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末几颜,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子讯屈,更是在濱河造成了極大的恐慌蛋哭,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,122評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件涮母,死亡現(xiàn)場離奇詭異谆趾,居然都是意外死亡,警方通過查閱死者的電腦和手機叛本,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評論 3 395
  • 文/潘曉璐 我一進店門沪蓬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人来候,你說我怎么就攤上這事跷叉。” “怎么了营搅?”我有些...
    開封第一講書人閱讀 164,491評論 0 354
  • 文/不壞的土叔 我叫張陵云挟,是天一觀的道長。 經(jīng)常有香客問我转质,道長园欣,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,636評論 1 293
  • 正文 為了忘掉前任休蟹,我火速辦了婚禮沸枯,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘赂弓。我一直安慰自己绑榴,他們只是感情好,可當我...
    茶點故事閱讀 67,676評論 6 392
  • 文/花漫 我一把揭開白布盈魁。 她就那樣靜靜地躺著彭沼,像睡著了一般。 火紅的嫁衣襯著肌膚如雪备埃。 梳的紋絲不亂的頭發(fā)上姓惑,一...
    開封第一講書人閱讀 51,541評論 1 305
  • 那天,我揣著相機與錄音按脚,去河邊找鬼于毙。 笑死,一個胖子當著我的面吹牛辅搬,可吹牛的內(nèi)容都是我干的唯沮。 我是一名探鬼主播,決...
    沈念sama閱讀 40,292評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼堪遂,長吁一口氣:“原來是場噩夢啊……” “哼介蛉!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起溶褪,我...
    開封第一講書人閱讀 39,211評論 0 276
  • 序言:老撾萬榮一對情侶失蹤币旧,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后猿妈,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體吹菱,經(jīng)...
    沈念sama閱讀 45,655評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,846評論 3 336
  • 正文 我和宋清朗相戀三年彭则,在試婚紗的時候發(fā)現(xiàn)自己被綠了鳍刷。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,965評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡俯抖,死狀恐怖输瓜,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情芬萍,我是刑警寧澤尤揣,帶...
    沈念sama閱讀 35,684評論 5 347
  • 正文 年R本政府宣布,位于F島的核電站担忧,受9級特大地震影響芹缔,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜瓶盛,卻給世界環(huán)境...
    茶點故事閱讀 41,295評論 3 329
  • 文/蒙蒙 一最欠、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧惩猫,春花似錦芝硬、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至奶镶,卻和暖如春迟赃,著一層夾襖步出監(jiān)牢的瞬間陪拘,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評論 1 269
  • 我被黑心中介騙來泰國打工纤壁, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留左刽,地道東北人。 一個月前我還...
    沈念sama閱讀 48,126評論 3 370
  • 正文 我出身青樓酌媒,卻偏偏與公主長得像欠痴,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子秒咨,可洞房花燭夜當晚...
    茶點故事閱讀 44,914評論 2 355

推薦閱讀更多精彩內(nèi)容