Android installed password application to force the start of technology

Foreword

Like a small partner welcome attention, I will share the knowledge and Android resolve on a regular basis, but also BATJ interview topics constantly updated, welcome to come to discuss the exchange, if any good articles are also welcome to contribute.

What is the password?

In the dial pad input *#*#<code>#*#*After, APP can monitor these inputs, and then do the appropriate action, such as starting applications, is not it a little show.

The following operating facie this show is how to achieve.

Results preview


16bf36d0c72336f9?imageslim


Source

DialtactsActivity#showDialpadFragment

There are DialtactsActivity showDialpadFragment method for loading a display dial, so showDialpadFragment looks from the entrance, Android P based on the analysis.

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 *#*#<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>#*#* 这样的指令时,程序会对外发送广播,这就意味着我们能够接收这个广播然后可以做我们想做的事情。

接下来我们看看这个接受广播代码是怎么写。

应用

首先在 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);
        }
    }
}

So long as the input in the dialing *#*#1010#*#*will be able to launch the corresponding application, OK, received power.


Article feel good partner to help small little Zanga attention Oh, there are any questions are also welcome to come to discuss the exchange.

Guess you like

Origin blog.51cto.com/13673213/2420493