應(yīng)用場(chǎng)景
有一些出廠測(cè)試的程序,或者一些隱秘的程序,不能將app的啟動(dòng)圖標(biāo)直接顯示到程序列表中,所以我們需要將程序隱藏,通過(guò)撥號(hào)輸入特定的號(hào)碼或字符來(lái)啟動(dòng)程序。
原理
如果你詳細(xì)研究過(guò)android源碼(當(dāng)然本人看的是低版本的你懂的),在聯(lián)系人模塊中有一個(gè)文件:
packages/apps/Contacts/src/com/android/contacts/SpecialCharSequenceMgr.java
他里面有一段關(guān)鍵代碼是這樣寫(xiě)的:
/**
* Handles secret codes to launch arbitrary activities in the form of *#*#<code>#*#*.
* If a secret code is encountered an Intent is started with the android_secret_code://<code>
* URI.
*
* @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
*/
static boolean handleSecretCode(Context context, String input) {
// Secret codes are in the form *#*#<code>#*#*
int len = input.length();
if (len > 8 && input.startsWith("*#*#") && input.endsWith("#*#*")) {
Intent intent = new Intent(Intents.SECRET_CODE_ACTION,
Uri.parse("android_secret_code://" + input.substring(4, len - 4)));
context.sendBroadcast(intent);
return true;
}
return false;
}
可以看到在撥號(hào)中當(dāng)接收到*#*#< code >#*#* 這樣的指令時(shí),程序會(huì)對(duì)外發(fā)送廣播。這就意味著我們都能夠接收這個(gè)廣播然后做自己想做的事情了。接下來(lái)我們看看代碼怎么寫(xiě):
暗碼啟動(dòng)代碼
-
1.自己設(shè)置一個(gè)key準(zhǔn)備作為啟動(dòng)的指令
public interface Constants { //通過(guò)暗碼撥號(hào)進(jìn)入應(yīng)用的key 需要與Manifest中注冊(cè)broadcast時(shí)host節(jié)點(diǎn)的值對(duì)應(yīng) String SECRET_CODE = "123"; }
-
2.在AndroidManifest文件中注冊(cè)廣播接收器
<receiver android:name=".broadcast.PhoneBroadcastReceiver"> <intent-filter> <action android:name="android.provider.Telephony.SECRET_CODE"/> <data android:host="123" android:scheme="android_secret_code"/> </intent-filter> </receiver>
-
3.接收廣播啟動(dòng)應(yīng)用
public class PhoneBroadcastReceiver extends BroadcastReceiver {
public static final String SECRET_CODE_ACTION = "android.provider.Telephony.SECRET_CODE";
@Override
public void onReceive(Context context, Intent intent) {
switch (intent.getAction()) {
case SECRET_CODE_ACTION:
Uri uri = intent.getData();
if(uri != null){
String host = uri.getSchemeSpecificPart().substring(2);
if(Constants.SECRET_CODE.equals(host)){
//啟動(dòng)應(yīng)用
Intent intent = new Intent(context, LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
}
break;
}
}
}
經(jīng)過(guò)以上3步就能夠?qū)崿F(xiàn)暗碼啟動(dòng)了, 只要在撥號(hào)中輸入*#*#123#*#*就會(huì)啟動(dòng)自己的程序。(我是用的5.1的手機(jī)測(cè)試的能夠正常啟動(dòng)5.1以上的系統(tǒng)未經(jīng)測(cè)試如果感興趣的可以自己去試試)
繼續(xù)探索
很不幸的是當(dāng)你去使用的時(shí)候會(huì)發(fā)現(xiàn)輸入這個(gè)暗碼口令也太麻煩了又長(zhǎng)又難輸,于是又有了新的需求能不能不要輸入 *#*# #*#*這條麻煩發(fā)口令,于是我換了一種思路來(lái)處理這個(gè)問(wèn)題,那就是通過(guò)撥號(hào)啟動(dòng)。通過(guò)監(jiān)聽(tīng)撥號(hào)廣播啟動(dòng)應(yīng)用。效果如下:
撥號(hào)啟動(dòng)代碼
- 1.自己設(shè)置一個(gè)key準(zhǔn)備作為撥號(hào)啟動(dòng)的指令
使用這種方式會(huì)攔截掉您的撥號(hào),千萬(wàn)不要將key設(shè)置為110,120 或者你老婆的電話啥的 (本文只是做一個(gè)示例未滿18歲請(qǐng)勿模仿)
public interface Constants {
//撥號(hào)進(jìn)入應(yīng)用的指令
String DIALING_INSTRUCTIONS = "110";
}
-
2.在AndroidManifest文件中添加權(quán)限
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
-
3.在AndroidManifest文件中注冊(cè)廣播接收者
<receiver android:name=".broadcast.PhoneBroadcastReceiver"> <intent-filter android:priority="1000"> <action android:name="android.intent.action.NEW_OUTGOING_CALL"/> </intent-filter> </receiver>
-
4.接收廣播啟動(dòng)應(yīng)用
public class PhoneBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); switch (action) { case Intent.ACTION_NEW_OUTGOING_CALL: //取得播出電話的號(hào)碼 String phoneNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER); //匹配撥號(hào)指令 if (Constants.DIALING_INSTRUCTIONS.equals(phoneNumber)) { //跳轉(zhuǎn)到應(yīng)用 Intent mIntent = new Intent(context, LoginActivity.class); mIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(mIntent); // 掐斷廣播 setResultData(null); } break; } }
5.注意事項(xiàng)
本人使用5.1系統(tǒng)的手機(jī)測(cè)試,使用這個(gè)方法啟動(dòng)應(yīng)用需要手機(jī)在安裝了手機(jī)卡的情況下,不然撥號(hào)不會(huì)成功,會(huì)彈出沒(méi)有手機(jī)卡的提示。 需要注意的是一定要在廣播接收到以后掐斷廣播,即:setResultData(null); 不然界面跳轉(zhuǎn)以后撥號(hào)還在繼續(xù)。
結(jié)語(yǔ)
使用以上兩種方法啟動(dòng)應(yīng)用都需要自己建立activity棧對(duì)activity的順序進(jìn)行處理,不然如果應(yīng)用還在運(yùn)行再次撥號(hào)啟動(dòng)就會(huì)使得activity多重層疊。