現在,用戶(hù)可以在應用的preferences中保存輸入的密碼了,接下來(lái),我們將要檢查手機接收到的短信,并且對我們感興趣的短信做出響應。這種短信的格式為:
SMSLOCATE:<password>
因此,如果某條短信以“SMSLOCATE:”開(kāi)頭,并且緊跟‘:’字符后面的密碼的MD5和我們先前存儲的匹配,我們將回復一條包含手機當前位置信息的短信。為了實(shí)現這一目的,我們需要建立一個(gè)IntentReceiver,響應類(lèi)型為“android.provider.Telephony.SMS_RECEIVED”的Action。該IntentReceiver必須在A(yíng)ndroidManifest.xml 文件中聲明,以下是AndroidManifest.xml 文件:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.helloandroid.android.phonefinder">
<uses-permission id="android.permission.RECEIVE_SMS" />
<application android:icon="@drawable/icon">
<activity class=".PhoneFinder" android:label="@string/app_name">
<intent-filter>
<action android:value="android.intent.action.MAIN" />
<category android:value="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver class=".FinderReceiver">
<intent-filter>
<action android:value="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
</application>
</manifest>
在第4行,通過(guò)<uses-permission>標簽,我們請求接收短信的權限。在第13行,我們指定我們的FinderReceiver作為一個(gè)receiver,同時(shí)聲明了intent-filter,以此來(lái)過(guò)濾被廣播的所有intent。你可以看到,我們只對“android.provider.Telephony.SMS_RECEIVED”這類(lèi)action感興趣。
現在,系統知道了對于這類(lèi)action,該調用何種receiver。接下來(lái)我們來(lái)創(chuàng )建名為FinderReceiver的IntentReceiver。
public class FinderReceiver extends IntentReceiver {
@Override
public void onReceiveIntent(Context context, Intent intent) {
SharedPreferences passwdfile = context.getSharedPreferences(
PhoneFinder.PASSWORD_PREF_KEY, 0);
String correctMd5 = passwdfile.getString(PhoneFinder.PASSWORD_PREF_KEY,
null);
if (correctMd5 != null) {
SmsMessage[] messages = Telephony.Sms.Intents
.getMessagesFromIntent(intent);
for (SmsMessage msg : messages) {
if (msg.getMessageBody().contains("SMSLOCATE:")) {
String[] tokens = msg.getMessageBody().split(":");
if (tokens.length >= 2) {
String md5hash = PhoneFinder.getMd5Hash(tokens[1]);
if (md5hash.equals(correctMd5)) {
String to = msg.getOriginatingAddress();
LocationManager lm =
(LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
SmsManager sm = SmsManager.getDefault();
sm.sendTextMessage(to, null, lm.getCurrentLocation("gps").toString(),
null, null, null);
NotificationManager nm =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
nm.notifyWithText(R.layout.main,
context.getText(R.string.notify_text) + " " + msg.getDisplayOriginatingAddress(),
NotificationManager.LENGTH_LONG, null);
}
}
}
}
}
}
}
首先,我們從SharedPreferences取出密碼的MD5(18-21行),如果我們取到了,我們就用它來(lái)檢查我們接收到的所有的短信。 我們使用Telphony.Sms.Intents.getMessageFromInent(intent)來(lái)獲取SmsMessages數組,我們將遍歷該數組,查看每條短信消息體中是否包含“SMSLOCATE:”標記,如果找到符合條件的短消息,我們會(huì )獲取‘:’字符后的密碼,計算其MD5,和手機里存儲的MD5進(jìn)行比較。 如果密碼匹配,系統會(huì )執行第36行處的代碼塊。接下來(lái)我們將回復該短信,現在我們只需要一個(gè)代表短信目的地的字符串,以及代表手機位置信息的字符串。我們創(chuàng )建一個(gè)LocationManager,使用其getCurrentLocation("gps").toString()方法來(lái)獲取位置信息。該信息由GPS位置服務(wù)提供者提供。然后,我們使用一個(gè)SmsManager對象發(fā)送短信。短信發(fā)送完畢后,我們還會(huì )顯示一個(gè)通知。 注意:有一個(gè)可能更好做法是,在密碼輸入對話(huà)框中加入一個(gè)可選項來(lái)控制是否顯示通知。如果手機被偷,最好把通知隱藏起來(lái),否則小偷會(huì )意識到自己被跟蹤,從而把手機關(guān)掉。
測試
現在,萬(wàn)事俱備。在新版的android SDK中,給模擬器打電話(huà)或者發(fā)短信都很容易。這些操作都可以通過(guò)Eclipse中的模擬器控制面板視圖來(lái)完成。你可以通過(guò)“"Window -> Show View -> Other”,選擇android部分的“Emulator Control”項來(lái)增加這個(gè)視圖。 譯者注:如果你的android Eclipse插件為ADT0.3.1,請務(wù)必升級到ADT0.3.3,升級步驟見(jiàn) http://code.google.com/android/intro/upgrading.html 測試的第一步是激活主Activity,設置密碼。例如,我使用“123456”作為密碼,接下來(lái),你可以發(fā)送一條內容為“SMSLOCATE:123456”的短信,如下圖所示:
好了,一切OK。我想,這是一個(gè)很好的例子。通過(guò)它,你會(huì )發(fā)現在android平臺上開(kāi)發(fā)一個(gè)有用的應用是多么的容易。我們通過(guò)2個(gè)基本的對象就完成了一件非常有用的任務(wù)。

