Android–基于PUSH服务的位置共享软件app的实现

来源:互联网 发布:淘宝助手菜鸟打印组件 编辑:程序博客网 时间:2024/06/06 16:27

原文地址:http://blog.ygeekcome.com/archives/186


开发软件的目的很单纯:如果想知道Ta的位置,你不用主动询问,打开手机软件,即可查看到对方的实时位置。

软件的早期版本没有使用PUSH服务,而是通过动态算法轮询的方式进行位置数据提交,比较耗费电量和流量。
软件最新版本下载地址:
http://dl.geekcome.com/TouchYou.apk

在新版的软件中加入了PUSH服务,在手机开机完成后会自动启动一个后台的PUSH服务,建立与PUSH服务器的长连接,以便收取到推送的消息。
PUSH服务使用的是JPUSH提供的免费服务。
在Android工程中添加JPUSH支持:

1、导入 SDK 开发包到你自己的应用程序项目

  • 解压缩 jpush-sdk_v1.x.y.zip 集成压缩包
  • 复制 libs/jpush-sdk-release1.x.y.jar 到工程 libs/ 目录下
  • 复制 libs/armeabi/libjpush.so 到工程 libs/armeabi 目录下

    如果您的项目有 libs/armeabi-v7a 这个目录,请把 libjpush.so 也复制一份到这个目录。

2、配置 AndroidManifest.xml

根据 SDK 压缩包里的 AndroidManifest.xml 样例文件,来配置应用程序项目的 AndroidManifest.xml 。

主要步骤为:

  1. 复制备注为 “Required” 的部分
  2. 将备注为替换包名的部分,替换为当前应用程序的包名

将AppKey替换为在Portal上注册该应用的的Key,例如(9fed5bcb7b9b87413678c407)

01<?xml version="1.0"encoding="utf-8"?>
02<manifest xmlns:android="http://schemas.android.com/apk/res/android"
03    package="Your Package"
04    android:versionCode="100"
05    android:versionName="1.0.0"
06    >
07 
08    <!-- Required -->
09    <permission android:name="Your Package.permission.JPUSH_MESSAGE" android:protectionLevel="signature" />
10 
11    <!-- Required -->
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" />
22 
23    <!-- Optional. Required for location feature -->
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" />
31 
32    <application
33        android:icon="@drawable/ic_launcher"
34        android:label="@string/app_name"
35        android:name="Your Application">
36 
37        <!-- Required -->
38        <service
39            android:name="cn.jpush.android.service.PushService"
40            android:enabled="true"
41            android:exported="false" >
42            <intent-filter>
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" />
47            </intent-filter>
48        </service>
49 
50        <!-- Required -->
51        <receiver
52            android:name="cn.jpush.android.service.PushReceiver"
53            android:enabled="true" >
54          <intent-filter android:priority="1000"<!--since 1.3.5 -->
55                <action android:name="cn.jpush.android.intent.NOTIFICATION_RECEIVED_PROXY" /> <!--since 1.3.5 -->
56                <category android:name="Your Package" /> <!--since 1.3.5 -->
57            </intent-filter<!--since 1.3.5 -->
58            <intent-filter>
59                <action android:name="android.intent.action.USER_PRESENT" />
60                <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
61            </intent-filter>
62            <intent-filter>
63                <action android:name="android.intent.action.PACKAGE_ADDED" />
64                <action android:name="android.intent.action.PACKAGE_REMOVED" />
65                <data android:scheme="package" />
66            </intent-filter>
67        </receiver>
68     <!-- Required SDK核心功能-->
69        <activity
70            android:name="cn.jpush.android.ui.PushActivity"
71            android:theme="@android:style/Theme.Translucent.NoTitleBar"
72            android:configChanges="orientation|keyboardHidden" >
73            <intent-filter>
74                <action android:name="cn.jpush.android.ui.PushActivity" />
75                <category android:name="android.intent.category.DEFAULT" />
76                <category android:name="Your Package" />
77            </intent-filter>
78        </activity>
79        <!-- Required SDK核心功能-->
80        <service
81            android:name="cn.jpush.android.service.DownloadService"
82            android:enabled="true"
83            android:exported="false" >
84        </service>
85        <!-- Required SDK核心功能-->
86        <receiver android:name="cn.jpush.android.service.AlarmReceiver" />
87 
88        <!-- Required. For publish channel feature -->
89        <!-- JPUSH_CHANNEL 是为了方便开发者统计APK分发渠道。-->
90        <!-- 例如: -->
91        <!-- 发到 Google Play 的APK可以设置为 google-play; -->
92        <!-- 发到其他市场的 APK 可以设置为 xxx-market。 -->
93        <!-- 目前这个渠道统计功能的报表还未开放。-->
94        <meta-data android:name="JPUSH_CHANNEL" android:value="developer-default"/>
95        <!-- Required. AppKey copied from Portal -->
96        <meta-data android:name="JPUSH_APPKEY" android:value="Your AppKey"/>
97    </application>
98</manifest>

