原文地址:http://blog.ygeekcome.com/archives/186
開發軟件的目的很單純:如果想知道Ta的位置,你不用主動詢問,打開手機軟件,即可查看到對方的實時位置。
軟件的早期版本沒有使用PUSH服務,而是通過動態算法輪詢的方式進行位置數據提交,比較耗費電量和流量。
軟件最新版本下載地址:
在新版的軟件中加入了PUSH服務,在手機開機完成後會自動啓動一個後臺的PUSH服務,建立與PUSH服務器的長連接,以便收取到推送的消息。
PUSH服務使用的是JPUSH提供的免費服務。
在Android工程中添加JPUSH支持:
1、導入 SDK 開發包到你自己的應用程序項目
2、配置 AndroidManifest.xml
根據 SDK 壓縮包裏的 AndroidManifest.xml 樣例文件,來配置應用程序項目的 AndroidManifest.xml 。
主要步驟爲:
- 複製備註爲 “Required” 的部分
- 將備註爲替換包名的部分,替換爲當前應用程序的包名
將AppKey替換爲在Portal上註冊該應用的的Key,例如(9fed5bcb7b9b87413678c407)
01 | <? xml version = "1.0" encoding = "utf-8" ?> |
03 | package = "Your Package" |
04 | android:versionCode = "100" |
05 | android:versionName = "1.0.0" |
09 | < permission android:name = "Your Package.permission.JPUSH_MESSAGE" android:protectionLevel = "signature" /> |
12 | < uses-permission android:name = "You Package.permission.JPUSH_MESSAGE" /> |
13 | < uses-permission android:name = "android.permission.RECEIVE_USER_PRESENT" /> |
14 | < uses-permission android:name = "android.permission.INTERNET" /> |
15 | < uses-permission android:name = "android.permission.WAKE_LOCK" /> |
16 | < uses-permission android:name = "android.permission.READ_PHONE_STATE" /> |
17 | < uses-permission android:name = "android.permission.WRITE_EXTERNAL_STORAGE" /> |
18 | < uses-permission android:name = "android.permission.READ_EXTERNAL_STORAGE" /> |
19 | < uses-permission android:name = "android.permission.VIBRATE" /> |
20 | < uses-permission android:name = "android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /> |
21 | < uses-permission android:name = "android.permission.ACCESS_NETWORK_STATE" /> |
24 | < uses-permission android:name = "android.permission.ACCESS_COARSE_LOCATION" /> |
25 | < uses-permission android:name = "android.permission.ACCESS_COARSE_UPDATES" /> |
26 | < uses-permission android:name = "android.permission.ACCESS_WIFI_STATE" /> |
27 | < uses-permission android:name = "android.permission.CHANGE_WIFI_STATE" /> |
28 | < uses-permission android:name = "android.permission.ACCESS_FINE_LOCATION" /> |
29 | < uses-permission android:name = "android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" /> |
30 | < uses-permission android:name = "android.permission.CHANGE_NETWORK_STATE" /> |
33 | android:icon = "@drawable/ic_launcher" |
34 | android:label = "@string/app_name" |
35 | android:name = "Your Application" > |
39 | android:name = "cn.jpush.android.service.PushService" |
40 | android:enabled = "true" |
41 | android:exported = "false" > |
43 | < action android:name = "cn.jpush.android.intent.REGISTER" /> |
44 | < action android:name = "cn.jpush.android.intent.REPORT" /> |
45 | < action android:name = "cn.jpush.android.intent.PushService" /> |
46 | < action android:name = "cn.jpush.android.intent.PUSH_TIME" /> |
52 | android:name = "cn.jpush.android.service.PushReceiver" |
53 | android:enabled = "true" > |
54 | < intent-filter android:priority = "1000" > |
55 | < action android:name = "cn.jpush.android.intent.NOTIFICATION_RECEIVED_PROXY" /> |
56 | < category android:name = "Your Package" /> |
59 | < action android:name = "android.intent.action.USER_PRESENT" /> |
60 | < action android:name = "android.net.conn.CONNECTIVITY_CHANGE" /> |
63 | < action android:name = "android.intent.action.PACKAGE_ADDED" /> |
64 | < action android:name = "android.intent.action.PACKAGE_REMOVED" /> |
65 | < data android:scheme = "package" /> |
70 | android:name = "cn.jpush.android.ui.PushActivity" |
71 | android:theme = "@android:style/Theme.Translucent.NoTitleBar" |
72 | android:configChanges = "orientation|keyboardHidden" > |
74 | < action android:name = "cn.jpush.android.ui.PushActivity" /> |
75 | < category android:name = "android.intent.category.DEFAULT" /> |
76 | < category android:name = "Your Package" /> |
81 | android:name = "cn.jpush.android.service.DownloadService" |
82 | android:enabled = "true" |
83 | android:exported = "false" > |
86 | < receiver android:name = "cn.jpush.android.service.AlarmReceiver" /> |
94 | < meta-data android:name = "JPUSH_CHANNEL" android:value = "developer-default" /> |
96 | < meta-data android:name = "JPUSH_APPKEY" android:value = "Your AppKey" /> |
然後在Android工程中添加BroadcastReciever類,用來接收系統的廣播,在系統期待完成後發送一個啓動完成的廣播,在收到這個廣播消息後啓動PUSH服務,然後對用戶名進行MD5加密後設在alias,用於對該用戶的唯一標識:
01 | Log.d(TAG, "Starting Push Service" ); |
02 | JPushInterface.init(context); |
03 | Log.d(TAG, "Push Service Started" ); |
05 | String email = sharedPreferences.getString( "EMAIL" , null ); |
06 | Log.d(TAG, "Set your device Alias to :" +email); |
10 | JPushInterface.setAliasAndTags(context, Utils.MD5(email), null ); |
這樣就建立了與PUSH服務器的長連接,由於使用MD5算法進行字符串加密,保證了別名的唯一性。
當用於需要查看對方的位置信息的時候,打開本軟件後會通過ASYNC任務向軟件服務器發送一個Web Service請求:
01 | public class ChangeTaStateTask extends AsyncTask<String, Void, Boolean> { |
03 | protected Boolean doInBackground(String... params) { |
05 | SoapObject changestate_soap = new SoapObject(NAMESPACE, CHANGE_TA_STATE_AND_RETURN); |
14 | changestate_soap.addProperty( "arg0" ,params[ 0 ]); |
15 | changestate_soap.addProperty( "arg1" ,params[ 1 ]); |
17 | Log.d(TAG, "Send a request to your friend to open position service" ); |
20 | SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); |
21 | envelope.bodyOut = changestate_soap; |
22 | envelope.dotNet = false ; |
24 | HttpTransportSE ht = new HttpTransportSE(URL); |
27 | ht.call(NAMESPACE + CHANGE_TA_STATE_AND_RETURN, envelope); |
28 | } catch (IOException e) { |
31 | } catch (XmlPullParserException e) { |
服務器端添加對JPUSH的支持:
點擊下載:jpush-api-v2.zip。
在你的項目裏引入 jpush-java-libraryV2.jar 以及lib文件夾裏的第三方依賴包(gson.jar)。
服務器接收到該請求會向對方通過唯一標識的別名發送一個PUSH消息:
01 | if (email == null || on_off == null ) |
04 | jpush = getJpushClient(); |
06 | MessageResult msgResult = jpush.sendCustomMessageWithAlias(getRandomSendNo(),Utils.MD5(ta_email), email, on_off); |
08 | if ( null != msgResult) { |
09 | logger.info( "JPUSH return data: " + msgResult.toString()); |
10 | if (msgResult.getErrcode() == ErrorCodeEnum.NOERROR.value()) { |
11 | logger.info(String.format( "send message successfully錛?sendNo= %s,messageId= %s" ,msgResult.getSendno(),msgResult.getMsg_id())); |
14 | logger.error( "send message failed錛?error code=" + msgResult.getErrcode() + ", error message=" + msgResult.getErrmsg()); |
18 | logger.error( "鏃犳硶鑾峯彇鏁版嵁" ); |
當另一方收到該自定義消息會進行消息的解析,然後通過消息的內容進行判斷是開啓還是關閉位置上傳服。
當你退出或將軟件運行轉到後臺後,也同時會向服務器發送PUSH服務,請求關閉對方的位置上傳服務。
由於有PUSH服務的支持,所以可以實現位置的按需上傳。只要對方開機,默認開啓數據連接,就能時刻查看對方的位置。
=-=-=-=-=
Powered by Blogilo