Fork me on GitHub

[Android]暗码机制

今天客户邮件过来一段代码让我加一下,说是用暗码启动MainActivity。

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

因为之前改过Dialer,定制过相关的暗码功能,所以没多想就直接把intent-filter加在MainActivity中了。然后测试告诉我,输入”*#*#368222#*#*“不起作用。嗯?

后来一想,好像哪里不太一样,Telephony.SECRET_CODE 好像是系统定义的,不是定制的。然后扒拉一下源码:

packages/apps/Dialer/java/com/android/dialer/app/SpecialCharSequenceMgr.java

/**
* Handles secret codes to launch arbitrary activities in the form of *#*#<code>#*#*.
*
* @param context the context to use
* @param input the text to check for a secret code in
* @return true if a secret code was encountered and handled
*/
static boolean handleSecretCode(Context context, String input) {
// Secret codes are accessed by dialing *#*#<code>#*#*

int len = input.length();
if (len <= 8 || !input.startsWith("*#*#") || !input.endsWith("#*#*")) {
return false;
}
String secretCode = input.substring(4, len - 4);
TelephonyManagerCompat.handleSecretCode(context, secretCode);
return true;
}

packages/apps/Dialer/java/com/android/contacts/common/compat/TelephonyManagerCompat.java

/**
* Handles secret codes to launch arbitrary activities.
*
* @param context the context to use
* @param secretCode the secret code without the "*#*#" prefix and "#*#*" suffix
*/
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()) {
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);
}
}

嗯,原来*#*##*#* 是定义好的暗码前后缀,拿到暗码之后,发送了一个广播。

所以需要创建一个receiver来handle这个广播:

public class SecretCodeReceiver extends BroadcastReceiver {

private static final String TAG = "SecretCodeReceiver";

@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.d(TAG, "Action = " + action);

Intent i = new Intent(Intent.ACTION_MAIN);
i.setClass(context, MainActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);

}
}

然后把intent-filter放在这个receiver中间

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

emmmm…好了

发现系统这一套暗码机制还挺好用的,也不理解客户之前为何还要定制一套暗码。

坚持原创技术分享,您的支持将鼓励我继续创作!