技術の開始を強制的にAndroidのインストールパスワードアプリ

序文

何か良い記事にも貢献することを歓迎している場合は、小さなパートナー歓迎の注意と同じように、私は定期的に知識やAndroidの決意を共有しますが、また、BATJインタビューのトピックは常に更新、交換を議論するために来て歓迎します。

パスワードは何ですか?

ダイヤルパッド入力では*#*#<code>#*#*APPは、これらの入力を監視して、そのようなアプリケーションを起動するなど適切な処置を行うことができ、後に、それは少しのショーではありません。

次のオペレーティング・facieは、このショーは実現する方法です。

結果プレビュー


16bf36d0c72336f9?imageslim


ソース

DialtactsActivity#showDialpadFragment

そこディスプレイダイヤルをロードするためのDialtactsActivity showDialpadFragment方法があるので、showDialpadFragmentは、分析に基づいて、入り口、AndroidのPから見えます。

プライベートボイドshowDialpadFragment(ブールアニメーション){ 
  // ... 
  最終FragmentTransactionフィート= getFragmentManager()のbeginTransaction()。
  IF(dialpadFragment == NULL){ 
    dialpadFragment =新しいDialpadFragment()。
    ft.add(R.id.dialtacts_container、dialpadFragment、TAG_DIALPAD_FRAGMENT)。
  }他{ 
    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>

接收广播,启动应用。

パブリッククラスSecretCodeReceiverはBroadcastReceiver {拡張
    @Override 
    ます。public void onReceive(コンテキストコンテキスト、テントの意図){ 
        場合(!意図= NULL && SECRET_CODE_ACTION.equals(intent.getAction())){ 
            ;テントI =新しいテント(Intent.ACTION_MAINを)
            i.setClass(コンテキスト、MainActivity.class)。
            i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)。
            context.startActivity(I); 
        } 
    } 
}

だから、長いダイヤルで入力として*#*#1010#*#*、対応するアプリケーションを起動することができるようになります、OK、パワーを受け取りました。


記事は、小さな小さなZangaを助けるために良いパートナーを感じるああ注意、何か質問がありますまた、為替を議論するために来て歓迎しています。

おすすめ

転載: blog.51cto.com/13673213/2420493