然后在Android工程中添加BroadcastReciever类,用来接收系统的广播,在系统期待完成后发送一个启动完成的广播,在收到这个广播消息后启动PUSH服务,然后对用户名进行MD5加密后设在alias,用于对该用户的唯一标识:

01Log.d(TAG,"Starting Push Service");
02JPushInterface.init(context);
03Log.d(TAG,"Push Service Started");
04 
05String email = sharedPreferences.getString("EMAIL"null);
06Log.d(TAG,"Set your device Alias to :"+email);
07 
08//如果没有记录到用户的用户名则不设置
09if(email != null)
10JPushInterface.setAliasAndTags(context, Utils.MD5(email), null);
这样就建立了与PUSH服务器的长连接,由于使用MD5算法进行字符串加密,保证了别名的唯一性。

当用于需要查看对方的位置信息的时候,打开本软件后会通过ASYNC任务向软件服务器发送一个Web Service请求:

01public class ChangeTaStateTask extends AsyncTask<String, Void, Boolean> {
02    @Override
03    protected Boolean doInBackground(String... params) {
04 
05        SoapObject changestate_soap =  new SoapObject(NAMESPACE, CHANGE_TA_STATE_AND_RETURN);
06 
07        /*
08         * params[0] is the email
09         *
10         * params[1] is the state:
11         * 0:not be focused
12         * 1:be focused
13        */
14        changestate_soap.addProperty("arg0",params[0]);
15        changestate_soap.addProperty("arg1",params[1]);
16 
17        Log.d(TAG, "Send a request to your friend to open position service");
18 
19        //鐢熸垚璋冪敤Web service鏂规硶鐨凷OAP璇锋眰淇℃伅
20        SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
21        envelope.bodyOut = changestate_soap;
22        envelope.dotNet = false;
23 
24        HttpTransportSE ht = new HttpTransportSE(URL);
25 
26        try {
27            ht.call(NAMESPACE + CHANGE_TA_STATE_AND_RETURN, envelope);
28        catch (IOException e) {
29            // TODO Auto-generated catch block
30            e.printStackTrace();
31        catch (XmlPullParserException e) {
32            // TODO Auto-generated catch block
33            e.printStackTrace();
34        }
35 
36        return true;
37    }
38}

 

 

服务器端添加对JPUSH的支持:

点击下载:jpush-api-v2.zip。

在你的项目里引入 jpush-java-libraryV2.jar 以及lib文件夹里的第三方依赖包(gson.jar)。

服务器接收到该请求会向对方通过唯一标识的别名发送一个PUSH消息:

01if(email == null || on_off == null)
02    return "ER";
03 
04jpush = getJpushClient();
05 
06MessageResult msgResult = jpush.sendCustomMessageWithAlias(getRandomSendNo(),Utils.MD5(ta_email), email, on_off);
07 
08if (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()));
12        return "OK";
13    else {
14        logger.error("send message failed锛?error code=" + msgResult.getErrcode() + ", error message=" + msgResult.getErrmsg());
15        return "ER";
16    }
17else {
18    logger.error("鏃犳硶鑾峰彇鏁版嵁");
19    return "ER";
20}

 

当另一方收到该自定义消息会进行消息的解析,然后通过消息的内容进行判断是开启还是关闭位置上传服。
当你退出或将软件运行转到后台后,也同时会向服务器发送PUSH服务,请求关闭对方的位置上传服务。
由于有PUSH服务的支持,所以可以实现位置的按需上传。只要对方开机,默认开启数据连接,就能时刻查看对方的位置。

=-=-=-=-=
Powered by Blogilo


2 0
原创粉丝点击