├── .gitignore
├── .gitmodules
├── .travis.yml
├── README.md
├── android-demo
├── .gitignore
├── 123456.keystore
├── build.gradle
├── google-services.json
├── libs
│ ├── HMSSdkBase_2.5.3.305.jar
│ ├── HMSSdkPush_2.5.3.305.jar
│ ├── MiPush_SDK_Client_3_2_2.jar
│ ├── alicloud-android-sdk-httpdns-1.0.7.jar
│ ├── armeabi
│ │ ├── libcocklogic-1.1.3.so
│ │ └── libtnet-3.1.11.so
│ ├── com.umeng.message_3.1.1a.jar
│ ├── utdid4all-1.1.5.3_proguard.jar
│ └── x86
│ │ ├── libcocklogic-1.1.3.so
│ │ └── libtnet-3.1.11.so
├── proguard-rules.txt
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── yy
│ │ └── misaka
│ │ └── demo
│ │ ├── TestSocketIO.java
│ │ └── util
│ │ ├── HttpUtil.java
│ │ ├── MyBroadcastReceiver.java
│ │ └── TestBase.java
│ └── main
│ ├── AndroidManifest.xml
│ ├── ic_launcher-web.png
│ ├── java
│ └── com
│ │ └── yy
│ │ └── misaka
│ │ └── demo
│ │ ├── ChatActivity.java
│ │ ├── ConnectActivity.java
│ │ ├── DrawActivity.java
│ │ ├── DrawView.java
│ │ ├── NickNameActivity.java
│ │ ├── adapter
│ │ └── ChatMessagesAdapter.java
│ │ ├── appmodel
│ │ ├── DemoApp.java
│ │ ├── HttpApi.java
│ │ └── YYNotificationReceiver.java
│ │ ├── entity
│ │ └── Message.java
│ │ ├── test
│ │ └── TestActivity.java
│ │ └── util
│ │ ├── HttpUtils.java
│ │ └── JsonHelper.java
│ └── res
│ ├── drawable-xxhdpi
│ └── misaka.jpg
│ ├── layout
│ ├── activity_chat.xml
│ ├── activity_connect.xml
│ ├── activity_draw.xml
│ ├── activity_im_user_list.xml
│ ├── activity_login.xml
│ ├── activity_main.xml
│ ├── activity_nick.xml
│ ├── activity_profile.xml
│ ├── activity_register.xml
│ ├── activity_splash.xml
│ ├── activity_test.xml
│ ├── item_message.xml
│ └── item_user.xml
│ ├── values-w820dp
│ └── dimens.xml
│ └── values
│ ├── dimens.xml
│ ├── hwpush_colors.xml
│ ├── hwpush_strings.xml
│ ├── hwpush_styles.xml
│ ├── strings.xml
│ └── styles.xml
├── android-push-sdk
├── build.gradle
├── libs
│ ├── HMSSdkBase_2.5.3.305.jar
│ ├── HMSSdkPush_2.5.3.305.jar
│ ├── MiPush_SDK_Client_3_2_2.jar
│ ├── android.jar
│ ├── com.umeng.message_3.1.1a.jar
│ ├── firebase-common-11.8.0.jar
│ ├── firebase-core-11.8.0.jar
│ ├── firebase-iid-11.8.0.jar
│ ├── firebase-messaging-11.8.0.jar
│ ├── play-services-base-11.8.0.jar
│ ├── play-services-basement-11.8.0.jar
│ ├── play-services-gcm-11.8.0.jar
│ └── support-v4-19.1.0.jar
└── src
│ └── main
│ ├── AndroidManifest.xml
│ └── java
│ └── com
│ └── yy
│ └── httpproxy
│ ├── AndroidLoggingHandler.java
│ ├── Config.java
│ ├── ProxyClient.java
│ ├── requester
│ └── RequestInfo.java
│ ├── service
│ ├── BootBroadcastReceiver.java
│ ├── ConnectionService.java
│ ├── DefaultDnsHandler.java
│ ├── DefaultNotificationHandler.java
│ ├── DelegateToClientNotificationHandler.java
│ ├── DnsHandler.java
│ ├── DummyNotificationHandler.java
│ ├── DummyService.java
│ ├── ForegroundService.java
│ ├── NotificationHandler.java
│ ├── NotificationReceiver.java
│ └── PushedNotification.java
│ ├── socketio
│ ├── RemoteClient.java
│ └── SocketIOProxyClient.java
│ ├── stats
│ ├── Connectivity.java
│ ├── Performance.java
│ └── Stats.java
│ ├── subscribe
│ ├── CachedSharedPreference.java
│ ├── ConnectCallback.java
│ ├── PushCallback.java
│ ├── PushSubscriber.java
│ └── RandomPushIdGenerator.java
│ ├── thirdparty
│ ├── FirebaseProvider.java
│ ├── HuaweiCallback.java
│ ├── HuaweiProvider.java
│ ├── HuaweiReceiver.java
│ ├── MyFirebaseInstanceIdService.java
│ ├── MyFirebaseMessagingService.java
│ ├── NotificationProvider.java
│ ├── ProviderFactory.java
│ ├── UmengIntentService.java
│ ├── UmengProvider.java
│ ├── XiaomiProvider.java
│ └── XiaomiReceiver.java
│ └── util
│ ├── CrashHandler.java
│ ├── HttpUtil.java
│ ├── JSONUtil.java
│ ├── Log.java
│ ├── LogcatLogger.java
│ ├── Logger.java
│ ├── ServiceCheckUtil.java
│ ├── SystemProperty.java
│ └── Version.java
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | local.properties
3 | *.iml
4 | node_modules
5 | *.log
6 | dump.rdb
7 | log.txt
8 | pid
9 | pids
10 | pid_debug
11 | .gradle
12 | build
13 | android-push-sdk/secring.gpg
14 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "android-push-sdk/sub/engine.io-client-java"]
2 | path = android-push-sdk/sub/engine.io-client-java
3 | url = https://github.com/xuduo/engine.io-client-java
4 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: android
2 |
3 | android:
4 | components:
5 | - build-tools-23.0.1
6 | - android-23
7 | - extra-android-m2repository
8 | - tools
9 | - platform-tools
10 |
11 | script:
12 | - ./gradlew test assembleDebug
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## socket.io-push-android [](https://travis-ci.org/xuduo/socket.io-push-android)
2 | demo实现了一个聊天室功能, 编译clone后 需要pull submodule
3 | ```
4 | git clone https://github.com/xuduo/socket.io-push-android
5 | git submodule update --recursive --remote
6 | ```
7 | ##### 小米,华为,友盟均为可选接入。开启条件为 对应厂商系统&classpath里有对应sdk&androidManifest里有配置
8 |
9 | 1. 小米推送(所有MUI) MiPush_SDK_Client_XXX.jar
10 | 2. 华为推送(EMUI5.0以上) HMSSdkBase_XXX.jar HMSSdkPush_XXX.jar
11 | 3. 友盟推送(非小米华为) com.umeng.message_XXX.jar alicloud-android-sdk-httpdns-XXX.jar utdid4all-XXX_proguard.jar libcocklogic-XXX.so libtnet-XXX.so
12 |
13 |
14 | ##### 添加maven/gradle依赖
15 |
16 | [](https://maven-badges.herokuapp.com/maven-central/com.yy/android-push-sdk)
17 |
18 |
19 | maven
20 | ```xml
21 |
22 | com.yy
23 | android-push-sdk
24 | ${version}
25 |
26 | ```
27 |
28 |
29 | gradle
30 | ```groovy
31 | compile 'com.yy:android-push-sdk:${versoion}'
32 | ```
33 |
34 | #### AndroidManifest.xml添加receiver,service,permission
35 | 参见Demo的[AndroidManifest.xml](android-demo/src/main/AndroidManifest.xml)
36 |
37 | #### Proguard
38 |
39 | 混淆配置
40 | ```
41 | -dontwarn com.yy.httpproxy.thirdparty.**
42 | -dontwarn okio.**
43 |
44 | ##如接入华为push
45 | -keep class com.huawei.android.pushagent.** {*;}
46 | -keep class com.huawei.android.pushselfshow.** {*;}
47 | -keep class com.huawei.android.microkernel.** {*;}
48 | -keep class com.baidu.mapapi.** {*;}
49 | -dontwarn com.huawei.**
50 | ##如接入华为push
51 |
52 |
53 | ```
54 |
55 | ##### 初始化ProxyClient
56 | 每次UI进程启动需要初始化,初始化后会自动启动push进程.
57 |
58 | ```java
59 | Proxy proxyClient = new ProxyClient(new Config(this)
60 | .setHost("http://spush.yy.com") //连接的服务器地址
61 | .setConnectCallback(this) //socket.io通道,连上,断开回调
62 | .setPushCallback(this) //push回调,socket.io长连接通道
63 | .setLogger(MyLogger.class)); //日志回调,可选,这个类会实例化在push进程
64 | ```
65 | 注意不要通过其他进程启动,可以用以下代码判断是否ui进程
66 | ```java
67 | private boolean isUiProcess() {
68 | ActivityManager am = ((ActivityManager) getSystemService(Context.ACTIVITY_SERVICE));
69 | List processInfos = am.getRunningAppProcesses();
70 | String mainProcessName = getPackageName();
71 | int myPid = Process.myPid();
72 | for (RunningAppProcessInfo info : processInfos) {
73 | if (info.pid == myPid && mainProcessName.equals(info.processName)) {
74 | return true;
75 | }
76 | }
77 | return false;
78 | }
79 | ```
80 |
81 |
82 | ##### 获取pushId
83 |
84 | 由客户端自动生成, proxyClient实例化后即可获得
85 |
86 | 用于服务器对单个设备发push/notification
87 | ```java
88 | String pushId = proxyClient.getPushId();
89 | ```
90 |
91 |
92 |
93 | #### subscribe/unsbuscribe topic
94 |
95 | 调用不需考虑当时是否连线, 重连也不需要重新sub/unsub,sdk里已经处理
96 | ```java
97 | proxyClient.subscribeBroadcast("aTopic"); //对于某个topic的push,需要客户端主动订阅,才能收到.如demo中,需订阅"chatRoom" topic,才能收到聊天消息
98 | proxyClient.subscribeAndReceiveTtlPackets("aTopic"); //同上,这个方法会接收服务器的重传
99 | proxyClient.unsubscribeBroadcast("aTopic");
100 | ```
101 |
102 |
103 |
104 | #### 接收push
105 | ```java
106 | public interface PushCallback {
107 |
108 | /**
109 | *
110 | * @param data 服务器push下来的字符串
111 | */
112 | void onPush(String data);
113 | }
114 | ```
115 |
116 |
117 | #### 接收notification(使用DefaultNotificationHandler/DelegateToClientNotificationHandler)
118 | sdk默认会弹出系统通知
119 | arrive和click后会调用receiver的方法
120 | ```java
121 | public class YYNotificationReceiver extends NotificationReceiver {
122 |
123 | @Override
124 | public void onNotificationClicked(Context context, PushedNotification notification) {
125 | Log.d("YYNotificationReceiver", "onNotificationClicked " + notification.id + " values " + notification.values);
126 | Toast.makeText(context, "YYNotificationReceiver clicked payload: " + notification.values.get("payload"), Toast.LENGTH_SHORT).show();
127 | Intent intent = new Intent(context, DrawActivity.class);
128 | intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
129 | context.startActivity(intent);
130 | }
131 |
132 | /**
133 | * 如果使用DelegateToClientNotificationHandler ,UI进程存活的时候,会调用此方法,不弹出通知.
134 | * UI进程被杀,push进程存活的时候,使用默认的样式弹出
135 | * 使用小米华为推送时,不会调用
136 | */
137 | @Override
138 | public void onNotificationArrived(Context context, PushedNotification notification) {
139 | Log.d("YYNotificationReceiver", "onNotificationArrived " + notification.id + " values " + notification.values);
140 | }
141 |
142 | }
143 | ```
144 | 启动时的配置,配置使用
145 | ```java
146 | config.setNotificationHandler(MyHandlerClass.class); //不能混淆这个类
147 | ```
148 |
149 |
150 | #### 自定义弹出通知(使用自定义NotificationHandler)
151 | 可以用代码根据业务服务器下发的notification中的自定义payload字段,展示不同的效果
152 |
153 | 注意!NotificationHandler的实例,是在push进程中的!
154 |
155 | 实现接口
156 | ```java
157 | public interface NotificationHandler {
158 | /**
159 | *
160 | * @param context context
161 | * @param binded UI进程 是否存活
162 | * @param notification 业务服务器下发的notification
163 | */
164 | void handlerNotification(Context context, boolean binded, PushedNotification notification);
165 |
166 | }
167 | ```
168 | 启动时的配置,设置NotificationHandler
169 | ```java
170 | config.setNotificationHandler("yourFullyQualifiedHandlerClassName"); //不能混淆这个类
171 | ```
172 |
173 | #### 绑定UID
174 | 绑定UID是业务服务器调用push-server接口进行绑定的(pushId - uid)的关系
175 |
176 | 由于安全性的问题,客户端无法直接绑定
177 |
178 | push-server和业务服务器的绑定关系可能会不一致
179 |
180 | 每次连接到push-sever后, 客户端要根据回调, 判断回调的uid与当前用户uid是否一致, 进行绑定/解绑
181 | ```java
182 | public interface ConnectCallback {
183 |
184 | /**
185 | *
186 | * @param uid 连接push-server后,在服务器绑定的uid,如未绑定,uid = ""
187 | * @param uid 连接push-server后,在服务器绑定的tags
188 | */
189 | void onConnect(String uid, Set tags);
190 |
191 | void onDisconnect();
192 |
193 | }
194 | ```
195 | 解绑Uid,客户端直接调用接口解绑
196 | ```java
197 | proxyClient.unbindUid();
198 | ```
199 |
200 | ##### 添加删除tag
201 |
202 | ```java
203 | proxyClient.addTag("tag1");
204 | proxyClient.removeTag("tag2");
205 | ```
206 |
207 | tag回调同上
208 |
209 |
210 | #### 集成小米push
211 |
212 |
213 | [华为push官方接入文档](http://dev.xiaomi.com/doc/?page_id=1670)
214 |
215 | 本系统透明集成了小米push,开启方法.
216 |
217 |
218 | 1. 添加小米push jar依赖
219 | 2. AndroidManifest.xml配置了小米push相关配置,参见demo
220 | 3. 当前手机运行MiUi系统
221 |
222 | 注意项
223 |
224 | 1. SDK会自动上报小米的regId,并不需要业务代码改动
225 | 2. 对于开启的手机,无法使用自定义NotificationHandler控制notification弹出
226 | 3. 可以通过push-server配置,应用在前台的时候,不弹出通知(小米push功能)
227 |
228 |
229 |
230 | #### 集成华为push
231 |
232 | [华为push官方接入文档](http://developer.huawei.com/push)
233 |
234 | 本系统透明集成了华为push,开启方法
235 |
236 | 1. 添加华为push jar依赖,拷贝一堆资源文件(华为push自带)
237 | 2. AndroidManifest.xml配置了华为push相关配置,参见demo
238 | 3. 当前手机运行华为系统
239 |
240 | 注意项
241 |
242 | 1. SDK会自动上报华为的token,并不需要业务代码改动
243 | 2. 对于开启的手机,无法使用自定义NotificationHandler控制notification弹出
244 |
245 |
246 | #### UI进程单独使用push功能
247 |
248 | ```java
249 | String pushId = new RandomPushIdGenerator().generatePushId(pushId); //生成随机pushId
250 | SocketIOProxyClient client = new SocketIOProxyClient(this.getApplicationContext(), host, null);
251 | client.setPushId(pushId); //设置pushId
252 | client.setPushCallback(this); // push回调
253 | client.setNotificationCallback(this); //notification回调
254 | client.setConnectCallback(this); //连接回调
255 | ```
256 |
--------------------------------------------------------------------------------
/android-demo/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/android-demo/123456.keystore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuduo/socket.io-push-android/c5738189a79bfae036b8199d0287980c734d9d85/android-demo/123456.keystore
--------------------------------------------------------------------------------
/android-demo/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 |
4 | android {
5 | compileSdkVersion 23
6 | buildToolsVersion "23.0.1"
7 |
8 | signingConfigs {
9 | release {
10 | storeFile file("123456.keystore")
11 | storePassword "123456"
12 | keyAlias "123456"
13 | keyPassword "123456"
14 | }
15 |
16 | debug {
17 | storeFile file("123456.keystore")
18 | storePassword "123456"
19 | keyAlias "123456"
20 | keyPassword "123456"
21 | }
22 |
23 | }
24 |
25 | defaultConfig {
26 | minSdkVersion 15
27 | targetSdkVersion 22
28 | versionCode 1
29 | versionName "1.0"
30 | applicationId "com.yy.misaka.demo"
31 | }
32 | buildTypes {
33 | release {
34 | minifyEnabled true
35 | signingConfig signingConfigs.release
36 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
37 | }
38 | }
39 | lintOptions {
40 | abortOnError false
41 | }
42 | dexOptions {
43 | incremental true
44 | }
45 | compileOptions {
46 | sourceCompatibility JavaVersion.VERSION_1_7
47 | targetCompatibility JavaVersion.VERSION_1_7
48 | }
49 |
50 | sourceSets {
51 | main {
52 | jniLibs.srcDirs = ['libs']
53 | }
54 | }
55 | }
56 |
57 | dependencies {
58 | compile fileTree(include: ['*.jar'], dir: 'libs')
59 | compile project(':android-push-sdk')
60 | compile 'com.android.support:appcompat-v7:19.+'
61 | compile 'com.google.code.gson:gson:2.4'
62 | compile 'com.android.support:recyclerview-v7:21.+'
63 | compile 'com.android.support:multidex:1.0.0'
64 | compile 'com.google.firebase:firebase-core:11.8.0' //接入GCM才需要
65 | compile 'com.google.firebase:firebase-messaging:11.8.0' //接入GCM才需要
66 | compile 'com.google.android.gms:play-services-base:11.8.0' //接入GCM才需要
67 | }
68 |
69 | apply plugin: 'com.google.gms.google-services' //接入GCM才需要, 并需要从后台下载google-services.json
--------------------------------------------------------------------------------
/android-demo/google-services.json:
--------------------------------------------------------------------------------
1 | {
2 | "project_info": {
3 | "project_number": "478153921873",
4 | "firebase_url": "https://socketiodemo.firebaseio.com",
5 | "project_id": "socketiodemo",
6 | "storage_bucket": "socketiodemo.appspot.com"
7 | },
8 | "client": [
9 | {
10 | "client_info": {
11 | "mobilesdk_app_id": "1:478153921873:android:163250854d1c81d9",
12 | "android_client_info": {
13 | "package_name": "com.yy.misaka.demo"
14 | }
15 | },
16 | "oauth_client": [
17 | {
18 | "client_id": "478153921873-k4vc1uogcfsvmv2skhjat9mhf7r4ir0n.apps.googleusercontent.com",
19 | "client_type": 3
20 | }
21 | ],
22 | "api_key": [
23 | {
24 | "current_key": "AIzaSyAsgGvo1gDNF8aczl3GoxpYVhl1luoxn5Q"
25 | }
26 | ],
27 | "services": {
28 | "analytics_service": {
29 | "status": 1
30 | },
31 | "appinvite_service": {
32 | "status": 1,
33 | "other_platform_oauth_client": []
34 | },
35 | "ads_service": {
36 | "status": 2
37 | }
38 | }
39 | }
40 | ],
41 | "configuration_version": "1"
42 | }
--------------------------------------------------------------------------------
/android-demo/libs/HMSSdkBase_2.5.3.305.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuduo/socket.io-push-android/c5738189a79bfae036b8199d0287980c734d9d85/android-demo/libs/HMSSdkBase_2.5.3.305.jar
--------------------------------------------------------------------------------
/android-demo/libs/HMSSdkPush_2.5.3.305.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuduo/socket.io-push-android/c5738189a79bfae036b8199d0287980c734d9d85/android-demo/libs/HMSSdkPush_2.5.3.305.jar
--------------------------------------------------------------------------------
/android-demo/libs/MiPush_SDK_Client_3_2_2.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuduo/socket.io-push-android/c5738189a79bfae036b8199d0287980c734d9d85/android-demo/libs/MiPush_SDK_Client_3_2_2.jar
--------------------------------------------------------------------------------
/android-demo/libs/alicloud-android-sdk-httpdns-1.0.7.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuduo/socket.io-push-android/c5738189a79bfae036b8199d0287980c734d9d85/android-demo/libs/alicloud-android-sdk-httpdns-1.0.7.jar
--------------------------------------------------------------------------------
/android-demo/libs/armeabi/libcocklogic-1.1.3.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuduo/socket.io-push-android/c5738189a79bfae036b8199d0287980c734d9d85/android-demo/libs/armeabi/libcocklogic-1.1.3.so
--------------------------------------------------------------------------------
/android-demo/libs/armeabi/libtnet-3.1.11.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuduo/socket.io-push-android/c5738189a79bfae036b8199d0287980c734d9d85/android-demo/libs/armeabi/libtnet-3.1.11.so
--------------------------------------------------------------------------------
/android-demo/libs/com.umeng.message_3.1.1a.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuduo/socket.io-push-android/c5738189a79bfae036b8199d0287980c734d9d85/android-demo/libs/com.umeng.message_3.1.1a.jar
--------------------------------------------------------------------------------
/android-demo/libs/utdid4all-1.1.5.3_proguard.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuduo/socket.io-push-android/c5738189a79bfae036b8199d0287980c734d9d85/android-demo/libs/utdid4all-1.1.5.3_proguard.jar
--------------------------------------------------------------------------------
/android-demo/libs/x86/libcocklogic-1.1.3.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuduo/socket.io-push-android/c5738189a79bfae036b8199d0287980c734d9d85/android-demo/libs/x86/libcocklogic-1.1.3.so
--------------------------------------------------------------------------------
/android-demo/libs/x86/libtnet-3.1.11.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuduo/socket.io-push-android/c5738189a79bfae036b8199d0287980c734d9d85/android-demo/libs/x86/libtnet-3.1.11.so
--------------------------------------------------------------------------------
/android-demo/proguard-rules.txt:
--------------------------------------------------------------------------------
1 | -keep class com.huawei.android.pushagent.** {*;}
2 | -keep class com.huawei.android.pushselfshow.** {*;}
3 | -keep class com.huawei.android.microkernel.** {*;}
4 | -keep class com.baidu.mapapi.** {*;}
5 |
6 | -dontwarn com.yy.httpproxy.thirdparty.**
7 | -dontwarn okio.**
8 |
9 | -dontwarn com.taobao.**
10 | -dontwarn anet.channel.**
11 | -dontwarn anetwork.channel.**
12 | -dontwarn org.android.**
13 | -dontwarn com.xiaomi.**
14 | -dontwarn com.huawei.**
15 | -dontwarn org.apache.thrift.**
16 |
17 | -keepattributes *Annotation*
18 |
19 | -keep class com.taobao.** {*;}
20 | -keep class org.android.** {*;}
21 | -keep class anet.channel.** {*;}
22 | -keep class com.umeng.** {*;}
23 | -keep class com.xiaomi.** {*;}
24 | -keep class com.huawei.** {*;}
25 | -keep class org.apache.thrift.** {*;}
26 | -keep class com.alibaba.sdk.android.**{*;}
27 | -keep class com.ut.**{*;}
28 | -keep class com.ta.**{*;}
29 |
30 | -keep public class com.umeng.message.example.example.R$*{
31 | public static final int *;
32 | }
33 |
34 | #避免log打印输出
35 | -assumenosideeffects class android.util.Log {
36 | public static *** v(...);
37 | public static *** d(...);
38 | public static *** i(...);
39 | public static *** w(...);
40 | }
41 |
42 | -ignorewarning
43 | -keepattributes Exceptions
44 | -keepattributes InnerClasses
45 | -keepattributes Signature
46 | -keepattributes SourceFile,LineNumberTable
47 | -keep class com.hianalytics.android.**{*;}
48 | -keep class com.huawei.updatesdk.**{*;}
49 | -keep class com.huawei.hms.**{*;}
--------------------------------------------------------------------------------
/android-demo/src/androidTest/java/com/yy/misaka/demo/TestSocketIO.java:
--------------------------------------------------------------------------------
1 | package com.yy.misaka.demo;
2 |
3 | import android.util.Log;
4 |
5 | import com.yy.misaka.demo.test.TestActivity;
6 | import com.yy.misaka.demo.util.MyBroadcastReceiver;
7 | import com.yy.misaka.demo.util.TestBase;
8 |
9 | import java.io.IOException;
10 | import java.util.concurrent.CountDownLatch;
11 | import java.util.concurrent.TimeUnit;
12 |
13 | import okhttp3.Call;
14 | import okhttp3.Callback;
15 | import okhttp3.Response;
16 |
17 | /**
18 | * Created by Administrator on 2016/7/26.
19 | */
20 | public class TestSocketIO extends TestBase {
21 | public final static String TAG = "TestSocketIO";
22 | private String pushData = "Hello World";
23 | private int timeOut = 10;
24 |
25 | public void testInit() throws InterruptedException {
26 | final CountDownLatch signal = new CountDownLatch(1);
27 | assertNotNull(mActivity);
28 | mActivity.setConnectCallBack(new TestActivity.TestConnectCallBack() {
29 | @Override
30 | public void isConnect(boolean state) {
31 | assertEquals(state, true);
32 | signal.countDown();
33 | }
34 | });
35 | boolean resutl = signal.await(timeOut, TimeUnit.SECONDS);
36 | assertEquals(resutl, true);//timeout return false
37 | }
38 |
39 | public void testPushByTopic() throws InterruptedException {
40 | pushTest(true);
41 | }
42 |
43 | public void testPushByPushId() throws InterruptedException {
44 | pushTest(false);
45 | }
46 |
47 | public void testNotification() throws InterruptedException {
48 | final CountDownLatch signal = new CountDownLatch(2);
49 | httpUtil.asyncGet(httpUtil.getNotificationUrl(mActivity.host, mActivity.pushId), new Callback() {
50 | @Override
51 | public void onFailure(Call call, IOException e) {
52 |
53 | }
54 |
55 | @Override
56 | public void onResponse(Call call, Response response) throws IOException {
57 | assertEquals(response.body().string(), httpResult);
58 | signal.countDown();
59 | }
60 | });
61 | myBroadcastReceiver.setNotificationCallBack(new MyBroadcastReceiver.TestNotificationCallBack() {
62 | @Override
63 | public void onNotification(String title, String message, String payload) {
64 | assertEquals(title, "title");
65 | assertEquals(message, "message");
66 | signal.countDown();
67 | }
68 | });
69 | boolean resutl = signal.await(timeOut, TimeUnit.SECONDS);
70 | assertEquals(resutl, true);
71 | }
72 |
73 | private void pushTest(boolean isTopic) throws InterruptedException{
74 | String url = httpUtil.getPushUrlByPushId(mActivity.host, pushData, mActivity.pushId);
75 | if (isTopic) {
76 | url = httpUtil.getPushUrlByTopic(mActivity.host, pushData, mActivity.topic);
77 | }
78 | final CountDownLatch signal = new CountDownLatch(2);
79 | httpUtil.asyncGet(url, new Callback() {
80 | @Override
81 | public void onFailure(Call call, IOException e) {
82 |
83 | }
84 |
85 | @Override
86 | public void onResponse(Call call, Response response) throws IOException {
87 | assertEquals(response.body().string(), httpResult);
88 | signal.countDown();
89 | }
90 | });
91 |
92 | mActivity.setPushCallBack(new TestActivity.TestPushCallBack() {
93 | @Override
94 | public void onPush(String data) {
95 | Log.i(TAG, "onPush: " + data);
96 | assertEquals(data, pushData);
97 | signal.countDown();
98 | }
99 | });
100 | boolean resutl = signal.await(timeOut, TimeUnit.SECONDS);
101 | assertEquals(resutl, true);
102 | }
103 |
104 |
105 | }
106 |
--------------------------------------------------------------------------------
/android-demo/src/androidTest/java/com/yy/misaka/demo/util/HttpUtil.java:
--------------------------------------------------------------------------------
1 | package com.yy.misaka.demo.util;
2 |
3 | import okhttp3.Callback;
4 | import okhttp3.OkHttpClient;
5 | import okhttp3.Request;
6 |
7 | /**
8 | * Created by Administrator on 2016/7/26.
9 | */
10 | public class HttpUtil {
11 |
12 | private OkHttpClient okHttpClient = new OkHttpClient();
13 |
14 | public void asyncGet(String requestUrl, Callback callback) {
15 | final Request request = new Request.Builder().url(requestUrl).build();
16 | okHttpClient.newCall(request).enqueue(callback);
17 | }
18 |
19 | public String getPushUrlByTopic(String host, String pushData, String topic) {
20 | return host + "/api/push?json=" + pushData + "&topic=" + topic;
21 | }
22 |
23 | public String getPushUrlByPushId(String host, String pushData, String pushId) {
24 | return host + "/api/push?json=" + pushData + "&pushId=" + pushId;
25 | }
26 |
27 | public String getNotificationUrl(String host, String pushId) {
28 | return host + "/api/notification?pushId=" + pushId
29 | + "¬ification=%7B%20%22android%22%3A%7B%22title%22%3A%22title%22%2C%22message%22%3A%22message%22%7D%2C%22apn%22%3A%7B%22alert%22%3A%22message%22%20%2C%20%22badge%22%3A5%2C%20%22sound%22%3A%22default%22%2C%20%22payload%22%3A1234%7D%7D";
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/android-demo/src/androidTest/java/com/yy/misaka/demo/util/MyBroadcastReceiver.java:
--------------------------------------------------------------------------------
1 | package com.yy.misaka.demo.util;
2 |
3 | import android.content.BroadcastReceiver;
4 | import android.content.Context;
5 | import android.content.Intent;
6 | import android.util.Log;
7 |
8 | /**
9 | * Created by Administrator on 2016/7/26.
10 | */
11 | public class MyBroadcastReceiver extends BroadcastReceiver {
12 |
13 | private TestNotificationCallBack notificationCallBack;
14 |
15 | public void setNotificationCallBack(TestNotificationCallBack notificationCallBack) {
16 | this.notificationCallBack = notificationCallBack;
17 | }
18 |
19 | @Override
20 | public void onReceive(Context context, Intent intent) {
21 | String title = intent.getStringExtra("title");
22 | String message = intent.getStringExtra("message");
23 | String payload = intent.getStringExtra("payload");
24 | notificationCallBack.onNotification(title, message, payload);
25 | }
26 |
27 | public interface TestNotificationCallBack {
28 | void onNotification(String title, String message, String payload);
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/android-demo/src/androidTest/java/com/yy/misaka/demo/util/TestBase.java:
--------------------------------------------------------------------------------
1 | package com.yy.misaka.demo.util;
2 |
3 | import android.content.Intent;
4 | import android.content.IntentFilter;
5 | import android.test.InstrumentationTestCase;
6 |
7 | import com.yy.misaka.demo.test.TestActivity;
8 |
9 | /**
10 | * Created by Administrator on 2016/7/22.
11 | */
12 | public class TestBase extends InstrumentationTestCase {
13 |
14 | public TestActivity mActivity;
15 | public String httpResult = "{\"code\":\"success\"}";
16 | public HttpUtil httpUtil = new HttpUtil();
17 | public MyBroadcastReceiver myBroadcastReceiver;
18 |
19 | @Override
20 | protected void setUp() throws Exception {
21 | super.setUp();
22 | Intent intent = new Intent();
23 | intent.setClassName("com.yy.misaka.demo", TestActivity.class.getName());
24 | intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
25 | mActivity = (TestActivity) getInstrumentation().startActivitySync(intent);
26 |
27 | if (getName().equals("testNotification")) {
28 | myBroadcastReceiver = new MyBroadcastReceiver();
29 | IntentFilter filter = new IntentFilter();
30 | filter.addAction("com.yy.misaka.demo.YY_NOTIFICATION");
31 | mActivity.registerReceiver(myBroadcastReceiver, filter);
32 | }
33 | }
34 |
35 | @Override
36 | protected void tearDown() {
37 | if (getName().equals("testNotification")) {
38 | mActivity.unregisterReceiver(myBroadcastReceiver);
39 | }
40 | mActivity.finish();
41 | try {
42 | super.tearDown();
43 | } catch (Exception e) {
44 | e.printStackTrace();
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/android-demo/src/main/ic_launcher-web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuduo/socket.io-push-android/c5738189a79bfae036b8199d0287980c734d9d85/android-demo/src/main/ic_launcher-web.png
--------------------------------------------------------------------------------
/android-demo/src/main/java/com/yy/misaka/demo/ChatActivity.java:
--------------------------------------------------------------------------------
1 | package com.yy.misaka.demo;
2 |
3 | import android.app.Activity;
4 | import android.content.Context;
5 | import android.content.Intent;
6 | import android.os.Bundle;
7 | import android.support.v7.widget.LinearLayoutManager;
8 | import android.support.v7.widget.RecyclerView;
9 | import android.util.Log;
10 | import android.view.View;
11 | import android.widget.EditText;
12 |
13 | import com.google.gson.Gson;
14 | import com.yy.httpproxy.subscribe.ConnectCallback;
15 | import com.yy.httpproxy.subscribe.PushCallback;
16 | import com.yy.misaka.demo.appmodel.DemoApp;
17 | import com.yy.misaka.demo.adapter.ChatMessagesAdapter;
18 | import com.yy.misaka.demo.entity.Message;
19 |
20 | import java.util.Set;
21 |
22 | public class ChatActivity extends Activity implements ConnectCallback, PushCallback {
23 | public final static String chatTopic = "chatRoom";
24 | public final static String TAG = "ChatActivity";
25 | private RecyclerView recyclerViewMessages;
26 | private ChatMessagesAdapter chatMessagesAdapter;
27 | public static final String API_URL = "https://spush.yy.com/api/push";
28 |
29 | @Override
30 | protected void onCreate(Bundle savedInstanceState) {
31 | super.onCreate(savedInstanceState);
32 | Log.i("DemoLogger", "ChatActivity onCreate");
33 | setContentView(R.layout.activity_chat);
34 | init();
35 |
36 | DemoApp.APP_CONTEXT.proxyClient.subscribeAndReceiveTtlPackets(chatTopic);
37 | DemoApp.APP_CONTEXT.proxyClient.getConfig().setPushCallback(this).setConnectCallback(this);
38 | }
39 |
40 | private void init() {
41 | final String nickName = getIntent().getStringExtra("nickName");
42 | final EditText editTextInput = (EditText) findViewById(R.id.et_input);
43 | findViewById(R.id.btn_send).setOnClickListener(new View.OnClickListener() {
44 | @Override
45 | public void onClick(View v) {
46 | if (String.valueOf(editTextInput.getText()).length() == 0) {
47 | return;
48 | }
49 | Message message = new Message();
50 | message.setMessage(String.valueOf(editTextInput.getText()));
51 | message.setNickName(nickName);
52 | DemoApp.APP_CONTEXT.httpApi.sendMessage(message, chatTopic, null);
53 | editTextInput.setText("");
54 | }
55 | });
56 | LinearLayoutManager linearLayoutManager = new LinearLayoutManager(ChatActivity.this);
57 | linearLayoutManager.setStackFromEnd(true);
58 | chatMessagesAdapter = new ChatMessagesAdapter();
59 | recyclerViewMessages = (RecyclerView) findViewById(R.id.rv_messages);
60 | recyclerViewMessages.setLayoutManager(linearLayoutManager);
61 | recyclerViewMessages.setAdapter(chatMessagesAdapter);
62 | recyclerViewMessages.scrollToPosition(chatMessagesAdapter.getItemCount() - 1);
63 |
64 | updateConnect();
65 | }
66 |
67 | public static void launch(Context context, String nickName) {
68 | Intent intent = new Intent();
69 | intent.putExtra("nickName", nickName);
70 | intent.setClass(context, ChatActivity.class);
71 | context.startActivity(intent);
72 | }
73 |
74 | @Override
75 | public void onBackPressed() {
76 | super.onBackPressed();
77 | }
78 |
79 | private void updateConnect() {
80 | String connectState = DemoApp.APP_CONTEXT.proxyClient.isConnected() ? "(connected)" : "(disconnected)";
81 | setTitle("ChatRoom" + connectState);
82 | }
83 |
84 | @Override
85 | public void onConnect(String uid) {
86 | updateConnect();
87 | }
88 |
89 | @Override
90 | public void onDisconnect() {
91 | updateConnect();
92 | }
93 |
94 | @Override
95 | public void onPush(String data) {
96 | Log.i(TAG, "on push " + data);
97 | try {
98 | Message message = new Gson().fromJson(data, Message.class);
99 | if ("chat_message".equals(message.getType())) {
100 | chatMessagesAdapter.addData(message);
101 | recyclerViewMessages.scrollToPosition(chatMessagesAdapter.getItemCount() - 1);
102 | }
103 | } catch (Exception e) {
104 |
105 | }
106 | }
107 | }
--------------------------------------------------------------------------------
/android-demo/src/main/java/com/yy/misaka/demo/ConnectActivity.java:
--------------------------------------------------------------------------------
1 | package com.yy.misaka.demo;
2 |
3 | import android.app.Activity;
4 | import android.content.Intent;
5 | import android.os.Bundle;
6 | import android.util.Log;
7 | import android.view.View;
8 | import android.widget.EditText;
9 | import android.widget.Toast;
10 |
11 | import com.yy.httpproxy.service.ForegroundService;
12 | import com.yy.httpproxy.subscribe.ConnectCallback;
13 | import com.yy.httpproxy.subscribe.PushCallback;
14 | import com.yy.httpproxy.util.Logger;
15 |
16 | /**
17 | * Created by huangzhilong on 2016/8/31.
18 | */
19 | public class ConnectActivity extends Activity implements ConnectCallback, PushCallback{
20 | private EditText editText;
21 | @Override
22 | protected void onCreate(Bundle savedInstanceState) {
23 | super.onCreate(savedInstanceState);
24 | setContentView(R.layout.activity_connect);
25 | editText = (EditText) findViewById(R.id.et_host);
26 |
27 | findViewById(R.id.btn_connect).setOnClickListener(new View.OnClickListener() {
28 | @Override
29 | public void onClick(View v) {
30 | String host = String.valueOf(editText.getText()).trim();
31 | }
32 | });
33 |
34 | findViewById(R.id.btn_foreground_test).setOnClickListener(new View.OnClickListener() {
35 | @Override
36 | public void onClick(View v) {
37 | startForegroundService();
38 | }
39 | });
40 | }
41 |
42 | @Override
43 | public void onConnect(String uid) {
44 | Intent intent = new Intent();
45 | intent.setClass(ConnectActivity.this, NickNameActivity.class);
46 | startActivity(intent);
47 | finish();
48 | }
49 |
50 | @Override
51 | public void onDisconnect() {
52 | Toast.makeText(this, "Connect Socket failed", Toast.LENGTH_SHORT);
53 | }
54 |
55 | @Override
56 | public void onPush(String data) {
57 |
58 | }
59 |
60 | private void startForegroundService() {
61 | try {
62 | Intent intent = new Intent(this, ForegroundService.class);
63 | startService(intent);
64 | } catch (Exception e) {
65 | com.yy.httpproxy.util.Log.e("", "start ForegroundService error", e);
66 | }
67 | }
68 |
69 | public static class DemoLogger implements Logger {
70 | @Override
71 | public void log(int level, String message, Throwable e) {
72 | Log.d("DemoLogger", "demo " + message, e);
73 | }
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/android-demo/src/main/java/com/yy/misaka/demo/DrawActivity.java:
--------------------------------------------------------------------------------
1 | package com.yy.misaka.demo;
2 |
3 | import android.app.Activity;
4 | import android.graphics.Color;
5 | import android.os.Bundle;
6 | import android.os.Handler;
7 | import android.util.Log;
8 | import android.view.MotionEvent;
9 | import android.view.View;
10 | import android.widget.TextView;
11 |
12 | import com.google.gson.Gson;
13 | import com.yy.httpproxy.subscribe.ConnectCallback;
14 | import com.yy.httpproxy.subscribe.PushCallback;
15 | import com.yy.misaka.demo.appmodel.DemoApp;
16 | import com.yy.misaka.demo.appmodel.HttpApi;
17 |
18 | import java.util.Random;
19 | import java.util.Set;
20 |
21 |
22 | public class DrawActivity extends Activity implements ConnectCallback, PushCallback {
23 |
24 | private static final String TAG = "DrawActivity";
25 | private static String drawTopic = "drawTopic";
26 | private DrawView drawView;
27 | private TextView latency;
28 | private TextView apiLatency;
29 | private TextView count;
30 | private TextView connect;
31 | private long totalTime;
32 | private long totalCount;
33 | private long totalApiTime;
34 | private long totalApiCount;
35 | public int myColors[] = {Color.BLACK, Color.DKGRAY, Color.CYAN, Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW, Color.MAGENTA};
36 | public int myColor;
37 | private Handler handler = new Handler();
38 | private HttpApi.CB cb = new HttpApi.CB() {
39 | @Override
40 | public void latency(final long latency) {
41 | handler.post(new Runnable() {
42 | @Override
43 | public void run() {
44 | updateApiLatency(latency);
45 | }
46 | });
47 | }
48 | };
49 |
50 | private void updateLatency(long timestamp) {
51 | totalTime += System.currentTimeMillis() - timestamp;
52 | totalCount++;
53 | latency.setText("all:" + (totalTime / totalCount) + "ms");
54 | count.setText(totalCount + "dots");
55 | }
56 |
57 |
58 | private void updateApiLatency(long latency) {
59 | totalApiTime += latency;
60 | totalApiCount++;
61 | apiLatency.setText("api:" + (totalApiTime / totalApiCount) + "ms");
62 | }
63 |
64 | private void resetLatency() {
65 | totalCount = 0;
66 | totalTime = 0;
67 | totalApiCount = 0;
68 | totalApiTime = 0;
69 | latency.setText("0ms");
70 | apiLatency.setText("0ms");
71 | count.setText("0dots");
72 | }
73 |
74 | @Override
75 | protected void onCreate(Bundle savedInstanceState) {
76 | super.onCreate(savedInstanceState);
77 | Log.i("DemoLogger", "DrawActivity onCreate");
78 | setContentView(R.layout.activity_draw);
79 | latency = (TextView) findViewById(R.id.tv_latency);
80 | apiLatency = (TextView) findViewById(R.id.tv_api_latency);
81 | count = (TextView) findViewById(R.id.tv_count);
82 | connect = (TextView) findViewById(R.id.tv_connect);
83 | drawView = (DrawView) findViewById(R.id.draw_view);
84 | DemoApp.APP_CONTEXT.proxyClient.getConfig().setConnectCallback(this);
85 | DemoApp.APP_CONTEXT.proxyClient.getConfig().setPushCallback(this);
86 | DemoApp.APP_CONTEXT.proxyClient.subscribeBroadcast(drawTopic);
87 | updateConnect();
88 |
89 | Random random = new Random();
90 | myColor = myColors[random.nextInt(myColors.length)];
91 |
92 | drawView.setOnTouchListener(new View.OnTouchListener() {
93 | @Override
94 | public boolean onTouch(View view, MotionEvent event) {
95 | DrawView.Dot dot = new DrawView.Dot();
96 | dot.xPercent = event.getX() / view.getWidth();
97 | dot.yPercent = event.getY() / view.getHeight();
98 | dot.setIntColor(myColor);
99 | Log.d(TAG, "onTouch " + dot);
100 | if (event.getAction() == MotionEvent.ACTION_DOWN || event.getAction() == MotionEvent.ACTION_MOVE) {
101 | DemoApp.APP_CONTEXT.httpApi.sendMessage(dot, drawTopic, cb);
102 | return true;
103 | } else if (event.getAction() == MotionEvent.ACTION_UP) {
104 | dot.endline = true;
105 | DemoApp.APP_CONTEXT.httpApi.sendMessage(dot, drawTopic, cb);
106 | return true;
107 | } else {
108 | return false;
109 | }
110 | }
111 | });
112 |
113 | findViewById(R.id.btn_clear).setOnClickListener(new View.OnClickListener() {
114 | @Override
115 | public void onClick(View v) {
116 | DemoApp.APP_CONTEXT.httpApi.sendMessage(new DrawView.Dot(), drawTopic, null);
117 | resetLatency();
118 | }
119 | });
120 | }
121 |
122 |
123 | private void updateConnect() {
124 | connect.setText(DemoApp.APP_CONTEXT.proxyClient.isConnected() ? "connected" : "disconnected");
125 | }
126 |
127 | @Override
128 | public void onConnect(String uid) {
129 | updateConnect();
130 | }
131 |
132 | @Override
133 | public void onDisconnect() {
134 | updateConnect();
135 | }
136 |
137 | @Override
138 | public void onPush(String data) {
139 | Log.d(TAG, "push " + data);
140 | DrawView.Dot dot = new Gson().fromJson(data, DrawView.Dot.class);
141 | if (dot.xPercent == 0 && dot.yPercent == 0) {
142 | drawView.clear();
143 | return;
144 | }
145 | drawView.addDot(dot);
146 | updateLatency(dot.timestamp);
147 | }
148 | }
--------------------------------------------------------------------------------
/android-demo/src/main/java/com/yy/misaka/demo/DrawView.java:
--------------------------------------------------------------------------------
1 | package com.yy.misaka.demo;
2 |
3 | import android.content.Context;
4 | import android.graphics.Canvas;
5 | import android.graphics.Color;
6 | import android.graphics.Paint;
7 | import android.graphics.Path;
8 | import android.util.AttributeSet;
9 | import android.view.View;
10 |
11 | import com.yy.httpproxy.util.Log;
12 |
13 | import java.util.ArrayList;
14 | import java.util.HashMap;
15 | import java.util.Iterator;
16 | import java.util.List;
17 | import java.util.Map;
18 |
19 | public class DrawView extends View {
20 |
21 | public static class Dot {
22 | private static int ID = (int) (Math.random() * 1000000);
23 |
24 | public float xPercent;
25 | public float yPercent;
26 | public String color;
27 | public int id = ID;
28 | public long timestamp = System.currentTimeMillis();
29 | public boolean endline = false;
30 |
31 | @Override
32 | public String toString() {
33 | return "Dot{" +
34 | "xPercent=" + xPercent +
35 | ", yPercent=" + yPercent +
36 | ", myColor=" + color +
37 | ", timestamp=" + timestamp +
38 | ", endline=" + endline +
39 | '}';
40 | }
41 |
42 | public void setIntColor(int intColor) {
43 | color = String.format("%06X", (0xFFFFFF & intColor));
44 | }
45 | }
46 |
47 | private Map> lineMap = new HashMap<>();
48 |
49 | public DrawView(Context context) {
50 | super(context);
51 | }
52 |
53 | public DrawView(Context context, AttributeSet attrs) {
54 | super(context, attrs);
55 | }
56 |
57 | public DrawView(Context context, AttributeSet attrs, int defStyle) {
58 | super(context, attrs, defStyle);
59 | }
60 |
61 | @Override
62 | protected void onDraw(Canvas canvas) {
63 | super.onDraw(canvas);
64 |
65 | Log.i("drawview", "ondraw");
66 | Paint paint = new Paint();
67 |
68 | paint.setStyle(Paint.Style.STROKE);
69 | paint.setStrokeWidth(6);
70 | for (List dots : lineMap.values()) {
71 | Path path = new Path();
72 | boolean first = true;
73 | for (Dot dot : dots) {
74 | float x = dot.xPercent * canvas.getWidth();
75 | float y = dot.yPercent * canvas.getHeight();
76 | paint.setColor(Color.parseColor("#" + dot.color));
77 | if (first) {
78 | first = false;
79 | path.moveTo(x, y);
80 | } else if (dot.endline) {
81 | path.lineTo(x, y);
82 | canvas.drawPath(path, paint);
83 | first = true;
84 | } else {
85 | path.lineTo(x, y);
86 | }
87 | }
88 | if (!first) {
89 | canvas.drawPath(path, paint);
90 | }
91 | }
92 | }
93 |
94 | public void addDot(Dot dot) {
95 | List lines = lineMap.get(dot.id);
96 | if (lines == null) {
97 | lines = new ArrayList<>();
98 | lineMap.put(dot.id, lines);
99 | }
100 | lines.add(dot);
101 | invalidate();
102 | }
103 |
104 | public void clear() {
105 | lineMap.clear();
106 | invalidate();
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/android-demo/src/main/java/com/yy/misaka/demo/NickNameActivity.java:
--------------------------------------------------------------------------------
1 | package com.yy.misaka.demo;
2 |
3 | import android.app.Activity;
4 | import android.content.Intent;
5 | import android.os.Bundle;
6 | import android.view.View;
7 | import android.widget.EditText;
8 | import android.widget.Toast;
9 |
10 | import android.util.Log;
11 |
12 | import com.yy.httpproxy.thirdparty.FirebaseProvider;
13 | import com.yy.httpproxy.thirdparty.ProviderFactory;
14 |
15 | import java.util.Arrays;
16 |
17 | public class NickNameActivity extends Activity {
18 |
19 | @Override
20 | protected void onCreate(Bundle savedInstanceState) {
21 | super.onCreate(savedInstanceState);
22 | if (FirebaseProvider.handleLauncher(this)) {
23 | finish();
24 | return;
25 | }
26 | setContentView(R.layout.activity_nick);
27 | String provider = "socket.io";
28 | if (ProviderFactory.checkProvider(this) != null) {
29 | provider = ProviderFactory.checkProvider(this).getSimpleName();
30 | }
31 | setTitle("NotificationProvider :" + provider);
32 | init();
33 | }
34 |
35 | private void init() {
36 | final EditText etNickName = (EditText) findViewById(R.id.et_nick_nickname);
37 |
38 | findViewById(R.id.btn_nick_enter).setOnClickListener(new View.OnClickListener() {
39 | @Override
40 | public void onClick(View v) {
41 | String nickname = String.valueOf(etNickName.getText()).trim();
42 | if (nickname.equals("")) {
43 | Toast.makeText(NickNameActivity.this, "Nickname can't be null", Toast.LENGTH_SHORT).show();
44 | } else {
45 | ChatActivity.launch(NickNameActivity.this, nickname);
46 | }
47 | }
48 | });
49 |
50 | findViewById(R.id.btn_draw_enter).setOnClickListener(new View.OnClickListener() {
51 | @Override
52 | public void onClick(View v) {
53 | Intent intent = new Intent();
54 | intent.setClass(NickNameActivity.this, DrawActivity.class);
55 | startActivity(intent);
56 | }
57 | });
58 | }
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/android-demo/src/main/java/com/yy/misaka/demo/adapter/ChatMessagesAdapter.java:
--------------------------------------------------------------------------------
1 | package com.yy.misaka.demo.adapter;
2 |
3 | import android.support.v7.widget.RecyclerView;
4 | import android.support.v7.widget.RecyclerView.ViewHolder;
5 | import android.view.LayoutInflater;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 | import android.widget.TextView;
9 |
10 | import com.yy.misaka.demo.R;
11 | import com.yy.misaka.demo.entity.Message;
12 |
13 | import java.util.ArrayList;
14 | import java.util.List;
15 |
16 |
17 | public class ChatMessagesAdapter extends RecyclerView.Adapter {
18 |
19 | private List messagesList;
20 |
21 | public void addData(Message message) {
22 | messagesList.add(message);
23 | notifyDataSetChanged();
24 | }
25 |
26 | public ChatMessagesAdapter() {
27 | messagesList = new ArrayList<>();
28 | }
29 |
30 | static class MyViewHolder extends ViewHolder {
31 |
32 | TextView textViewNickName;
33 | TextView textViewMessage;
34 | View itemView;
35 |
36 | public MyViewHolder(View itemView) {
37 | super(itemView);
38 | this.itemView=itemView;
39 | textViewNickName = (TextView) itemView.findViewById(R.id.tv_nickname);
40 | textViewMessage = (TextView) itemView.findViewById(R.id.tv_message);
41 | }
42 | }
43 |
44 | @Override
45 | public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
46 | View view = LayoutInflater.from(parent.getContext())
47 | .inflate(R.layout.item_message, parent, false);
48 | return new MyViewHolder(view);
49 | }
50 |
51 | @Override
52 | public void onBindViewHolder(MyViewHolder holder, int position) {
53 | holder.textViewNickName.setText(messagesList.get(position).getNickName() + ": ");
54 | holder.textViewMessage.setText( messagesList.get(position).getMessage());
55 | holder.itemView.setTag(position);
56 | }
57 |
58 | @Override
59 | public int getItemCount() {
60 | return messagesList.size();
61 | }
62 |
63 | }
64 |
65 |
--------------------------------------------------------------------------------
/android-demo/src/main/java/com/yy/misaka/demo/appmodel/DemoApp.java:
--------------------------------------------------------------------------------
1 | package com.yy.misaka.demo.appmodel;
2 |
3 | import android.app.Application;
4 | import android.util.Log;
5 |
6 | import com.yy.httpproxy.Config;
7 | import com.yy.httpproxy.ProxyClient;
8 | import com.yy.httpproxy.service.DefaultDnsHandler;
9 | import com.yy.httpproxy.service.DefaultNotificationHandler;
10 | import com.yy.misaka.demo.ChatActivity;
11 | import com.yy.misaka.demo.ConnectActivity;
12 |
13 |
14 | /**
15 | * Created by xuduo on 6/13/16.
16 | */
17 | public class DemoApp extends Application {
18 |
19 | public static DemoApp APP_CONTEXT;
20 | public ProxyClient proxyClient;
21 | public HttpApi httpApi;
22 | private String host = "https://spush.yy.com";
23 |
24 | @Override
25 | public void onCreate() {
26 | Log.i("DemoLogger", "DemoApp onCreate");
27 | super.onCreate();
28 | APP_CONTEXT = this;
29 | httpApi = new HttpApi(ChatActivity.API_URL);
30 | DemoApp.APP_CONTEXT.proxyClient = new ProxyClient(new Config(DemoApp.APP_CONTEXT).setHost(host)
31 | .setNotificationHandler(DefaultNotificationHandler.class)
32 | .setDnsHandler(DefaultDnsHandler.class)
33 | .setLogger(ConnectActivity.DemoLogger.class));
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/android-demo/src/main/java/com/yy/misaka/demo/appmodel/HttpApi.java:
--------------------------------------------------------------------------------
1 | package com.yy.misaka.demo.appmodel;
2 |
3 | import android.util.Log;
4 |
5 | import com.yy.httpproxy.ProxyClient;
6 | import com.yy.misaka.demo.ChatActivity;
7 | import com.yy.misaka.demo.entity.Message;
8 | import com.yy.misaka.demo.util.HttpUtils;
9 | import com.yy.misaka.demo.util.JsonHelper;
10 |
11 | import java.io.IOException;
12 | import java.util.HashMap;
13 |
14 | import okhttp3.Call;
15 | import okhttp3.Callback;
16 | import okhttp3.Response;
17 |
18 | public class HttpApi {
19 | private String url;
20 | private static final String TAG = "HttpApi";
21 |
22 | public interface CB {
23 | void latency(long latency);
24 | }
25 |
26 | public HttpApi(String url) {
27 | this.url = url;
28 | }
29 |
30 | public void sendMessage(Object msg, String topic,final CB cb) {
31 | HashMap params = new HashMap<>();
32 | String msgStr = JsonHelper.toJson(msg, "UTF-8");
33 | Log.d(TAG, "msgStr " + msgStr);
34 | params.put("json", msgStr);
35 | params.put("topic", topic);
36 | final long start = System.currentTimeMillis();
37 | HttpUtils.request(url, params, new Callback() {
38 | @Override
39 | public void onFailure(Call call, IOException e) {
40 | Log.d(TAG, "sendMessage onFailure");
41 | }
42 |
43 | @Override
44 | public void onResponse(Call call, Response response) throws IOException {
45 | Log.d(TAG, "sendMessage onResponse " + " p: " + response.protocol() + " " + response.body().string());
46 | if (cb != null) {
47 | cb.latency(System.currentTimeMillis() - start);
48 | }
49 | }
50 | });
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/android-demo/src/main/java/com/yy/misaka/demo/appmodel/YYNotificationReceiver.java:
--------------------------------------------------------------------------------
1 | package com.yy.misaka.demo.appmodel;
2 |
3 | import android.content.Context;
4 | import android.content.Intent;
5 | import android.util.Log;
6 | import android.widget.Toast;
7 |
8 | import com.yy.httpproxy.service.DefaultNotificationHandler;
9 | import com.yy.httpproxy.service.NotificationReceiver;
10 | import com.yy.httpproxy.service.PushedNotification;
11 | import com.yy.misaka.demo.DrawActivity;
12 |
13 | import java.util.HashMap;
14 |
15 | /**
16 | * Created by xuduo on 11/6/15.
17 | */
18 | public class YYNotificationReceiver extends NotificationReceiver {
19 |
20 | @Override
21 | public void onNotificationClicked(Context context, PushedNotification notification) {
22 | Log.d("DemoLogger", "YYNotificationReceiver onNotificationClicked " + notification.id + " values " + notification.payload);
23 | Toast.makeText(context, "YYNotificationReceiver clicked payload: " + notification.payload, Toast.LENGTH_SHORT).show();
24 | Intent intent = new Intent(context, DrawActivity.class);
25 | intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
26 | context.startActivity(intent);
27 | }
28 |
29 | @Override
30 | public void onNotificationArrived(Context context, PushedNotification notification) {
31 | Log.d("DemoLogger", "YYNotificationReceiver onNotificationArrived " + notification.id + " values " + notification.payload);
32 | }
33 |
34 | }
--------------------------------------------------------------------------------
/android-demo/src/main/java/com/yy/misaka/demo/entity/Message.java:
--------------------------------------------------------------------------------
1 | package com.yy.misaka.demo.entity;
2 |
3 | public class Message {
4 |
5 | private String message;
6 | private String nickName;
7 | private String type = "chat_message";
8 |
9 | public String getMessage() {
10 | return message;
11 | }
12 |
13 | public String getNickName() {
14 | return nickName;
15 | }
16 |
17 | public void setMessage(String message) {
18 | this.message = message;
19 | }
20 |
21 | public void setNickName(String nickName) {
22 | this.nickName = nickName;
23 | }
24 |
25 | public String getType() {
26 | return type;
27 | }
28 |
29 | public void setType(String type) {
30 | this.type = type;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/android-demo/src/main/java/com/yy/misaka/demo/test/TestActivity.java:
--------------------------------------------------------------------------------
1 | package com.yy.misaka.demo.test;
2 |
3 | import android.app.Activity;
4 | import android.graphics.Color;
5 | import android.os.Bundle;
6 | import android.util.Log;
7 | import android.widget.TextView;
8 |
9 | import com.yy.httpproxy.Config;
10 | import com.yy.httpproxy.ProxyClient;
11 | import com.yy.httpproxy.service.DefaultDnsHandler;
12 | import com.yy.httpproxy.service.DefaultNotificationHandler;
13 | import com.yy.httpproxy.subscribe.ConnectCallback;
14 | import com.yy.httpproxy.subscribe.PushCallback;
15 | import com.yy.misaka.demo.R;
16 | import java.util.Set;
17 |
18 | /**
19 | * Created by Administrator on 2016/7/19.
20 | */
21 | public class TestActivity extends Activity implements ConnectCallback, PushCallback{
22 |
23 | private static final String TAG = "TestActivity";
24 | public static String host = "https://spush.yy.com";
25 | public static final String topic = "testTopic";
26 | public ProxyClient proxyClient;
27 | private TextView tv_socketState,tv_pushId;
28 | public String pushId;
29 |
30 | private TestConnectCallBack connectCallBack;
31 | private TestPushCallBack pushCallBack;
32 |
33 | public void setPushCallBack(TestPushCallBack pushCallBack) {
34 | this.pushCallBack = pushCallBack;
35 | }
36 |
37 | public void setConnectCallBack(TestConnectCallBack connectCallBack) {
38 | this.connectCallBack = connectCallBack;
39 | }
40 |
41 | @Override
42 | protected void onCreate(Bundle savedInstanceState) {
43 | super.onCreate(savedInstanceState);
44 | setContentView(R.layout.activity_test);
45 | initView();
46 | proxyClient = new ProxyClient(new Config(this).setHost(host)
47 | .setConnectCallback(this)
48 | .setPushCallback(this)
49 | .setDnsHandler(DefaultDnsHandler.class)
50 | .setNotificationHandler(DefaultNotificationHandler.class));
51 | proxyClient.subscribeBroadcast(topic);
52 | pushId = proxyClient.getPushId();
53 | tv_pushId.setText("pushId: " + pushId);
54 | proxyClient.subscribeBroadcast(topic);
55 | }
56 |
57 | public void initView() {
58 | tv_socketState = (TextView)findViewById(R.id.tv_state);
59 | tv_pushId = (TextView)findViewById(R.id.tv_pushId);
60 | }
61 |
62 | @Override
63 | public void onConnect(String uid) {
64 | Log.i(TAG, "socket Connect and uid is " + uid);
65 | tv_socketState.setText("connected");
66 | tv_socketState.setTextColor(Color.GREEN);
67 | if(connectCallBack != null) {
68 | connectCallBack.isConnect(true);
69 | }
70 | }
71 |
72 | @Override
73 | public void onDisconnect() {
74 | Log.i(TAG, "socket disConnect");
75 | tv_socketState.setText("disconnected");
76 | tv_socketState.setTextColor(Color.RED);
77 | if(connectCallBack != null) {
78 | connectCallBack.isConnect(false);
79 | }
80 | }
81 |
82 | @Override
83 | public void onPush(String data) {
84 | Log.i(TAG, data);
85 | pushCallBack.onPush(data);
86 | }
87 |
88 |
89 | public interface TestConnectCallBack {
90 | void isConnect(boolean state);
91 | }
92 |
93 | public interface TestPushCallBack {
94 | void onPush(String data);
95 | }
96 |
97 | }
98 |
--------------------------------------------------------------------------------
/android-demo/src/main/java/com/yy/misaka/demo/util/HttpUtils.java:
--------------------------------------------------------------------------------
1 | package com.yy.misaka.demo.util;
2 |
3 |
4 | import java.security.cert.CertificateException;
5 | import java.util.HashMap;
6 | import java.util.Map;
7 |
8 | import javax.net.ssl.HostnameVerifier;
9 | import javax.net.ssl.SSLContext;
10 | import javax.net.ssl.SSLSession;
11 | import javax.net.ssl.SSLSocketFactory;
12 | import javax.net.ssl.TrustManager;
13 | import javax.net.ssl.X509TrustManager;
14 |
15 | import okhttp3.Callback;
16 | import okhttp3.OkHttpClient;
17 | import okhttp3.Protocol;
18 | import okhttp3.Request;
19 | import okhttp3.internal.Util;
20 |
21 | /**
22 | * Created by Administrator on 2016/4/27.
23 | */
24 | public class HttpUtils {
25 |
26 | private static OkHttpClient okHttpClient = getUnsafeOkHttpClient();
27 |
28 | public static void request(String url, HashMap params, Callback callback) {
29 | StringBuilder okRequestURL = new StringBuilder(url);
30 | if (params != null) {
31 | okRequestURL.append("?");
32 | for (String key : params.keySet()) {
33 | if (params.get(key) instanceof String) {
34 | okRequestURL.append(key).append("=").append(params.get(key).toString()).append("&");
35 | } else {
36 | String encodeStr = JsonHelper.toJson(params.get(key), "UTF-8");
37 | okRequestURL.append(key).append("=").append(encodeStr).append("&");
38 | }
39 | }
40 | }
41 | Request request = new Request.Builder().url(okRequestURL.toString()).build();
42 | okHttpClient.newCall(request).enqueue(callback);
43 | }
44 |
45 | private static OkHttpClient getUnsafeOkHttpClient() {
46 | try {
47 | // Create a trust manager that does not validate certificate chains
48 | X509TrustManager manager = new X509TrustManager() {
49 | @Override
50 | public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
51 | }
52 |
53 | @Override
54 | public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
55 | }
56 |
57 | @Override
58 | public java.security.cert.X509Certificate[] getAcceptedIssuers() {
59 | return new java.security.cert.X509Certificate[]{};
60 | }
61 | };
62 | final TrustManager[] trustAllCerts = new TrustManager[]{
63 | manager
64 | };
65 |
66 | // Install the all-trusting trust manager
67 | final SSLContext sslContext = SSLContext.getInstance("SSL");
68 | sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
69 | // Create an ssl socket factory with our all-trusting manager
70 | final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
71 |
72 | OkHttpClient.Builder builder = new OkHttpClient.Builder();
73 | builder.sslSocketFactory(sslSocketFactory, manager);
74 | builder.hostnameVerifier(new HostnameVerifier() {
75 | @Override
76 | public boolean verify(String hostname, SSLSession session) {
77 | return true;
78 | }
79 | });
80 | // builder.protocols(Util.immutableList(
81 | // Protocol.HTTP_1_1));
82 | OkHttpClient okHttpClient = builder.build();
83 | return okHttpClient;
84 | } catch (Exception e) {
85 | throw new RuntimeException(e);
86 | }
87 | }
88 |
89 | }
90 |
--------------------------------------------------------------------------------
/android-demo/src/main/java/com/yy/misaka/demo/util/JsonHelper.java:
--------------------------------------------------------------------------------
1 | package com.yy.misaka.demo.util;
2 |
3 | import com.google.gson.Gson;
4 | import com.google.gson.GsonBuilder;
5 | import com.google.gson.JsonSyntaxException;
6 | import com.google.gson.reflect.TypeToken;
7 |
8 | import java.io.UnsupportedEncodingException;
9 | import java.lang.reflect.Type;
10 | import java.net.URLEncoder;
11 | import java.util.List;
12 |
13 | public class JsonHelper {
14 |
15 | private static Gson sGson;
16 |
17 |
18 | private static Gson getGson() {
19 | if (sGson == null) {
20 | GsonBuilder gsonBuilder = new GsonBuilder();
21 | sGson = gsonBuilder.create();
22 | }
23 | return sGson;
24 | }
25 |
26 | public static T toObject(String jsonString, Class mclass) {
27 | String s = jsonString;
28 | Gson gson = new Gson();
29 | return gson.fromJson(jsonString, mclass);
30 | }
31 |
32 | public static T jsonToObject(String json, Type tokenType) {
33 | T t = null;
34 | try {
35 | t = getGson().fromJson(json, tokenType);
36 | } catch (JsonSyntaxException e) {
37 | e.printStackTrace();
38 | }
39 | return t;
40 | }
41 |
42 | public static List toObjectList(String jsonString, Class mclass) {
43 | Gson gson = new Gson();
44 | return gson.fromJson(jsonString,
45 | new TypeToken>() {
46 | }.getType());
47 | }
48 |
49 | public static List jsonToObjectList(String json, Type tokenType) {
50 | List t = null;
51 | try {
52 | t = getGson().fromJson(json,
53 | new TypeToken>() {
54 | }.getType());
55 | } catch (JsonSyntaxException e) {
56 | e.printStackTrace();
57 | }
58 | return t;
59 | }
60 |
61 | public static String toJson(T object, String encode) {
62 | return getGson().toJson(object);
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/android-demo/src/main/res/drawable-xxhdpi/misaka.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuduo/socket.io-push-android/c5738189a79bfae036b8199d0287980c734d9d85/android-demo/src/main/res/drawable-xxhdpi/misaka.jpg
--------------------------------------------------------------------------------
/android-demo/src/main/res/layout/activity_chat.xml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
16 |
17 |
23 |
24 |
29 |
30 |
31 |
37 |
38 |
--------------------------------------------------------------------------------
/android-demo/src/main/res/layout/activity_connect.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
13 |
19 |
20 |
26 |
27 |
--------------------------------------------------------------------------------
/android-demo/src/main/res/layout/activity_draw.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
11 |
12 |
19 |
20 |
28 |
29 |
37 |
38 |
46 |
47 |
55 |
56 |
--------------------------------------------------------------------------------
/android-demo/src/main/res/layout/activity_im_user_list.xml:
--------------------------------------------------------------------------------
1 |
10 |
11 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/android-demo/src/main/res/layout/activity_login.xml:
--------------------------------------------------------------------------------
1 |
11 |
12 |
17 |
18 |
19 |
25 |
26 |
28 |
29 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/android-demo/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
22 |
23 |
30 |
31 |
37 |
--------------------------------------------------------------------------------
/android-demo/src/main/res/layout/activity_nick.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
15 |
16 |
24 |
25 |
33 |
34 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/android-demo/src/main/res/layout/activity_profile.xml:
--------------------------------------------------------------------------------
1 |
11 |
16 |
23 |
24 |
30 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/android-demo/src/main/res/layout/activity_register.xml:
--------------------------------------------------------------------------------
1 |
10 |
11 |
16 |
17 |
18 |
24 |
25 |
27 |
28 |
34 |
35 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/android-demo/src/main/res/layout/activity_splash.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/android-demo/src/main/res/layout/activity_test.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
13 |
14 |
18 |
19 |
20 |
21 |
22 |
28 |
29 |
33 |
34 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/android-demo/src/main/res/layout/item_message.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
15 |
21 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/android-demo/src/main/res/layout/item_user.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
14 |
22 |
31 |
32 |
--------------------------------------------------------------------------------
/android-demo/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/android-demo/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
--------------------------------------------------------------------------------
/android-demo/src/main/res/values/hwpush_colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #ffffffff
4 | #ff000000
5 | #FF000000
6 | #80000000
7 | #65000000
8 | #2c9195
9 | #00bcd5
10 | #000000
11 |
12 |
--------------------------------------------------------------------------------
/android-demo/src/main/res/values/hwpush_strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Back
5 | Forward
6 | Refresh
7 | Favorite
8 | Delete notifications
9 | Favorites
10 | Favorite notifications
11 |
12 | Delete
13 | Select all
14 |
15 | A Favorites icon will be created on the home screen. You can touch the icon to view all your favorite notifications.
16 | OK
17 |
18 | Cancel
19 |
20 |
21 | - Delete selected notification?
22 |
23 | - Delete selected notifications?
24 |
25 | Deselect all
26 | No favorite notifications
27 | Push Service
28 | Rich media
29 | Loading... Please wait.
30 | Note
31 | A maximum of 1000 favorite notifications can be saved. Delete some notifications before you can add new ones. Go to your favorite notifications list?
32 | Go
33 | Store messages
34 |
35 | successRateAnalytics
36 |
--------------------------------------------------------------------------------
/android-demo/src/main/res/values/hwpush_styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
--------------------------------------------------------------------------------
/android-demo/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | socket.io-push
4 | Hello world!
5 | Settings
6 | ImUserListActivity
7 | ChatActivity
8 | 2882303761517467652
9 | 5981746732652
10 |
11 |
--------------------------------------------------------------------------------
/android-demo/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/android-push-sdk/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'java'
2 | apply plugin: 'idea'
3 | apply plugin: 'maven'
4 | apply plugin: 'signing'
5 |
6 | configurations {
7 | provided
8 | }
9 |
10 | sourceSets {
11 | main {
12 | compileClasspath += configurations.provided
13 | }
14 | test {
15 | compileClasspath += configurations.provided
16 | }
17 |
18 | main.java.srcDirs += 'sub/engine.io-client-java/src/main/java'
19 | //main.java.srcDirs += 'sub/socket.io-client-java/src/main/java'
20 | }
21 |
22 | sourceSets.main.compileClasspath += configurations.provided
23 |
24 | idea {
25 | module {
26 | scopes.PROVIDED.plus += [configurations.provided] // for Gradle 2.0
27 | }
28 | }
29 |
30 | dependencies {
31 | compile 'com.squareup.okhttp3:okhttp:3.5.0'
32 | compile('io.socket:socket.io-client:0.8.3') {
33 | exclude group: 'io.socket', module: 'engine.io-client'
34 | }
35 | provided files('libs/support-v4-19.1.0.jar')
36 | provided files('libs/android.jar')
37 | provided files('libs/HMSSdkBase_2.5.3.305.jar')
38 | provided files('libs/HMSSdkPush_2.5.3.305.jar')
39 | provided files('libs/MiPush_SDK_Client_3_2_2.jar')
40 | provided files('libs/com.umeng.message_3.1.1a.jar')
41 | provided files('libs/firebase-core-11.8.0.jar')
42 | provided files('libs/firebase-iid-11.8.0.jar')
43 | provided files('libs/firebase-messaging-11.8.0.jar')
44 | provided files('libs/firebase-common-11.8.0.jar')
45 | provided files('libs/play-services-base-11.8.0.jar')
46 | provided files('libs/play-services-basement-11.8.0.jar')
47 |
48 | }
49 |
50 | group = "com.yy"
51 | version = "1.1.28"
52 |
53 | tasks.withType(JavaCompile) {
54 | options.encoding = 'UTF-8'
55 | }
56 |
57 | javadoc {
58 | options {
59 | encoding "UTF-8"
60 | charSet 'UTF-8'
61 | author true // 支持author标记XXx
62 | version true // 支持version标记
63 | }
64 | }
65 |
66 | compileJava {
67 | options.encoding = "UTF-8"
68 | }
69 |
70 | task javadocJar(type: Jar) {
71 | classifier = 'javadoc'
72 | from javadoc
73 | }
74 |
75 | task sourcesJar(type: Jar) {
76 | classifier = 'sources'
77 | from sourceSets.main.allSource
78 | }
79 |
80 | artifacts {
81 | archives javadocJar, sourcesJar
82 | }
83 |
84 | signing {
85 | sign configurations.archives
86 | }
87 |
88 | uploadArchives {
89 | repositories {
90 | mavenDeployer {
91 | beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }
92 |
93 | repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") {
94 | authentication(userName: 'xuudoo@gmail.com', password: 'qwe12345')
95 | }
96 |
97 | pom.project {
98 | name 'misaka-android'
99 | packaging 'jar'
100 | description 'misaka-android'
101 | description 'misaka-android'
102 | url 'https://github.com/xuduo/misaka'
103 |
104 | scm {
105 | url 'https://github.com/xuduo/AndroidNotificationCenter'
106 | connection 'https://github.com/xuduo/AndroidNotificationCenter'
107 | developerConnection 'https://github.com/xuduo/AndroidNotificationCenter'
108 | }
109 |
110 | licenses {
111 | license {
112 | name 'The Apache Software License, Version 2.0'
113 | url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
114 | distribution 'repo'
115 | }
116 | }
117 |
118 | developers {
119 | developer {
120 | id 'xuduo'
121 | name 'xuduo'
122 | }
123 | }
124 | }
125 |
126 | }
127 | }
128 | }
--------------------------------------------------------------------------------
/android-push-sdk/libs/HMSSdkBase_2.5.3.305.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuduo/socket.io-push-android/c5738189a79bfae036b8199d0287980c734d9d85/android-push-sdk/libs/HMSSdkBase_2.5.3.305.jar
--------------------------------------------------------------------------------
/android-push-sdk/libs/HMSSdkPush_2.5.3.305.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuduo/socket.io-push-android/c5738189a79bfae036b8199d0287980c734d9d85/android-push-sdk/libs/HMSSdkPush_2.5.3.305.jar
--------------------------------------------------------------------------------
/android-push-sdk/libs/MiPush_SDK_Client_3_2_2.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuduo/socket.io-push-android/c5738189a79bfae036b8199d0287980c734d9d85/android-push-sdk/libs/MiPush_SDK_Client_3_2_2.jar
--------------------------------------------------------------------------------
/android-push-sdk/libs/android.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuduo/socket.io-push-android/c5738189a79bfae036b8199d0287980c734d9d85/android-push-sdk/libs/android.jar
--------------------------------------------------------------------------------
/android-push-sdk/libs/com.umeng.message_3.1.1a.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuduo/socket.io-push-android/c5738189a79bfae036b8199d0287980c734d9d85/android-push-sdk/libs/com.umeng.message_3.1.1a.jar
--------------------------------------------------------------------------------
/android-push-sdk/libs/firebase-common-11.8.0.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuduo/socket.io-push-android/c5738189a79bfae036b8199d0287980c734d9d85/android-push-sdk/libs/firebase-common-11.8.0.jar
--------------------------------------------------------------------------------
/android-push-sdk/libs/firebase-core-11.8.0.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuduo/socket.io-push-android/c5738189a79bfae036b8199d0287980c734d9d85/android-push-sdk/libs/firebase-core-11.8.0.jar
--------------------------------------------------------------------------------
/android-push-sdk/libs/firebase-iid-11.8.0.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuduo/socket.io-push-android/c5738189a79bfae036b8199d0287980c734d9d85/android-push-sdk/libs/firebase-iid-11.8.0.jar
--------------------------------------------------------------------------------
/android-push-sdk/libs/firebase-messaging-11.8.0.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuduo/socket.io-push-android/c5738189a79bfae036b8199d0287980c734d9d85/android-push-sdk/libs/firebase-messaging-11.8.0.jar
--------------------------------------------------------------------------------
/android-push-sdk/libs/play-services-base-11.8.0.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuduo/socket.io-push-android/c5738189a79bfae036b8199d0287980c734d9d85/android-push-sdk/libs/play-services-base-11.8.0.jar
--------------------------------------------------------------------------------
/android-push-sdk/libs/play-services-basement-11.8.0.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuduo/socket.io-push-android/c5738189a79bfae036b8199d0287980c734d9d85/android-push-sdk/libs/play-services-basement-11.8.0.jar
--------------------------------------------------------------------------------
/android-push-sdk/libs/play-services-gcm-11.8.0.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuduo/socket.io-push-android/c5738189a79bfae036b8199d0287980c734d9d85/android-push-sdk/libs/play-services-gcm-11.8.0.jar
--------------------------------------------------------------------------------
/android-push-sdk/libs/support-v4-19.1.0.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuduo/socket.io-push-android/c5738189a79bfae036b8199d0287980c734d9d85/android-push-sdk/libs/support-v4-19.1.0.jar
--------------------------------------------------------------------------------
/android-push-sdk/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/android-push-sdk/src/main/java/com/yy/httpproxy/AndroidLoggingHandler.java:
--------------------------------------------------------------------------------
1 | package com.yy.httpproxy;
2 |
3 | import android.util.Log;
4 |
5 | import java.util.logging.Handler;
6 | import java.util.logging.Level;
7 | import java.util.logging.LogManager;
8 | import java.util.logging.LogRecord;
9 | import java.util.logging.Logger;
10 |
11 | public class AndroidLoggingHandler extends Handler {
12 |
13 | public static void reset(Handler rootHandler) {
14 | Logger rootLogger = LogManager.getLogManager().getLogger("");
15 | Handler[] handlers = rootLogger.getHandlers();
16 | for (Handler handler : handlers) {
17 | rootLogger.removeHandler(handler);
18 | }
19 | LogManager.getLogManager().getLogger("").addHandler(rootHandler);
20 | }
21 |
22 | @Override
23 | public void close() {
24 | }
25 |
26 | @Override
27 | public void flush() {
28 | }
29 |
30 | @Override
31 | public void publish(LogRecord record) {
32 | if (!super.isLoggable(record))
33 | return;
34 |
35 | String name = record.getLoggerName();
36 | int maxLength = 30;
37 | String tag = name.length() > maxLength ? name.substring(name.length() - maxLength) : name;
38 |
39 | try {
40 | int level = getAndroidLevel(record.getLevel());
41 | if (level <= Log.DEBUG) {
42 | com.yy.httpproxy.util.Log.d(tag, record.getMessage());
43 | } else if (level <= Log.WARN) {
44 | com.yy.httpproxy.util.Log.d(tag, record.getMessage());
45 | } else if (level <= Log.ERROR) {
46 | com.yy.httpproxy.util.Log.e(tag, record.getMessage(), record.getThrown());
47 | }
48 | } catch (RuntimeException e) {
49 | Log.e("AndroidLoggingHandler", "Error logging message.", e);
50 | }
51 | }
52 |
53 | static int getAndroidLevel(Level level) {
54 | int value = level.intValue();
55 | if (value >= 1000) {
56 | return Log.ERROR;
57 | } else if (value >= 900) {
58 | return Log.WARN;
59 | } else if (value >= 800) {
60 | return Log.INFO;
61 | } else {
62 | return Log.DEBUG;
63 | }
64 | }
65 | }
--------------------------------------------------------------------------------
/android-push-sdk/src/main/java/com/yy/httpproxy/Config.java:
--------------------------------------------------------------------------------
1 | package com.yy.httpproxy;
2 |
3 | import android.content.Context;
4 |
5 | import com.yy.httpproxy.socketio.RemoteClient;
6 | import com.yy.httpproxy.subscribe.ConnectCallback;
7 | import com.yy.httpproxy.subscribe.PushCallback;
8 | import com.yy.httpproxy.subscribe.RandomPushIdGenerator;
9 | import com.yy.httpproxy.util.Logger;
10 |
11 | /**
12 | * Created by xuduo on 10/19/15.
13 | */
14 | public class Config {
15 |
16 | private RemoteClient remoteClient;
17 | private Context context;
18 | private PushCallback pushCallback;
19 | private ConnectCallback connectCallback;
20 | private String host;
21 | private String pushId;
22 | private String notificationHandler;
23 | private String dnsHandler;
24 | private String logger;
25 |
26 | public Config(Context context) {
27 | this.context = context;
28 | this.pushId = new RandomPushIdGenerator().generatePushId(context);
29 | }
30 |
31 | public RemoteClient getRemoteClient() {
32 | if (remoteClient == null) {
33 | remoteClient = new RemoteClient(context, host, pushId, notificationHandler, logger, dnsHandler);
34 | }
35 | return remoteClient;
36 | }
37 |
38 | public Config setHost(String host) {
39 | this.host = host;
40 | return this;
41 | }
42 |
43 | public Config setPushCallback(PushCallback pushCallback) {
44 | this.pushCallback = pushCallback;
45 | return this;
46 | }
47 |
48 | public PushCallback getPushCallback() {
49 | return pushCallback;
50 | }
51 |
52 | public Config setLogger(Class extends Logger> logger) {
53 | this.logger = logger.getName();
54 | return this;
55 | }
56 |
57 | public Config setNotificationHandler(Class notificationHandler) {
58 | this.notificationHandler = notificationHandler.getName();
59 | return this;
60 | }
61 |
62 | public Config setDnsHandler(Class dnsHandler) {
63 | this.dnsHandler = dnsHandler.getName();
64 | return this;
65 | }
66 |
67 | public ConnectCallback getConnectCallback() {
68 | return connectCallback;
69 | }
70 |
71 | public Config setConnectCallback(ConnectCallback connectCallback) {
72 | this.connectCallback = connectCallback;
73 | return this;
74 | }
75 |
76 | public String getPushId() {
77 | return pushId;
78 | }
79 |
80 | public String getLogger() {
81 | return logger;
82 | }
83 |
84 | public Context getContext() {
85 | return context;
86 | }
87 |
88 | public String getHost() {
89 | return host;
90 | }
91 |
92 | public String getNotificationHandler() {
93 | return notificationHandler;
94 | }
95 |
96 | public String getDnsHandler() {
97 | return dnsHandler;
98 | }
99 |
100 | @Override
101 | public String toString() {
102 | return "Config{" +
103 | "remoteClient=" + remoteClient +
104 | ", context=" + context +
105 | ", pushCallback=" + pushCallback +
106 | ", connectCallback=" + connectCallback +
107 | ", host='" + host + '\'' +
108 | ", pushId='" + pushId + '\'' +
109 | ", notificationHandler='" + notificationHandler + '\'' +
110 | ", dnsHandler='" + dnsHandler + '\'' +
111 | ", logger='" + logger + '\'' +
112 | '}';
113 | }
114 | }
--------------------------------------------------------------------------------
/android-push-sdk/src/main/java/com/yy/httpproxy/ProxyClient.java:
--------------------------------------------------------------------------------
1 | package com.yy.httpproxy;
2 |
3 | import android.app.ActivityManager;
4 | import android.app.Service;
5 | import android.content.Context;
6 | import android.content.Intent;
7 | import android.os.Handler;
8 | import android.os.Looper;
9 | import android.os.SystemClock;
10 |
11 | import com.yy.httpproxy.requester.RequestInfo;
12 | import com.yy.httpproxy.service.ConnectionService;
13 | import com.yy.httpproxy.subscribe.PushCallback;
14 | import com.yy.httpproxy.thirdparty.ProviderFactory;
15 | import com.yy.httpproxy.thirdparty.UmengProvider;
16 | import com.yy.httpproxy.util.Log;
17 | import com.yy.httpproxy.util.ServiceCheckUtil;
18 |
19 | import java.io.BufferedReader;
20 | import java.io.FileInputStream;
21 | import java.io.IOException;
22 | import java.io.InputStreamReader;
23 | import java.util.HashMap;
24 | import java.util.Set;
25 |
26 | public class ProxyClient implements PushCallback {
27 |
28 | private Config config;
29 | public static final String TAG = "ProxyClient";
30 | private long mainThreadId;
31 | private Handler handler;
32 | public static long uptime;
33 |
34 | public ProxyClient(final Config config) {
35 | uptime = SystemClock.elapsedRealtime();
36 | String packageName = config.getContext().getPackageName();
37 | String processName = getProcessName(config.getContext());
38 | if (!packageName.equals(processName)) {
39 | String pushProcess = ServiceCheckUtil.getPushProcessName(config.getContext());
40 | Log.i(TAG, "not in main process, skip init , start service ");
41 | if (pushProcess.equals(processName)) {
42 | Log.i(TAG, "in push process, registerUmeng");
43 | registerUmeng(config.getContext());
44 | }
45 | return;
46 | }
47 | Log.i(TAG, "init " + config);
48 | this.config = config;
49 | handler = new Handler(Looper.getMainLooper());
50 | mainThreadId = Looper.getMainLooper().getThread().getId();
51 |
52 | if (config.getRemoteClient() != null) {
53 | config.getRemoteClient().setProxyClient(this);
54 | }
55 |
56 | registerUmeng(config.getContext());
57 |
58 | }
59 |
60 | private void registerUmeng(Context context) {
61 | if (UmengProvider.class.equals(ProviderFactory.checkProvider(context))) {
62 | UmengProvider.register(context);
63 | }
64 | }
65 |
66 | public boolean isConnected() {
67 | return config.getRemoteClient().isConnected();
68 | }
69 |
70 | public void setTags(Set tags) {
71 | config.getRemoteClient().
72 | setTag(tags);
73 | }
74 |
75 | public void request(String path, byte[] data) {
76 | final RequestInfo requestInfo = new RequestInfo();
77 | requestInfo.setBody(data);
78 | requestInfo.setPath(path);
79 |
80 | config.getRemoteClient().
81 | request(requestInfo);
82 | }
83 |
84 | public void reportStats(String path, int successCount, int errorCount, int latency) {
85 | config.getRemoteClient().
86 | reportStats(path, successCount, errorCount, latency);
87 | }
88 |
89 | private void subscribeBroadcast(String topic, boolean receiveTtlPackets) {
90 | config.getRemoteClient().subscribeBroadcast(topic, receiveTtlPackets);
91 | }
92 |
93 | public void subscribeBroadcast(String topic) {
94 | config.getRemoteClient().subscribeBroadcast(topic, false);
95 | }
96 |
97 | public void subscribeAndReceiveTtlPackets(String topic) {
98 | config.getRemoteClient().subscribeBroadcast(topic, true);
99 | }
100 |
101 | public void unsubscribeBroadcast(String topic) {
102 | config.getRemoteClient().unsubscribeBroadcast(topic);
103 | }
104 |
105 | public void exit() {
106 | config.getRemoteClient().exit();
107 | }
108 |
109 | public void unbindUid() {
110 | config.getRemoteClient().unbindUid();
111 | }
112 |
113 | public void bindUid(HashMap data) {
114 | config.getRemoteClient().bindUid(data);
115 | }
116 |
117 | @Override
118 | public void onPush(final String data) {
119 | if (config.getPushCallback() != null) {
120 | if (Thread.currentThread().getId() == mainThreadId) {
121 | Log.d(TAG, "mainThreadId push data: " + data);
122 | config.getPushCallback().onPush(data);
123 | } else {
124 | handler.post(new Runnable() {
125 | @Override
126 | public void run() {
127 | Log.d(TAG, "post push data: " + data);
128 | config.getPushCallback().onPush(data);
129 | }
130 | });
131 | }
132 | }
133 | }
134 |
135 | public String getProcessName(Context context) {
136 | BufferedReader cmdlineReader = null;
137 | try {
138 | cmdlineReader = new BufferedReader(new InputStreamReader(
139 | new FileInputStream(
140 | "/proc/" + android.os.Process.myPid() + "/cmdline"),
141 | "iso-8859-1"));
142 | int c;
143 | StringBuilder processName = new StringBuilder();
144 | while ((c = cmdlineReader.read()) > 0) {
145 | processName.append((char) c);
146 | }
147 | Log.d(TAG, "/proc/ file name " + processName.toString());
148 | return processName.toString();
149 | } catch (Exception e) {
150 | Log.e(TAG, "read /proc/ error ", e);
151 | int pid = android.os.Process.myPid();
152 | ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
153 | for (ActivityManager.RunningAppProcessInfo processInfo : manager.getRunningAppProcesses()) {
154 | if (processInfo.pid == pid) {
155 | Log.d(TAG, "processInfo.processName file name " + processInfo.processName);
156 | return processInfo.processName;
157 | }
158 | }
159 | } finally {
160 | if (cmdlineReader != null) {
161 | try {
162 | cmdlineReader.close();
163 | } catch (IOException e) {
164 |
165 | }
166 | }
167 | }
168 | return context.getPackageName();
169 | }
170 |
171 | public String getPushId() {
172 | return getConfig().getPushId();
173 | }
174 |
175 | public Config getConfig() {
176 | return config;
177 | }
178 | }
179 |
--------------------------------------------------------------------------------
/android-push-sdk/src/main/java/com/yy/httpproxy/requester/RequestInfo.java:
--------------------------------------------------------------------------------
1 | package com.yy.httpproxy.requester;
2 |
3 | import java.io.Serializable;
4 | import java.math.BigInteger;
5 | import java.security.SecureRandom;
6 |
7 | /**
8 | * Created by xuduo on 10/16/15.
9 | */
10 | public class RequestInfo implements Serializable{
11 |
12 | private String sequenceId = new BigInteger(130, new SecureRandom()).toString(32);
13 | private byte[] body;
14 | private String path;
15 | private boolean expectReply = false;
16 | private long timestamp;
17 |
18 | public String getPath() {
19 | return path;
20 | }
21 |
22 | public void setPath(String path) {
23 | this.path = path;
24 | }
25 |
26 | public String getSequenceId() {
27 | return sequenceId;
28 | }
29 |
30 | public long getTimestamp() {
31 | return timestamp;
32 | }
33 |
34 | public void setTimestamp() {
35 | this.timestamp = System.currentTimeMillis();
36 | }
37 |
38 | public boolean timeoutForRequest(long timeout) {
39 | return System.currentTimeMillis() - timestamp > timeout;
40 | }
41 |
42 | public byte[] getBody() {
43 | return body;
44 | }
45 |
46 | public void setBody(byte[] body) {
47 | this.body = body;
48 | }
49 |
50 | public boolean isExpectReply() {
51 | return expectReply;
52 | }
53 |
54 | public void setExpectReply(boolean expectReply) {
55 | this.expectReply = expectReply;
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/android-push-sdk/src/main/java/com/yy/httpproxy/service/BootBroadcastReceiver.java:
--------------------------------------------------------------------------------
1 | package com.yy.httpproxy.service;
2 |
3 | import android.content.BroadcastReceiver;
4 | import android.content.Context;
5 | import android.content.Intent;
6 |
7 | import com.yy.httpproxy.util.Log;
8 |
9 | /**
10 | * Created by Administrator on 2015/12/31.
11 | */
12 | public class BootBroadcastReceiver extends BroadcastReceiver {
13 | private static String TAG = "MyBootBroadcastReceiver";
14 |
15 | @Override
16 | public void onReceive(Context context, Intent intent) {
17 | Log.i(TAG, "BOOT_COMPLETED start ConnectService");
18 | try {
19 | Intent service = new Intent(context, ConnectionService.class);
20 | context.startService(service);
21 | } catch (Exception e) {
22 | Log.e(TAG, "BOOT_COMPLETED start ConnectService error", e);
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/android-push-sdk/src/main/java/com/yy/httpproxy/service/ConnectionService.java:
--------------------------------------------------------------------------------
1 | package com.yy.httpproxy.service;
2 |
3 | import android.app.Service;
4 | import android.content.Intent;
5 | import android.os.Bundle;
6 | import android.os.Handler;
7 | import android.os.IBinder;
8 | import android.os.Message;
9 | import android.os.Messenger;
10 | import android.text.format.DateFormat;
11 |
12 | import com.yy.httpproxy.requester.RequestInfo;
13 | import com.yy.httpproxy.socketio.RemoteClient;
14 | import com.yy.httpproxy.socketio.SocketIOProxyClient;
15 | import com.yy.httpproxy.subscribe.CachedSharedPreference;
16 | import com.yy.httpproxy.subscribe.PushCallback;
17 | import com.yy.httpproxy.thirdparty.NotificationProvider;
18 | import com.yy.httpproxy.thirdparty.ProviderFactory;
19 | import com.yy.httpproxy.util.CrashHandler;
20 | import com.yy.httpproxy.util.Log;
21 | import com.yy.httpproxy.util.LogcatLogger;
22 | import com.yy.httpproxy.util.Logger;
23 |
24 | import org.json.JSONObject;
25 |
26 | import java.util.ArrayList;
27 | import java.util.Date;
28 | import java.util.HashMap;
29 | import java.util.HashSet;
30 |
31 | public class ConnectionService extends Service implements PushCallback, SocketIOProxyClient.Callback {
32 |
33 | private static final String TAG = "ConnectionService";
34 | public static SocketIOProxyClient client;
35 | private NotificationHandler notificationHandler;
36 | private DnsHandler dnsHandler;
37 | private static NotificationProvider notificationProvider;
38 |
39 | public static final int CMD_PUSH = 2;
40 | public static final int CMD_NOTIFICATION_CLICKED = 3;
41 | public static final int CMD_NOTIFICATION_ARRIVED = 5;
42 | public static final int CMD_CONNECTED = 5;
43 | public static final int CMD_DISCONNECT = 6;
44 | private CachedSharedPreference pref;
45 | private final Messenger messenger = new Messenger(new IncomingHandler());
46 | private Messenger remoteClient;
47 | private boolean bound = false;
48 |
49 | private class IncomingHandler extends Handler {
50 | @Override
51 | public void handleMessage(Message msg) {
52 | int cmd = msg.what;
53 | Log.d(TAG, "receive msg " + cmd);
54 | Bundle bundle = msg.getData();
55 | if (cmd == RemoteClient.CMD_SUBSCRIBE_BROADCAST) {
56 | String topic = bundle.getString("topic");
57 | boolean receiveTtlPackets = bundle.getBoolean("receiveTtlPackets", false);
58 | client().subscribeBroadcast(topic, receiveTtlPackets);
59 | } else if (cmd == RemoteClient.CMD_REQUEST) {
60 | RequestInfo info = (RequestInfo) bundle.getSerializable("requestInfo");
61 | client().request(info);
62 | } else if (cmd == RemoteClient.CMD_REGISTER_CLIENT) {
63 | remoteClient = msg.replyTo;
64 | bound = true;
65 | } else if (cmd == RemoteClient.CMD_UNSUBSCRIBE_BROADCAST) {
66 | String topic = bundle.getString("topic");
67 | client().unsubscribeBroadcast(topic);
68 | } else if (cmd == RemoteClient.CMD_STATS) {
69 | String path = bundle.getString("path");
70 | int successCount = bundle.getInt("successCount");
71 | int errorCount = bundle.getInt("errorCount");
72 | int latency = bundle.getInt("latency");
73 | client().reportStats(path, successCount, errorCount, latency);
74 | } else if (cmd == RemoteClient.CMD_UNBIND_UID) {
75 | client().unbindUid();
76 | } else if (cmd == RemoteClient.CMD_BIND_UID) {
77 | HashMap data = (HashMap) bundle.getSerializable("data");
78 | client().bindUid(data);
79 | } else if (cmd == RemoteClient.CMD_SET_TOKEN) {
80 | String token = bundle.getString("token");
81 | setToken(token);
82 | } else if (cmd == RemoteClient.CMD_NOTIFICATION_CLICK) {
83 | String id = bundle.getString("id");
84 | client().sendNotificationClick(id);
85 | } else if (cmd == RemoteClient.CMD_SET_TAG) {
86 | ArrayList tags = bundle.getStringArrayList("tags");
87 | client().setTags(new HashSet(tags));
88 | } else if (cmd == RemoteClient.CMD_NOTIFICATION_RECEIVE) {
89 | String notificationStr = bundle.getString("notification");
90 | try {
91 | JSONObject obj = new JSONObject(notificationStr);
92 | PushedNotification pushedNotification = new PushedNotification(obj.getString("id"), obj);
93 | if (ForegroundService.instance != null) {
94 | ForegroundService.instance.onNotification(pushedNotification);
95 | }
96 | } catch (Exception e) {
97 |
98 | }
99 |
100 | }
101 | }
102 | }
103 |
104 | @Override
105 | public void onCreate() {
106 | super.onCreate();
107 | pref = new CachedSharedPreference(this);
108 | Log.i(TAG, "ConnectionService onCreate");
109 | }
110 |
111 | private SocketIOProxyClient client() {
112 | if (client == null) {
113 | initClient(null);
114 | }
115 | return client;
116 | }
117 |
118 | private void startForegroundService() {
119 | try {
120 | Intent intent = new Intent(this, ForegroundService.class);
121 | startService(intent);
122 | } catch (Exception e) {
123 | Log.e(TAG, "start ForegroundService error", e);
124 | }
125 | }
126 |
127 | private String getFromIntentOrPref(Intent intent, String name) {
128 | String value = null;
129 | if (intent != null) {
130 | value = intent.getStringExtra(name);
131 | }
132 | if (value == null) {
133 | value = pref.get(name);
134 | } else {
135 | pref.save(name, value);
136 | }
137 | return value;
138 | }
139 |
140 | @Override
141 | public int onStartCommand(Intent intent, int flags, int startId) {
142 | String logger = getFromIntentOrPref(intent, "logger");
143 | initLogger(logger);
144 | initCrashHandler();
145 | String host = "null";
146 | if (intent != null) {
147 | host = intent.getStringExtra("host");
148 | }
149 | Log.d(TAG, "onStartCommand " + host);
150 |
151 | ForegroundService.instance = this;
152 | startForegroundService();
153 |
154 | initClient(intent);
155 | return Service.START_STICKY;
156 | }
157 |
158 | @Override
159 | public IBinder onBind(Intent intent) {
160 | Log.d(TAG, "onBind");
161 | return messenger.getBinder();
162 | }
163 |
164 | private void initCrashHandler() {
165 | if (!(Thread.getDefaultUncaughtExceptionHandler() instanceof CrashHandler)) {
166 | Thread.setDefaultUncaughtExceptionHandler(new CrashHandler());
167 | }
168 | }
169 |
170 | private void initLogger(String loggerClass) {
171 | android.util.Log.i(TAG, "initLogger " + loggerClass);
172 | if (Log.logger == null) {
173 | if (loggerClass == null) {
174 | Log.logger = new LogcatLogger();
175 | } else {
176 | try {
177 | Log.logger = (Logger) Class.forName(loggerClass).newInstance();
178 | } catch (Exception e) {
179 | throw new RuntimeException(e);
180 | }
181 | }
182 | }
183 | }
184 |
185 | private void initClient(Intent intent) {
186 | String host = getFromIntentOrPref(intent, "host");
187 | if (client != null && !host.equals(client.getHost())) {
188 | Log.i(TAG, "host changed re create client");
189 | client.disconnect();
190 | client = null;
191 | }
192 | if (client == null) {
193 | String pushId = getFromIntentOrPref(intent, "pushId");
194 |
195 | if (host == null) {
196 | Log.e(TAG, "host is null , exit");
197 | stopSelf();
198 | return;
199 | }
200 |
201 | notificationHandler = (NotificationHandler) initClassByName(getFromIntentOrPref(intent, "notificationHandler"));
202 | if (notificationHandler == null) {
203 | notificationHandler = new DefaultNotificationHandler();
204 | }
205 |
206 | dnsHandler = (DnsHandler) initClassByName(getFromIntentOrPref(intent, "dnsHandler"));
207 | if (dnsHandler == null) {
208 | dnsHandler = new DefaultDnsHandler();
209 | }
210 | dnsHandler.init(this.getApplicationContext());
211 |
212 | notificationProvider = ProviderFactory.getProvider(this.getApplicationContext());
213 | client = new SocketIOProxyClient(this.getApplicationContext(), host, pushId, notificationProvider, dnsHandler);
214 | client.setPushCallback(this);
215 | client.setSocketCallback(this);
216 | }
217 | }
218 |
219 | private Object initClassByName(String handlerClassName) {
220 | Class handlerClass;
221 | Object handler = null;
222 | if (handlerClassName != null) {
223 | try {
224 | handlerClass = Class.forName(handlerClassName);
225 | handler = handlerClass.newInstance();
226 | } catch (Exception e) {
227 | e.printStackTrace();
228 | handler = null;
229 | }
230 |
231 | }
232 | return handler;
233 | }
234 |
235 | @Override
236 | public void onDestroy() {
237 | Log.d(TAG, "onDestroy");
238 | super.onDestroy();
239 | if (client != null) {
240 | client.disconnect();
241 | client = null;
242 | }
243 | }
244 |
245 | @Override
246 | public void onRebind(Intent intent) {
247 | Log.d(TAG, "onRebind");
248 | if (client != null) {
249 | RequestInfo requestInfo = new RequestInfo();
250 | requestInfo.setPath("/androidBind");
251 | client().request(requestInfo);
252 | }
253 | }
254 |
255 | @Override
256 | public boolean onUnbind(Intent intent) {
257 | Log.d(TAG, "onUnbind");
258 | RequestInfo requestInfo = new RequestInfo();
259 | requestInfo.setPath("/androidUnbind");
260 | client().request(requestInfo);
261 | bound = false;
262 | return true;
263 | }
264 |
265 | @Override
266 | public void onPush(String data) {
267 | Log.d(TAG, "on push data:" + data);
268 | Message msg = Message.obtain(null, ConnectionService.CMD_PUSH, 0, 0);
269 | Bundle bundle = new Bundle();
270 | bundle.putString("data", data);
271 | msg.setData(bundle);
272 | sendMsg(msg);
273 | }
274 |
275 | @Override
276 | public void onNotification(PushedNotification notification) {
277 | Log.i(TAG, "onNotification " + notification);
278 | String hashCode = notification.hashCode() + "";
279 | DateFormat df = new DateFormat();
280 | Date now = new Date();
281 | String today = "noti_" + df.format("yyyy-MM-dd", now).toString();
282 | String yesterday = "noti_" + df.format("yyyy-MM-dd", new Date(now.getTime() - 24 * 3600 * 1000)).toString();
283 | if (!pref.getStringSet(today).contains(hashCode) && !pref.getStringSet(yesterday).contains(hashCode)) {
284 | pref.addStringSet(today, hashCode);
285 | notificationHandler.handlerNotification(this, bound, notification);
286 | } else {
287 | Log.i(TAG, "skip duplicate notification");
288 | }
289 | }
290 |
291 | public void sendConnect() {
292 | if (client == null) {
293 | return;
294 | }
295 | int id;
296 | if (client.isConnected()) {
297 | id = ConnectionService.CMD_CONNECTED;
298 | } else {
299 | id = ConnectionService.CMD_DISCONNECT;
300 | }
301 | Message msg = Message.obtain(null, id, 0, 0);
302 | Bundle bundle = new Bundle();
303 | bundle.putString("uid", client.getUid());
304 | msg.setData(bundle);
305 | sendMsg(msg);
306 | Log.i(TAG, "sendConnect uid:" + client.getUid());
307 | }
308 |
309 | @Override
310 | public void onConnect() {
311 | sendConnect();
312 | }
313 |
314 | @Override
315 | public void onDisconnect() {
316 | sendConnect();
317 | }
318 |
319 | public static void setToken(String token) {
320 | if (token == null || token.isEmpty()) {
321 | Log.e(TAG, "token null return");
322 | return;
323 | }
324 | if (notificationProvider != null && client != null) {
325 | Log.i(TAG, "setToken " + token);
326 | notificationProvider.setToken(token);
327 | client.sendTokenToServer();
328 | } else {
329 | Log.i(TAG, "setToken from main process");
330 | RemoteClient.setToken(token);
331 | }
332 | }
333 |
334 | public static void sendNotificationClick(String id) {
335 | if (client != null) {
336 | Log.i(TAG, "sendNotificationClick " + id);
337 | client.sendNotificationClick(id);
338 | } else {
339 | Log.i(TAG, "sendNotificationClick from main process");
340 | RemoteClient.sendNotificationClick(id);
341 | }
342 | }
343 |
344 | public void sendMsg(Message msg) {
345 | if (bound && remoteClient != null) {
346 | try {
347 | remoteClient.send(msg);
348 | Log.d(TAG, "sendMsg message");
349 | } catch (Exception e) {
350 | Log.e(TAG, "sendMsg error!", e);
351 | }
352 | } else {
353 | Log.d(TAG, "sendMsg not bound");
354 | }
355 | }
356 | }
357 |
--------------------------------------------------------------------------------
/android-push-sdk/src/main/java/com/yy/httpproxy/service/DefaultDnsHandler.java:
--------------------------------------------------------------------------------
1 | package com.yy.httpproxy.service;
2 |
3 | import android.content.Context;
4 |
5 | /**
6 | * Created by huangzhilong on 2016/8/18.
7 | */
8 | public class DefaultDnsHandler implements DnsHandler {
9 |
10 | @Override
11 | public void init(Context context) {
12 |
13 | }
14 |
15 | @Override
16 | public String handlerDns(String host) {
17 | return host;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/android-push-sdk/src/main/java/com/yy/httpproxy/service/DefaultNotificationHandler.java:
--------------------------------------------------------------------------------
1 | package com.yy.httpproxy.service;
2 |
3 | import android.app.Notification;
4 | import android.app.NotificationManager;
5 | import android.app.PendingIntent;
6 | import android.content.Context;
7 | import android.content.Intent;
8 | import android.support.v4.app.NotificationCompat;
9 |
10 | /**
11 | * Created by xuduo on 11/6/15.
12 | */
13 |
14 | public class DefaultNotificationHandler implements NotificationHandler {
15 |
16 | public static final String INTENT_TAIL = ".YY_NOTIFICATION";
17 |
18 | @Override
19 | public void handlerNotification(Context context, boolean binded, PushedNotification pushedNotification) {
20 |
21 | showNotification(context, pushedNotification);
22 |
23 | sendArrived(context, pushedNotification);
24 |
25 | }
26 |
27 | public static String getIntentName(Context context) {
28 | return context.getApplicationInfo().packageName + INTENT_TAIL;
29 | }
30 |
31 | protected void sendArrived(Context context, PushedNotification pushedNotification) {
32 | String intentName = getIntentName(context);
33 | Intent arrive = new Intent(intentName);
34 | arrive.putExtra("cmd", ConnectionService.CMD_NOTIFICATION_ARRIVED);
35 | arrive.putExtra("id", pushedNotification.id);
36 | arrive.putExtra("title", pushedNotification.title);
37 | arrive.putExtra("message", pushedNotification.message);
38 | arrive.putExtra("payload", pushedNotification.payload);
39 | context.sendBroadcast(arrive);
40 | }
41 |
42 | protected void showNotification(Context context, PushedNotification pushedNotification) {
43 | String intentName = getIntentName(context);
44 | Intent pushIntent = new Intent(intentName);
45 | pushIntent.putExtra("cmd", ConnectionService.CMD_NOTIFICATION_CLICKED);
46 | pushIntent.putExtra("id", pushedNotification.id);
47 | pushIntent.putExtra("title", pushedNotification.title);
48 | pushIntent.putExtra("message", pushedNotification.message);
49 | pushIntent.putExtra("payload", pushedNotification.payload);
50 | PendingIntent pendingIntent = PendingIntent.getBroadcast(context, pushedNotification.id.hashCode(), pushIntent, PendingIntent.FLAG_ONE_SHOT);
51 |
52 |
53 | NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
54 | NotificationCompat.Builder mBuilder =
55 | new NotificationCompat.Builder(context)
56 | .setAutoCancel(true)
57 | .setContentIntent(pendingIntent)
58 | .setSmallIcon(context.getApplicationInfo().icon)
59 | .setContentTitle(pushedNotification.title)
60 | .setContentText(pushedNotification.message).setPriority(NotificationCompat.PRIORITY_HIGH);
61 | Notification notification = mBuilder.build();
62 | nm.notify(pushedNotification.id.hashCode(), notification);
63 | }
64 |
65 | }
66 |
--------------------------------------------------------------------------------
/android-push-sdk/src/main/java/com/yy/httpproxy/service/DelegateToClientNotificationHandler.java:
--------------------------------------------------------------------------------
1 | package com.yy.httpproxy.service;
2 |
3 | import android.content.Context;
4 |
5 | /**
6 | * Created by xuduo on 11/6/15.
7 | */
8 |
9 | public class DelegateToClientNotificationHandler extends DefaultNotificationHandler {
10 |
11 | @Override
12 | public void handlerNotification(Context context, boolean binded, PushedNotification pushedNotification) {
13 | if (!binded) {
14 | showNotification(context, pushedNotification);
15 | } else {
16 | sendArrived(context, pushedNotification);
17 | }
18 | }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/android-push-sdk/src/main/java/com/yy/httpproxy/service/DnsHandler.java:
--------------------------------------------------------------------------------
1 | package com.yy.httpproxy.service;
2 |
3 |
4 | import android.content.Context;
5 |
6 | /**
7 | * Created by huangzhilong on 2016/8/18.
8 | */
9 | public interface DnsHandler {
10 |
11 | void init(Context context);
12 |
13 | String handlerDns(String host);
14 | }
15 |
--------------------------------------------------------------------------------
/android-push-sdk/src/main/java/com/yy/httpproxy/service/DummyNotificationHandler.java:
--------------------------------------------------------------------------------
1 | package com.yy.httpproxy.service;
2 |
3 | import android.content.Context;
4 |
5 | /**
6 | * Created by xuduo on 11/6/15.
7 | */
8 |
9 | public class DummyNotificationHandler implements NotificationHandler {
10 |
11 | @Override
12 | public void handlerNotification(Context context, boolean binded, PushedNotification pushedNotification) {
13 |
14 |
15 | }
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/android-push-sdk/src/main/java/com/yy/httpproxy/service/DummyService.java:
--------------------------------------------------------------------------------
1 | package com.yy.httpproxy.service;
2 |
3 | import android.app.Service;
4 | import android.content.Intent;
5 | import android.os.IBinder;
6 |
7 | import com.yy.httpproxy.util.Log;
8 |
9 | public class DummyService extends Service {
10 |
11 | private final String TAG = "DummyService";
12 |
13 | @Override
14 | public void onCreate() {
15 | super.onCreate();
16 | Log.i(TAG, "DummyService onCreate");
17 | }
18 |
19 | @Override
20 | public IBinder onBind(Intent intent) {
21 | return null;
22 | }
23 |
24 | @Override
25 | public int onStartCommand(Intent intent, int flags, int startId) {
26 | Log.d(TAG, "onStartCommand");
27 | return Service.START_STICKY;
28 | }
29 |
30 | @Override
31 | public void onDestroy() {
32 | super.onDestroy();
33 | Log.i(TAG, "DummyService onDestroy");
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/android-push-sdk/src/main/java/com/yy/httpproxy/service/ForegroundService.java:
--------------------------------------------------------------------------------
1 | package com.yy.httpproxy.service;
2 |
3 | import android.app.Notification;
4 | import android.app.Service;
5 | import android.content.Context;
6 | import android.content.Intent;
7 | import android.os.Build;
8 | import android.os.IBinder;
9 | import android.support.v4.app.NotificationCompat;
10 |
11 | import com.yy.httpproxy.util.Log;
12 |
13 | public class ForegroundService extends Service {
14 |
15 | private final String TAG = "ForegroundService";
16 |
17 | public static ConnectionService instance;
18 |
19 | @Override
20 | public void onCreate() {
21 | super.onCreate();
22 | try {
23 | if (Build.VERSION.SDK_INT < 26) {
24 | NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
25 | builder.setPriority(Notification.PRIORITY_MIN);
26 | startForeground(12345, builder.build());
27 | beginForeground();
28 | }
29 | } catch (Exception e) {
30 | Log.e(TAG, "startForeground error");
31 | }
32 | stopSelf();
33 | Log.i(TAG, "FakeService onCreate");
34 | }
35 |
36 | @Override
37 | public IBinder onBind(Intent intent) {
38 | return null;
39 | }
40 |
41 | @Override
42 | public int onStartCommand(Intent intent, int flags, int startId) {
43 | Log.d(TAG, "onStartCommand");
44 | return Service.START_STICKY;
45 | }
46 |
47 | @Override
48 | public void onDestroy() {
49 | super.onDestroy();
50 | Log.i(TAG, "FakeService onDestroy");
51 | stopForeground(true);
52 | }
53 |
54 | public void beginForeground() {
55 | if (instance != null) {
56 | if (Build.VERSION.SDK_INT < 26) {
57 | NotificationCompat.Builder builder = new NotificationCompat.Builder(instance);
58 | builder.setPriority(Notification.PRIORITY_MIN);
59 | instance.startForeground(12345, builder.build());
60 | }
61 | }
62 | }
63 |
64 | }
65 |
--------------------------------------------------------------------------------
/android-push-sdk/src/main/java/com/yy/httpproxy/service/NotificationHandler.java:
--------------------------------------------------------------------------------
1 | package com.yy.httpproxy.service;
2 |
3 | import android.content.Context;
4 |
5 | /**
6 | * Created by xuduo on 11/6/15.
7 | */
8 | public interface NotificationHandler {
9 |
10 | /**
11 | *
12 | * @param context context
13 | * @param binded UI进程 是否存活
14 | * @param notification 服务器下发的notification
15 | */
16 | void handlerNotification(Context context, boolean binded, PushedNotification notification);
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/android-push-sdk/src/main/java/com/yy/httpproxy/service/NotificationReceiver.java:
--------------------------------------------------------------------------------
1 | package com.yy.httpproxy.service;
2 |
3 | import android.content.BroadcastReceiver;
4 | import android.content.Context;
5 | import android.content.Intent;
6 |
7 | /**
8 | * Created by xuduo on 11/6/15.
9 | */
10 | public abstract class NotificationReceiver extends BroadcastReceiver {
11 | @Override
12 | public void onReceive(Context context, Intent intent) {
13 | if (intent.getIntExtra("cmd", -1) == ConnectionService.CMD_NOTIFICATION_CLICKED) {
14 | String id = intent.getStringExtra("id");
15 | ConnectionService.sendNotificationClick(id);
16 | PushedNotification notification = new PushedNotification(id, intent.getStringExtra("title"), intent.getStringExtra("message"), intent.getStringExtra("payload"));
17 | onNotificationClicked(context, notification);
18 | } else if (intent.getIntExtra("cmd", -1) == ConnectionService.CMD_NOTIFICATION_ARRIVED) {
19 | String id = intent.getStringExtra("id");
20 | PushedNotification notification = new PushedNotification(id, intent.getStringExtra("title"), intent.getStringExtra("message"), intent.getStringExtra("payload"));
21 | onNotificationArrived(context, notification);
22 | }
23 | }
24 |
25 | public abstract void onNotificationClicked(Context context, PushedNotification notification);
26 |
27 | public abstract void onNotificationArrived(Context context, PushedNotification notification);
28 | }
29 |
--------------------------------------------------------------------------------
/android-push-sdk/src/main/java/com/yy/httpproxy/service/PushedNotification.java:
--------------------------------------------------------------------------------
1 | package com.yy.httpproxy.service;
2 |
3 | import org.json.JSONArray;
4 | import org.json.JSONException;
5 | import org.json.JSONObject;
6 |
7 | import java.util.ArrayList;
8 | import java.util.HashMap;
9 | import java.util.Iterator;
10 | import java.util.List;
11 | import java.util.Map;
12 |
13 | /**
14 | * Created by xuduo on 11/6/15.
15 | */
16 | public class PushedNotification {
17 |
18 | public String title;
19 | public String message;
20 | public String id;
21 | public String payload;
22 |
23 | public PushedNotification(String id, JSONObject object) {
24 | this.id = id;
25 | title = object.optString("title", "");
26 | message = object.optString("message", "");
27 | payload = object.optString("payload", "");
28 | }
29 |
30 | public PushedNotification(String id, String title, String message, String payload) {
31 | this.id = id;
32 | this.title = title;
33 | this.message = message;
34 | this.payload = payload;
35 | }
36 |
37 | @Override
38 | public int hashCode() {
39 | return this.id.hashCode() + this.message.hashCode() + this.title.hashCode() + this.payload.hashCode();
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/android-push-sdk/src/main/java/com/yy/httpproxy/socketio/RemoteClient.java:
--------------------------------------------------------------------------------
1 | package com.yy.httpproxy.socketio;
2 |
3 | import android.content.ComponentName;
4 | import android.content.Context;
5 | import android.content.Intent;
6 | import android.content.ServiceConnection;
7 | import android.os.Bundle;
8 | import android.os.Handler;
9 | import android.os.IBinder;
10 | import android.os.Looper;
11 | import android.os.Message;
12 | import android.os.Messenger;
13 |
14 | import com.yy.httpproxy.ProxyClient;
15 | import com.yy.httpproxy.requester.RequestInfo;
16 | import com.yy.httpproxy.service.ConnectionService;
17 | import com.yy.httpproxy.service.DummyService;
18 | import com.yy.httpproxy.service.PushedNotification;
19 | import com.yy.httpproxy.subscribe.PushSubscriber;
20 | import com.yy.httpproxy.util.Log;
21 |
22 | import org.json.JSONObject;
23 |
24 | import java.util.ArrayList;
25 | import java.util.HashMap;
26 | import java.util.Map;
27 | import java.util.Set;
28 |
29 |
30 | public class RemoteClient implements PushSubscriber {
31 |
32 | private static final String TAG = "RemoteClient";
33 | public static final int CMD_SUBSCRIBE_BROADCAST = 1;
34 | public static final int CMD_REQUEST = 3;
35 | public static final int CMD_REGISTER_CLIENT = 4;
36 | public static final int CMD_UNSUBSCRIBE_BROADCAST = 5;
37 | public static final int CMD_STATS = 6;
38 | public static final int CMD_UNBIND_UID = 7;
39 | public static final int CMD_SET_TOKEN = 8;
40 | public static final int CMD_BIND_UID = 13;
41 | public static final int CMD_NOTIFICATION_CLICK = 14;
42 | public static final int CMD_SET_TAG = 15;
43 | public static final int CMD_NOTIFICATION_RECEIVE = 16;
44 | private Map topics = new HashMap<>();
45 | private ProxyClient proxyClient;
46 | private Messenger mService;
47 | private boolean mBound;
48 | private Messenger messenger = null;
49 | private Context context;
50 | private boolean connected = false;
51 | private static RemoteClient instance;
52 | private Handler handler = new Handler(Looper.getMainLooper());
53 | private String host;
54 | private String pushId;
55 | private String notificationHandler;
56 | private String dnsHandler;
57 | private String logger;
58 |
59 | public RemoteClient(Context context, String host, String pushId, String notificationHandler, String logger, String dnsHandler) {
60 | this.context = context;
61 | this.host = host;
62 | this.pushId = pushId;
63 | this.notificationHandler = notificationHandler;
64 | this.logger = logger;
65 | this.dnsHandler = dnsHandler;
66 | startServices();
67 | }
68 |
69 | public void unsubscribeBroadcast(final String topic) {
70 | runInMainThread(new Runnable() {
71 | @Override
72 | public void run() {
73 | Message msg = Message.obtain(null, CMD_UNSUBSCRIBE_BROADCAST, 0, 0);
74 | Bundle bundle = new Bundle();
75 | bundle.putSerializable("topic", topic);
76 | msg.setData(bundle);
77 | sendMsg(msg);
78 | topics.remove(topic);
79 | }
80 | });
81 | }
82 |
83 | public boolean isConnected() {
84 | return connected;
85 | }
86 |
87 | public void reportStats(String path, int successCount, int errorCount, int latency) {
88 | Message msg = Message.obtain(null, CMD_STATS, 0, 0);
89 | Bundle bundle = new Bundle();
90 | bundle.putString("path", path);
91 | bundle.putInt("successCount", successCount);
92 | bundle.putInt("errorCount", errorCount);
93 | bundle.putInt("latency", latency);
94 | msg.setData(bundle);
95 | sendMsg(msg);
96 | }
97 |
98 | public void exit() {
99 | context.stopService(new Intent(context, ConnectionService.class));
100 | context.unbindService(mConnection);
101 | }
102 |
103 | public void bindUid(HashMap data) {
104 | Message msg = Message.obtain(null, CMD_BIND_UID, 0, 0);
105 | Bundle bundle = new Bundle();
106 | bundle.putSerializable("data", data);
107 | msg.setData(bundle);
108 | sendMsg(msg);
109 | }
110 |
111 | public static void sendNotificationClick(String id) {
112 | if (instance != null) {
113 | Message msg = Message.obtain(null, CMD_NOTIFICATION_CLICK, 0, 0);
114 | Bundle bundle = new Bundle();
115 | bundle.putString("id", id);
116 | msg.setData(bundle);
117 | instance.sendMsg(msg);
118 | }
119 | }
120 |
121 | public static void sendNotificationReceive(String notification) {
122 | if (instance != null) {
123 | Message msg = Message.obtain(null, CMD_NOTIFICATION_RECEIVE, 0, 0);
124 | Bundle bundle = new Bundle();
125 | bundle.putString("notification", notification);
126 | msg.setData(bundle);
127 | instance.sendMsg(msg);
128 | }
129 | }
130 |
131 | public void setTag(Set tags) {
132 | Message msg = Message.obtain(null, CMD_SET_TAG, 0, 0);
133 | Bundle bundle = new Bundle();
134 | bundle.putStringArrayList("tags", new ArrayList(tags));
135 | msg.setData(bundle);
136 | sendMsg(msg);
137 | }
138 |
139 | private class IncomingHandler extends Handler {
140 | @Override
141 | public void handleMessage(Message msg) {
142 | int cmd = msg.what;
143 | Bundle bundle = msg.getData();
144 | if (cmd == ConnectionService.CMD_PUSH) {
145 | String data = bundle.getString("data");
146 | Log.d(TAG, "push data: " + data);
147 | proxyClient.onPush(data);
148 | } else if (cmd == ConnectionService.CMD_CONNECTED && connected == false) {
149 | connected = true;
150 | if (proxyClient.getConfig().getConnectCallback() != null) {
151 | String uid = null;
152 | if (bundle != null) {
153 | uid = bundle.getString("uid", "");
154 | }
155 | proxyClient.getConfig().getConnectCallback().onConnect(uid);
156 | }
157 | } else if (cmd == ConnectionService.CMD_DISCONNECT && connected == true) {
158 | connected = false;
159 | if (proxyClient.getConfig().getConnectCallback() != null) {
160 | proxyClient.getConfig().getConnectCallback().onDisconnect();
161 | }
162 | }
163 | }
164 | }
165 |
166 | private void resubscribeTopics() {
167 | for (Map.Entry topic : topics.entrySet()) {
168 | doSubscribe(topic.getKey(), topic.getValue());
169 | }
170 | }
171 |
172 | private ServiceConnection mConnection = new ServiceConnection() {
173 | public void onServiceConnected(ComponentName className, IBinder service) {
174 | // service using a Messenger, so here we get a client-side
175 | // representation of that from the raw IBinder object.
176 | Log.i(TAG, "onServiceConnected");
177 | mService = new Messenger(service);
178 | mBound = true;
179 | Message msg = Message.obtain(null, CMD_REGISTER_CLIENT, 0, 0);
180 | msg.replyTo = messenger;
181 | sendMsg(msg);
182 | instance = RemoteClient.this;
183 | resubscribeTopics();
184 | }
185 |
186 | public void onServiceDisconnected(ComponentName className) {
187 | // This is called when the connection with the service has been
188 | // unexpectedly disconnected -- that is, its process crashed.
189 | mService = null;
190 | mBound = false;
191 | Log.i(TAG, "onServiceDisconnected");
192 | startServices();
193 | }
194 | };
195 |
196 | private void startServices() {
197 | handler.post(startServiceRunnable);
198 | }
199 |
200 | private Runnable startServiceRunnable = new Runnable() {
201 | @Override
202 | public void run() {
203 | if (messenger == null) {
204 | messenger = new Messenger(new IncomingHandler());
205 | }
206 | if (!mBound) {
207 | try {
208 | startRemoteService();
209 | startDummyService();
210 | } catch (Exception e) {
211 | Log.e(TAG, "start service exception, will try restart", e);
212 | }
213 | handler.postDelayed(startServiceRunnable, 5000L);
214 | }
215 | }
216 | };
217 |
218 | private void startDummyService() {
219 | Intent intent = new Intent(context, DummyService.class);
220 | context.startService(intent);
221 | }
222 |
223 | private void startRemoteService() {
224 | Intent intent = new Intent(context, ConnectionService.class);
225 | intent.putExtra("host", host);
226 | intent.putExtra("pushId", pushId);
227 | intent.putExtra("logger", logger);
228 | if (notificationHandler != null) {
229 | intent.putExtra("notificationHandler", notificationHandler);
230 | }
231 | if (dnsHandler != null) {
232 | intent.putExtra("dnsHandler", dnsHandler);
233 | }
234 | context.startService(intent);
235 | Intent bindIntent = new Intent(context, ConnectionService.class);
236 | context.bindService(bindIntent, mConnection, Context.BIND_AUTO_CREATE);
237 | }
238 |
239 | private void sendMsg(Message msg) {
240 | try {
241 | if (mBound) {
242 | mService.send(msg);
243 | }
244 | } catch (Exception e) {
245 | Log.e(TAG, "sendMsg error!", e);
246 | }
247 | }
248 |
249 | private void runInMainThread(Runnable runnable) {
250 | if (Looper.myLooper() == Looper.getMainLooper()) {
251 | runnable.run();
252 | } else {
253 | handler.post(runnable);
254 | }
255 | }
256 |
257 | public void request(RequestInfo requestInfo) {
258 | Message msg = Message.obtain(null, CMD_REQUEST, 0, 0);
259 | Bundle bundle = new Bundle();
260 | bundle.putSerializable("requestInfo", requestInfo);
261 | msg.setData(bundle);
262 | sendMsg(msg);
263 | }
264 |
265 | public void unbindUid() {
266 | Message msg = Message.obtain(null, CMD_UNBIND_UID, 0, 0);
267 | sendMsg(msg);
268 | }
269 |
270 |
271 | @Override
272 | public void subscribeBroadcast(final String topic, final boolean receiveTtlPackets) {
273 | runInMainThread(new Runnable() {
274 | @Override
275 | public void run() {
276 | topics.put(topic, receiveTtlPackets);
277 | doSubscribe(topic, receiveTtlPackets);
278 | }
279 | });
280 | }
281 |
282 | private void doSubscribe(String topic, boolean receiveTtlPackets) {
283 | Message msg = Message.obtain(null, CMD_SUBSCRIBE_BROADCAST, 0, 0);
284 | Bundle bundle = new Bundle();
285 | bundle.putString("topic", topic);
286 | bundle.putBoolean("receiveTtlPackets", receiveTtlPackets);
287 | msg.setData(bundle);
288 | sendMsg(msg);
289 | }
290 |
291 | public void setProxyClient(ProxyClient proxyClient) {
292 | this.proxyClient = proxyClient;
293 | }
294 |
295 | public static void setToken(String token) {
296 | if (instance != null) {
297 | Message msg = Message.obtain(null, CMD_SET_TOKEN, 0, 0);
298 | Bundle bundle = new Bundle();
299 | bundle.putString("token", token);
300 | msg.setData(bundle);
301 | instance.sendMsg(msg);
302 | }
303 | }
304 |
305 | }
306 |
--------------------------------------------------------------------------------
/android-push-sdk/src/main/java/com/yy/httpproxy/stats/Connectivity.java:
--------------------------------------------------------------------------------
1 | package com.yy.httpproxy.stats;
2 |
3 | import com.yy.httpproxy.util.Log;
4 |
5 | import java.util.ArrayList;
6 | import java.util.List;
7 |
8 | public class Connectivity {
9 | private static String TAG = "ConnectivityStats";
10 |
11 | static class ConnectionEvent {
12 | int type = 0;
13 | long timestamp = System.currentTimeMillis();
14 |
15 | ConnectionEvent(int type) {
16 | this.type = type;
17 | }
18 | }
19 |
20 | public static class ConnectionTimes {
21 | long timeConnected;
22 | long timeTotal;
23 | }
24 |
25 | private List events = new ArrayList<>();
26 |
27 | public Connectivity() {
28 | onDisconnect();
29 | }
30 |
31 | public void onConnect() {
32 | Log.d(TAG, "onConnect");
33 | events.add(new ConnectionEvent(1));
34 | }
35 |
36 | public void onDisconnect() {
37 | Log.d(TAG, "onDisconnect");
38 | events.add(new ConnectionEvent(0));
39 | }
40 |
41 | public ConnectionTimes getResult() {
42 | ConnectionEvent latest = events.get(events.size() - 1);
43 | latest = new ConnectionEvent(latest.type);
44 | ConnectionEvent current = latest;
45 | long timeConnected = 0;
46 | long timeTotal = 0;
47 |
48 | for (int i = events.size() - 1; i >= 0; i--) {
49 | ConnectionEvent event = events.get(i);
50 | long span = latest.timestamp - event.timestamp;
51 | if (event.type == 1) {
52 | timeConnected += span;
53 | }
54 | timeTotal += span;
55 | latest = event;
56 | }
57 | events.clear();
58 | events.add(current);
59 |
60 | ConnectionTimes result = new ConnectionTimes();
61 | result.timeConnected = timeConnected / 1000;
62 | result.timeTotal = timeTotal / 1000;
63 | Log.d(TAG, "get connectivity result connected " + result.timeConnected + " total :" + result.timeTotal );
64 | return result;
65 | }
66 |
67 | }
68 |
--------------------------------------------------------------------------------
/android-push-sdk/src/main/java/com/yy/httpproxy/stats/Performance.java:
--------------------------------------------------------------------------------
1 | package com.yy.httpproxy.stats;
2 |
3 | /**
4 | * Created by xuduo on 1/8/16.
5 | */
6 | public class Performance {
7 |
8 | public long successCount;
9 | public long errorCount;
10 | public long totalLatency;
11 | public String path;
12 |
13 | public void addError() {
14 | errorCount++;
15 | }
16 |
17 | public void addSuccess(long latency) {
18 | successCount++;
19 | this.totalLatency += latency;
20 | }
21 |
22 | @Override
23 | public String toString() {
24 | return "Performance{" +
25 | "successCount=" + successCount +
26 | ", errorCount=" + errorCount +
27 | ", totalLatency=" + totalLatency +
28 | '}';
29 | }
30 |
31 | public void add(int successCount, int errorCount, int latency) {
32 | this.successCount += successCount;
33 | this.errorCount += errorCount;
34 | this.totalLatency += latency;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/android-push-sdk/src/main/java/com/yy/httpproxy/stats/Stats.java:
--------------------------------------------------------------------------------
1 | package com.yy.httpproxy.stats;
2 |
3 |
4 | import org.json.JSONArray;
5 | import org.json.JSONException;
6 | import org.json.JSONObject;
7 |
8 | import java.util.HashMap;
9 | import java.util.Map;
10 |
11 | /**
12 | * Created by xuduo on 1/8/16.
13 | */
14 | public class Stats {
15 |
16 | private Map performances = new HashMap<>();
17 | private Connectivity connectivity = new Connectivity();
18 |
19 | public void reportError(String path) {
20 | Performance performance = getPerformance(path);
21 | performance.addError();
22 | }
23 |
24 | private Performance getPerformance(String path) {
25 | Performance performance = performances.get(path);
26 | if (performance == null) {
27 | performance = new Performance();
28 | performance.path = path;
29 | performances.put(path, performance);
30 | }
31 | return performance;
32 | }
33 |
34 | public void reportStats(String path, int successCount, int errorCount, int latency) {
35 | Performance performance = getPerformance(path);
36 | performance.add(successCount, errorCount, latency);
37 | }
38 |
39 | public void reportSuccess(String path, long timestamp) {
40 | Performance performance = getPerformance(path);
41 | performance.addSuccess(System.currentTimeMillis() - timestamp);
42 | }
43 |
44 | public void onConnect(){
45 | connectivity.onConnect();
46 | }
47 |
48 | public void onDisconnect(){
49 | connectivity.onDisconnect();
50 | }
51 |
52 | public JSONArray getRequestJsonArray() throws JSONException {
53 | JSONArray array = new JSONArray();
54 | for (Performance performance : performances.values()) {
55 | JSONObject object = new JSONObject();
56 | object.put("path", performance.path);
57 | object.put("successCount", performance.successCount);
58 | object.put("totalCount", performance.errorCount + performance.successCount);
59 | object.put("totalLatency", performance.totalLatency);
60 | array.put(object);
61 | }
62 | performances.clear();
63 | Connectivity.ConnectionTimes connectionTimes = connectivity.getResult();
64 | if(connectionTimes.timeTotal > 10){
65 | JSONObject object = new JSONObject();
66 | object.put("path", "Connectivity");
67 | object.put("successCount", connectionTimes.timeConnected);
68 | object.put("totalCount", connectionTimes.timeTotal);
69 | array.put(object);
70 | }
71 | return array;
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/android-push-sdk/src/main/java/com/yy/httpproxy/subscribe/CachedSharedPreference.java:
--------------------------------------------------------------------------------
1 | package com.yy.httpproxy.subscribe;
2 |
3 | import android.content.Context;
4 | import android.content.SharedPreferences;
5 | import android.os.Build;
6 |
7 | import java.util.HashMap;
8 | import java.util.HashSet;
9 | import java.util.Map;
10 | import java.util.Set;
11 |
12 |
13 | public class CachedSharedPreference {
14 |
15 | private SharedPreferences preferences;
16 | private Map cache = new HashMap<>();
17 |
18 | public CachedSharedPreference(Context context) {
19 | preferences = context.getSharedPreferences("SharedPreferencePushGenerator", Context.MODE_PRIVATE);
20 | }
21 |
22 | public void save(String key, String value) {
23 | cache.put(key, value);
24 | SharedPreferences.Editor editor = preferences.edit().putString(key, value);
25 | if (Build.VERSION.SDK_INT > 8) {
26 | editor.apply();
27 | } else {
28 | editor.commit();
29 | }
30 | }
31 |
32 | public Set getStringSet(String key) {
33 | return new HashSet<>(preferences.getStringSet(key, new HashSet()));
34 | }
35 |
36 | public void addStringSet(String key, String value) {
37 | Set values = getStringSet(key);
38 | values.add(value);
39 | preferences.edit().putStringSet(key, values).commit();
40 | }
41 |
42 | public String get(String key) {
43 | String value = cache.get(key);
44 | if (value == null) {
45 | value = preferences.getString(key, null);
46 | }
47 | return value;
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/android-push-sdk/src/main/java/com/yy/httpproxy/subscribe/ConnectCallback.java:
--------------------------------------------------------------------------------
1 | package com.yy.httpproxy.subscribe;
2 |
3 | import java.util.Set;
4 |
5 | /**
6 | * Created by xuduo on 10/20/15.
7 | */
8 | public interface ConnectCallback {
9 |
10 | /**
11 | * @param uid 连接push-server后,在服务器绑定的uid
12 | */
13 | void onConnect(String uid);
14 |
15 | void onDisconnect();
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/android-push-sdk/src/main/java/com/yy/httpproxy/subscribe/PushCallback.java:
--------------------------------------------------------------------------------
1 | package com.yy.httpproxy.subscribe;
2 |
3 | /**
4 | * Created by xuduo on 10/20/15.
5 | */
6 | public interface PushCallback {
7 |
8 | /**
9 | * @param data 服务器push下来的json字符串
10 | */
11 | void onPush(String data);
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/android-push-sdk/src/main/java/com/yy/httpproxy/subscribe/PushSubscriber.java:
--------------------------------------------------------------------------------
1 | package com.yy.httpproxy.subscribe;
2 |
3 | /**
4 | * Created by xuduo on 10/20/15.
5 | */
6 | public interface PushSubscriber {
7 |
8 | void subscribeBroadcast(String topic, boolean receiveTtlPackets);
9 |
10 | }
11 |
--------------------------------------------------------------------------------
/android-push-sdk/src/main/java/com/yy/httpproxy/subscribe/RandomPushIdGenerator.java:
--------------------------------------------------------------------------------
1 | package com.yy.httpproxy.subscribe;
2 |
3 | import android.content.Context;
4 |
5 | import com.yy.httpproxy.util.Log;
6 |
7 | import java.io.BufferedReader;
8 | import java.io.File;
9 | import java.io.FileInputStream;
10 | import java.io.FileOutputStream;
11 | import java.io.IOException;
12 | import java.io.InputStream;
13 | import java.io.InputStreamReader;
14 | import java.io.OutputStreamWriter;
15 | import java.math.BigInteger;
16 | import java.security.SecureRandom;
17 |
18 | /**
19 | * Created by xuduo on 10/20/15.
20 | */
21 | public class RandomPushIdGenerator {
22 |
23 | private static final String TAG = "RandomPushIdGenerator";
24 |
25 | public String generatePushId(Context context) {
26 | CachedSharedPreference cachedSharedPreference = new CachedSharedPreference(context);
27 | String pushId = cachedSharedPreference.get("pushId");
28 | if (pushId != null) {
29 | pushId = pushId.trim();
30 | }
31 | Log.i(TAG, "read pushId from sharePref " + pushId);
32 | if (pushId == null || pushId.isEmpty()) {
33 | File pushIdFile = null;
34 | try {
35 | File root = android.os.Environment.getExternalStorageDirectory();
36 | File dir = new File(root.getAbsolutePath() + "/" + context.getPackageName());
37 | dir.mkdirs();
38 | pushIdFile = new File(dir, "pushId");
39 | pushId = getStringFromFile(pushIdFile);
40 | if (pushId != null) {
41 | pushId = pushId.trim();
42 | }
43 | Log.i(TAG, "read pushId from file " + pushId);
44 | cachedSharedPreference.save("pushId", pushId);
45 | } catch (Exception e) {
46 | Log.e(TAG, "generatePushId exception ", e);
47 | }
48 | if (pushId == null || pushId.isEmpty()) {
49 | pushId = new BigInteger(130, new SecureRandom()).toString(32);
50 | cachedSharedPreference.save("pushId", pushId);
51 | if (pushIdFile != null) {
52 | Log.i(TAG, "write pushId to file " + pushId);
53 | writeToFile(pushId, pushIdFile);
54 | }
55 | }
56 | }
57 | return pushId;
58 | }
59 |
60 | public static String convertStreamToString(InputStream is) throws Exception {
61 | BufferedReader reader = new BufferedReader(new InputStreamReader(is));
62 | StringBuilder sb = new StringBuilder();
63 | String line;
64 | while ((line = reader.readLine()) != null) {
65 | sb.append(line).append("\n");
66 | }
67 | reader.close();
68 | return sb.toString();
69 | }
70 |
71 | public static String getStringFromFile(File file) throws Exception {
72 | if (!file.exists()) {
73 | return null;
74 | }
75 | FileInputStream fin = new FileInputStream(file);
76 | String ret = convertStreamToString(fin);
77 | fin.close();
78 | return ret;
79 | }
80 |
81 |
82 | private void writeToFile(String data, File file) {
83 | try {
84 | OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream(file));
85 | outputStreamWriter.write(data);
86 | outputStreamWriter.close();
87 | } catch (IOException e) {
88 | Log.e("Exception", "File write failed: " + e.toString());
89 | }
90 | }
91 |
92 | }
93 |
--------------------------------------------------------------------------------
/android-push-sdk/src/main/java/com/yy/httpproxy/thirdparty/FirebaseProvider.java:
--------------------------------------------------------------------------------
1 | package com.yy.httpproxy.thirdparty;
2 |
3 | import android.app.Activity;
4 | import android.content.Context;
5 | import android.content.Intent;
6 | import android.os.Bundle;
7 |
8 | import com.google.android.gms.common.GoogleApiAvailability;
9 | import com.google.firebase.FirebaseApp;
10 | import com.google.firebase.iid.FirebaseInstanceId;
11 | import com.google.firebase.messaging.FirebaseMessaging;
12 | import com.huawei.hms.api.ConnectionResult;
13 | import com.yy.httpproxy.service.ConnectionService;
14 | import com.yy.httpproxy.service.DefaultNotificationHandler;
15 | import com.yy.httpproxy.service.PushedNotification;
16 | import com.yy.httpproxy.util.Log;
17 | import com.yy.httpproxy.util.ServiceCheckUtil;
18 |
19 | import org.json.JSONObject;
20 |
21 | /**
22 | * Created by xuduo on 22/05/2017.
23 | */
24 |
25 | public class FirebaseProvider implements NotificationProvider {
26 |
27 | public final static String TAG = "FirebaseProvider";
28 | private static String token;
29 |
30 | public FirebaseProvider(Context context) {
31 | FirebaseApp.initializeApp(context);
32 | String token = FirebaseInstanceId.getInstance().getToken();
33 | Log.i(TAG, "FCMProvider init " + token);
34 | FirebaseMessaging.getInstance().subscribeToTopic("all");
35 | if (token != null) {
36 | setToken(token);
37 | }
38 |
39 | }
40 |
41 | public static boolean available(Context context) {
42 | try {
43 | boolean available = Class.forName("com.google.firebase.iid.FirebaseInstanceId") != null
44 | && ServiceCheckUtil.isIntentServiceAvailable(context, MyFirebaseInstanceIdService.class) &&
45 | ServiceCheckUtil.isIntentServiceAvailable(context, MyFirebaseMessagingService.class) &&
46 | isGooglePlayServicesAvailable(context);
47 | Log.d(TAG, "available " + available);
48 | return available;
49 | } catch (Throwable e) {
50 | Log.e(TAG, "available ", e);
51 | return false;
52 | }
53 | }
54 |
55 | public static boolean isGooglePlayServicesAvailable(Context context) {
56 | GoogleApiAvailability googleApiAvailability = GoogleApiAvailability.getInstance();
57 | int resultCode = googleApiAvailability.isGooglePlayServicesAvailable(context);
58 | boolean result = resultCode == ConnectionResult.SUCCESS;
59 | Log.d(TAG, "isGooglePlayServicesAvailable " + result);
60 | return true;
61 | }
62 |
63 |
64 | public static boolean handleLauncher(Activity activity) {
65 | Bundle bundle = activity.getIntent().getExtras();
66 | if (bundle != null) {
67 | String payload = bundle.getString("payload");
68 | if (payload != null) {
69 | try {
70 |
71 | JSONObject obj = new JSONObject(payload);
72 | PushedNotification pushedNotification = new PushedNotification(obj.getString("id"), obj);
73 |
74 | Intent clickIntent = new Intent(DefaultNotificationHandler.getIntentName(activity));
75 | clickIntent.putExtra("cmd", ConnectionService.CMD_NOTIFICATION_CLICKED);
76 | clickIntent.putExtra("id", pushedNotification.id);
77 | clickIntent.putExtra("title", pushedNotification.title);
78 | clickIntent.putExtra("message", pushedNotification.message);
79 | clickIntent.putExtra("payload", pushedNotification.payload);
80 | activity.sendBroadcast(clickIntent);
81 |
82 | Log.d("Message ", obj.getString("id"));
83 | return true;
84 |
85 | } catch (Throwable t) {
86 | Log.e("My App", "Could not parse malformed JSON: \"" + payload + "\"");
87 | }
88 | }
89 | }
90 | return false;
91 | }
92 |
93 | @Override
94 | public String getToken() {
95 | return token;
96 | }
97 |
98 | @Override
99 | public String getType() {
100 | return "fcm";
101 | }
102 |
103 | @Override
104 | public void setToken(String token) {
105 | this.token = token;
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/android-push-sdk/src/main/java/com/yy/httpproxy/thirdparty/HuaweiCallback.java:
--------------------------------------------------------------------------------
1 | package com.yy.httpproxy.thirdparty;
2 |
3 | import android.content.Context;
4 |
5 | import com.huawei.hms.api.ConnectionResult;
6 | import com.huawei.hms.api.HuaweiApiClient;
7 | import com.huawei.hms.support.api.client.PendingResult;
8 | import com.huawei.hms.support.api.client.ResultCallback;
9 | import com.huawei.hms.support.api.push.HuaweiPush;
10 | import com.huawei.hms.support.api.push.TokenResult;
11 | import com.yy.httpproxy.util.Log;
12 |
13 | /**
14 | * Created by Administrator on 2016/4/29.
15 | */
16 | public class HuaweiCallback implements HuaweiApiClient.ConnectionCallbacks, HuaweiApiClient.OnConnectionFailedListener {
17 |
18 | public final static String TAG = "HuaweiProvider";
19 | private HuaweiApiClient client;
20 |
21 | public HuaweiCallback(Context context) {
22 | Log.i("HuaweiProvider", "init");
23 | client = new HuaweiApiClient.Builder(context)
24 | .addApi(HuaweiPush.PUSH_API)
25 | .addConnectionCallbacks(this)
26 | .addOnConnectionFailedListener(this)
27 | .build();
28 |
29 | client.connect();
30 | }
31 |
32 | private void getTokenAsync() {
33 |
34 | if (!client.isConnected()) {
35 |
36 | Log.i(TAG, "获取token失败,原因:HuaweiApiClient未连接");
37 |
38 | client.connect();
39 |
40 | return;
41 |
42 | }
43 |
44 |
45 | Log.i(TAG, "异步接口获取push token");
46 |
47 | PendingResult tokenResult = HuaweiPush.HuaweiPushApi.getToken(client);
48 |
49 | tokenResult.setResultCallback(new ResultCallback() {
50 |
51 | @Override
52 |
53 | public void onResult(TokenResult result) {
54 | Log.i(TAG, "TokenResult " + result.getTokenRes().getToken());
55 | }
56 |
57 | });
58 |
59 | }
60 |
61 | @Override
62 | public void onConnected() {
63 | getTokenAsync();
64 | }
65 |
66 | @Override
67 | public void onConnectionSuspended(int i) {
68 | Log.e(TAG, "onConnectionSuspended " + i);
69 | }
70 |
71 | @Override
72 | public void onConnectionFailed(ConnectionResult connectionResult) {
73 | Log.e(TAG, "onConnectionFailed " + connectionResult.getErrorCode());
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/android-push-sdk/src/main/java/com/yy/httpproxy/thirdparty/HuaweiProvider.java:
--------------------------------------------------------------------------------
1 | package com.yy.httpproxy.thirdparty;
2 |
3 | import android.content.Context;
4 | import android.content.pm.PackageInfo;
5 | import android.content.pm.PackageManager;
6 |
7 | import com.yy.httpproxy.util.Log;
8 | import com.yy.httpproxy.util.ServiceCheckUtil;
9 | import com.yy.httpproxy.util.Version;
10 |
11 | import java.lang.reflect.Method;
12 |
13 | /**
14 | * Created by Administrator on 2016/4/29.
15 | */
16 | public class HuaweiProvider implements NotificationProvider {
17 |
18 | public final static String TAG = "HuaweiProvider";
19 | private String token;
20 |
21 | public HuaweiProvider(Context context) {
22 | Log.i("HuaweiProvider", "init");
23 | HuaweiCallback callback = new HuaweiCallback(context);
24 | }
25 |
26 |
27 | public static boolean available(Context context) {
28 | try {
29 | return Class.forName("com.huawei.hms.update.provider.UpdateProvider") != null
30 | && ServiceCheckUtil.isBroadcastReceiverAvailable(context, HuaweiReceiver.class) && isHmsAvailable(context) && EMUIValid();
31 | } catch (Throwable e) {
32 | Log.e(TAG, "available ", e);
33 | return false;
34 | }
35 | }
36 |
37 | public static boolean EMUIValid() {
38 | try {
39 | Class> classType = Class.forName("android.os.SystemProperties");
40 | Method getMethod = classType.getDeclaredMethod("get", new Class>[]{String.class});
41 | String buildVersion = (String) getMethod.invoke(classType, new Object[]{"ro.build.version.emui"});
42 | buildVersion = buildVersion.replaceAll("EmotionUI_", "");
43 | Version ver = new Version(buildVersion);
44 | Log.i(TAG, "EMUI " + buildVersion);
45 | return ver.compareTo(new Version("5.0")) >= 0; // 5.0以下emui 有各种问题
46 | } catch (Exception e) {
47 | Log.e(TAG, "getEMUI ", e);
48 | return false;
49 | }
50 | }
51 |
52 | private static boolean isHmsAvailable(Context context) {
53 |
54 | PackageManager pm = context.getPackageManager();
55 |
56 | try {
57 |
58 | PackageInfo pi = pm.getPackageInfo("com.huawei.hwid", 0);
59 |
60 | if (pi != null) {
61 |
62 | Log.i(TAG, "com.huawei.hwid code " + pi.versionCode + " ,version " + pi.versionName);
63 | return pi.versionCode >= 241300;
64 | }
65 |
66 | } catch (Exception e) {
67 |
68 | Log.e(TAG, "isHmsAvailable ", e);
69 |
70 | }
71 | return false;
72 | }
73 |
74 | @Override
75 | public String getToken() {
76 | return token;
77 | }
78 |
79 | @Override
80 | public String getType() {
81 | return "huawei";
82 | }
83 |
84 | @Override
85 | public void setToken(String token) {
86 | this.token = token;
87 | }
88 |
89 | }
90 |
--------------------------------------------------------------------------------
/android-push-sdk/src/main/java/com/yy/httpproxy/thirdparty/HuaweiReceiver.java:
--------------------------------------------------------------------------------
1 | package com.yy.httpproxy.thirdparty;
2 |
3 | import android.app.NotificationManager;
4 | import android.content.BroadcastReceiver;
5 | import android.content.Context;
6 | import android.content.Intent;
7 | import android.os.Bundle;
8 |
9 | import com.huawei.hms.support.api.push.PushReceiver;
10 | import com.yy.httpproxy.service.ConnectionService;
11 | import com.yy.httpproxy.service.DefaultNotificationHandler;
12 | import com.yy.httpproxy.service.PushedNotification;
13 | import com.yy.httpproxy.util.Log;
14 |
15 | import org.json.JSONArray;
16 |
17 | /**
18 | * Created by Administrator on 2016/4/29.
19 | */
20 | public class HuaweiReceiver extends PushReceiver {
21 |
22 | private static final String TAG = "HuaweiReceiver";
23 |
24 | public void onToken(Context context, String token, Bundle extras) {
25 | String belongId = extras.getString("belongId");
26 | Log.i("DemoLogger", TAG + " token = " + token + ",belongId = " + belongId);
27 | ConnectionService.setToken(token);
28 | }
29 |
30 | public boolean onPushMsg(Context context, byte[] msg, Bundle bundle) {
31 | try {
32 | String content = "onPushMsg: " + new String(msg, "UTF-8");
33 | Log.d(TAG, content);
34 | } catch (Exception e) {
35 | }
36 | return false;
37 | }
38 |
39 | public void onEvent(Context context, Event event, Bundle extras) {
40 | if (Event.NOTIFICATION_OPENED.equals(event) || Event.NOTIFICATION_CLICK_BTN.equals(event)) {
41 | int notifyId = extras.getInt(BOUND_KEY.pushNotifyId, 0);
42 | if (0 != notifyId) {
43 | NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
44 | manager.cancel(notifyId);
45 | }
46 | String json = extras.getString(BOUND_KEY.pushMsgKey);
47 | String content = "huawei clicked: " + extras.getString(BOUND_KEY.pushMsgKey);
48 | android.util.Log.i("DemoLogger", TAG + " " + content);
49 | try {
50 |
51 | JSONArray obj = new JSONArray(json);
52 |
53 | PushedNotification pushedNotification = new PushedNotification(obj.getString(0), obj.getJSONObject(1));
54 | Intent clickIntent = new Intent(DefaultNotificationHandler.getIntentName(context));
55 | clickIntent.putExtra("cmd", ConnectionService.CMD_NOTIFICATION_CLICKED);
56 | clickIntent.putExtra("id", pushedNotification.id);
57 | clickIntent.putExtra("title", pushedNotification.title);
58 | clickIntent.putExtra("message", pushedNotification.message);
59 | clickIntent.putExtra("payload", pushedNotification.payload);
60 | context.sendBroadcast(clickIntent);
61 | Log.d(TAG, content);
62 |
63 | } catch (Exception e) {
64 | Log.e("DemoLogger", TAG + " Could not parse malformed JSON: \"" + json + "\"");
65 | }
66 |
67 | }
68 | }
69 |
70 | }
71 |
--------------------------------------------------------------------------------
/android-push-sdk/src/main/java/com/yy/httpproxy/thirdparty/MyFirebaseInstanceIdService.java:
--------------------------------------------------------------------------------
1 | package com.yy.httpproxy.thirdparty;
2 |
3 | import com.google.firebase.iid.FirebaseInstanceId;
4 | import com.google.firebase.iid.FirebaseInstanceIdService;
5 | import com.yy.httpproxy.service.ConnectionService;
6 | import com.yy.httpproxy.util.Log;
7 |
8 | public class MyFirebaseInstanceIdService extends FirebaseInstanceIdService {
9 |
10 | private static final String TAG = MyFirebaseInstanceIdService.class.getName();
11 |
12 | @Override
13 | public void onTokenRefresh() {
14 | super.onTokenRefresh();
15 | String refreshedToken = FirebaseInstanceId.getInstance().getToken();
16 | Log.d(TAG, "refreshedToken=" + refreshedToken);
17 | ConnectionService.setToken(refreshedToken);
18 | }
19 |
20 | }
--------------------------------------------------------------------------------
/android-push-sdk/src/main/java/com/yy/httpproxy/thirdparty/MyFirebaseMessagingService.java:
--------------------------------------------------------------------------------
1 | package com.yy.httpproxy.thirdparty;
2 |
3 | import com.google.firebase.messaging.FirebaseMessagingService;
4 | import com.google.firebase.messaging.RemoteMessage;
5 | import com.yy.httpproxy.socketio.RemoteClient;
6 | import com.yy.httpproxy.util.Log;
7 |
8 | /**
9 | * Created by xuduo on 08/03/2018.
10 | */
11 |
12 | public class MyFirebaseMessagingService extends FirebaseMessagingService {
13 |
14 | private static final String TAG = MyFirebaseMessagingService.class.getName();
15 |
16 | @Override
17 | public void onMessageReceived(RemoteMessage remoteMessage) {
18 | super.onMessageReceived(remoteMessage);
19 |
20 | Log.d(TAG, "From: " + remoteMessage.getFrom());
21 |
22 | // Check if message contains a data payload.
23 | if (remoteMessage.getData().size() > 0) {
24 | Log.d(TAG, "Message data payload: " + remoteMessage.getData());
25 | }
26 |
27 | // Check if message contains a notification payload.
28 | if (remoteMessage.getNotification() != null) {
29 | Log.d(TAG, "fcm to remote client" + remoteMessage.getData());
30 | RemoteClient.sendNotificationReceive(remoteMessage.getData().get("payload"));
31 |
32 | }
33 |
34 | }
35 |
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/android-push-sdk/src/main/java/com/yy/httpproxy/thirdparty/NotificationProvider.java:
--------------------------------------------------------------------------------
1 | package com.yy.httpproxy.thirdparty;
2 |
3 | /**
4 | * Created by Administrator on 2016/4/29.
5 | */
6 | public interface NotificationProvider {
7 |
8 | String getToken();
9 |
10 | String getType();
11 |
12 | void setToken(String token);
13 |
14 | }
15 |
--------------------------------------------------------------------------------
/android-push-sdk/src/main/java/com/yy/httpproxy/thirdparty/ProviderFactory.java:
--------------------------------------------------------------------------------
1 | package com.yy.httpproxy.thirdparty;
2 |
3 | import android.content.Context;
4 |
5 | import com.yy.httpproxy.util.Log;
6 |
7 | import com.yy.httpproxy.util.SystemProperty;
8 |
9 | public class ProviderFactory {
10 |
11 | private static final String KEY_HUAWEI_VERSION = "ro.build.version.emui";
12 | private static final String KEY_MIUI_VERSION = "ro.miui.ui.version.name";
13 | private static final String TAG = "ProviderFactory";
14 |
15 | public static NotificationProvider getProvider(Context context) {
16 | Class provider = checkProvider(context);
17 | if (HuaweiProvider.class.equals(provider)) {
18 | return new HuaweiProvider(context);
19 | } else if (XiaomiProvider.class.equals(provider)) {
20 | return new XiaomiProvider(context);
21 | } else if (FirebaseProvider.class.equals(provider)) {
22 | return new FirebaseProvider(context);
23 | } else if (UmengProvider.class.equals(provider)) {
24 | return new UmengProvider(context);
25 | } else {
26 | return null;
27 | }
28 | }
29 |
30 | public static Class checkProvider(Context context) {
31 | final SystemProperty prop = new SystemProperty(context);
32 | boolean isHuaweiSystem = isSystem(prop, KEY_HUAWEI_VERSION);
33 | boolean isHuaweiAvailable = HuaweiProvider.available(context);
34 | Log.i(TAG, "isHuaweiSystem " + isHuaweiSystem + ", isHuaweiAvailable " + isHuaweiAvailable);
35 | if (isHuaweiSystem && isHuaweiAvailable) {
36 | Log.i(TAG, "HuaweiProvider");
37 | return HuaweiProvider.class;
38 | } else {
39 | boolean isXiaomi = isSystem(prop, KEY_MIUI_VERSION);
40 | if (isXiaomi && XiaomiProvider.available(context)) {
41 | Log.i(TAG, "XiaomiProvider");
42 | return XiaomiProvider.class;
43 | } else if (FirebaseProvider.available(context)) {
44 | return FirebaseProvider.class;
45 | } else if (UmengProvider.available(context)) {
46 | return UmengProvider.class;
47 | } else {
48 | Log.i(TAG, "No provider");
49 | return null;
50 | }
51 | }
52 | }
53 |
54 | private static boolean isSystem(SystemProperty prop, String key) {
55 | String value = prop.get(key);
56 | boolean b = value != null && !value.isEmpty();
57 | Log.d(TAG, key + " " + value + " " + b);
58 | return b;
59 | }
60 |
61 | }
62 |
--------------------------------------------------------------------------------
/android-push-sdk/src/main/java/com/yy/httpproxy/thirdparty/UmengIntentService.java:
--------------------------------------------------------------------------------
1 | package com.yy.httpproxy.thirdparty;
2 |
3 | import android.content.Context;
4 | import android.content.Intent;
5 | import android.os.SystemClock;
6 |
7 | import com.umeng.message.UmengMessageService;
8 | import com.umeng.message.entity.UMessage;
9 | import com.yy.httpproxy.ProxyClient;
10 | import com.yy.httpproxy.service.ConnectionService;
11 | import com.yy.httpproxy.service.ForegroundService;
12 | import com.yy.httpproxy.service.PushedNotification;
13 | import com.yy.httpproxy.util.Log;
14 |
15 | import org.android.agoo.common.AgooConstants;
16 | import org.json.JSONObject;
17 |
18 | public class UmengIntentService extends UmengMessageService {
19 |
20 | private static final String TAG = UmengIntentService.class.getName();
21 |
22 | @Override
23 | public void onCreate() {
24 | super.onCreate();
25 | Log.i(TAG, "onCreate");
26 | if (ForegroundService.instance == null) {
27 | Log.i(TAG, "start ConnectionService from umeng");
28 | Context context = getApplicationContext();
29 | Intent intent = new Intent(context, ConnectionService.class);
30 | context.startService(intent);
31 | }
32 | }
33 |
34 | @Override
35 | public void onMessage(Context context, Intent intent) {
36 | long appUptime = SystemClock.elapsedRealtime() - ProxyClient.uptime;
37 | Log.d(TAG, "uptime=" + appUptime + "message=" + intent.getStringExtra(AgooConstants.MESSAGE_BODY));
38 | try {
39 | //可以通过MESSAGE_BODY取得消息体
40 | String message = intent.getStringExtra(AgooConstants.MESSAGE_BODY);
41 | UMessage msg = new UMessage(new JSONObject(message));
42 | Log.d(TAG, "message=" + message); //消息体
43 | Log.d(TAG, "custom=" + msg.custom); //自定义消息的内容
44 | // 通知内容
45 | // code to handle message here
46 | // ...
47 |
48 | try {
49 | JSONObject obj = new JSONObject(msg.custom);
50 | PushedNotification pushedNotification = new PushedNotification(obj.getString("id"), obj);
51 | if (ForegroundService.instance != null) {
52 | ForegroundService.instance.onNotification(pushedNotification);
53 | }
54 | if (ConnectionService.client != null) {
55 | ConnectionService.client.sendUmengReply(obj.getString("id"));
56 | if (appUptime < 3000) { //被友盟兄弟拉起
57 | Log.d(TAG, "start by host");
58 | ConnectionService.client.reportStats("umengStart", 1, 0, 0);
59 | }
60 | }
61 |
62 | Log.d(TAG, "umeng on arrive " + msg.custom);
63 | } catch (Exception e) {
64 | Log.e(TAG, "umeng Could not parse malformed JSON: \"" + msg.custom + "\"", e);
65 | }
66 |
67 | } catch (Exception e) {
68 | Log.e(TAG, "message error", e);
69 | }
70 | }
71 | }
--------------------------------------------------------------------------------
/android-push-sdk/src/main/java/com/yy/httpproxy/thirdparty/UmengProvider.java:
--------------------------------------------------------------------------------
1 | package com.yy.httpproxy.thirdparty;
2 |
3 | import android.content.Context;
4 |
5 | import com.umeng.message.IUmengRegisterCallback;
6 | import com.umeng.message.PushAgent;
7 | import com.yy.httpproxy.service.ConnectionService;
8 | import com.yy.httpproxy.util.Log;
9 | import com.yy.httpproxy.util.ServiceCheckUtil;
10 |
11 | /**
12 | * Created by xuduo on 22/05/2017.
13 | */
14 |
15 | public class UmengProvider implements NotificationProvider {
16 |
17 | public final static String TAG = "UmengProvider";
18 | private static String token;
19 |
20 | public UmengProvider(Context context) {
21 | Log.i(TAG, "UmengProvider init");
22 | }
23 |
24 | public static void register(Context context) {
25 | try {
26 | PushAgent mPushAgent = PushAgent.getInstance(context);
27 | mPushAgent.setDebugMode(false);
28 | String regId = mPushAgent.getRegistrationId();
29 | Log.i(TAG, "register " + mPushAgent.getRegistrationId());
30 | if (regId != null && !regId.isEmpty()) {
31 | token = regId;
32 | }
33 | //注册推送服务,每次调用register方法都会回调该接口
34 | mPushAgent.register(new IUmengRegisterCallback() {
35 |
36 | @Override
37 | public void onSuccess(String deviceToken) {
38 | Log.i(TAG, "main process onSuccess deviceToken " + deviceToken);
39 | ConnectionService.setToken(deviceToken);
40 | }
41 |
42 | @Override
43 | public void onFailure(String s, String s1) {
44 | Log.e(TAG, "main process onFailure " + s + " " + s1);
45 | }
46 | });
47 | mPushAgent.setPushIntentServiceClass(UmengIntentService.class);
48 | } catch (Exception e) {
49 | //友盟sdk可能会崩溃
50 | Log.e(TAG, "register error", e);
51 | }
52 |
53 | }
54 |
55 | public static boolean available(Context context) {
56 | try {
57 | boolean available = ServiceCheckUtil.isIntentServiceAvailable(context, UmengIntentService.class) &&
58 | Class.forName("com.umeng.message.PushAgent") != null
59 | && Class.forName("com.umeng.message.UmengIntentService") != null;
60 | Log.d(TAG, "available " + available);
61 | return available;
62 | } catch (Throwable e) {
63 | Log.e(TAG, "available ", e);
64 | return false;
65 | }
66 | }
67 |
68 | @Override
69 | public String getToken() {
70 | return token;
71 | }
72 |
73 | @Override
74 | public String getType() {
75 | return "umeng";
76 | }
77 |
78 | @Override
79 | public void setToken(String token) {
80 | this.token = token;
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/android-push-sdk/src/main/java/com/yy/httpproxy/thirdparty/XiaomiProvider.java:
--------------------------------------------------------------------------------
1 | package com.yy.httpproxy.thirdparty;
2 |
3 | import android.content.Context;
4 | import android.content.pm.ApplicationInfo;
5 | import android.content.pm.PackageManager;
6 |
7 | import com.yy.httpproxy.util.Log;
8 |
9 | import com.xiaomi.channel.commonutils.logger.LoggerInterface;
10 | import com.xiaomi.mipush.sdk.Logger;
11 | import com.xiaomi.mipush.sdk.MiPushClient;
12 | import com.yy.httpproxy.util.ServiceCheckUtil;
13 |
14 | public class XiaomiProvider implements NotificationProvider {
15 |
16 | public final static String TAG = "XiaomiProvider";
17 | private String token;
18 |
19 | public XiaomiProvider(Context context) {
20 |
21 | String appId = getMetaDataValue(context, "XIAOMI_APP_ID");
22 | String appKey = getMetaDataValue(context, "XIAOMI_APP_KEY");
23 | Log.i(TAG, appId + " " + appKey);
24 | MiPushClient.registerPush(context, appId, appKey);
25 |
26 | LoggerInterface newLogger = new LoggerInterface() {
27 |
28 | @Override
29 | public void setTag(String tag) {
30 | // ignore
31 | }
32 |
33 | @Override
34 | public void log(String content, Throwable t) {
35 | Log.e(TAG, content, t);
36 | }
37 |
38 | @Override
39 | public void log(String content) {
40 | Log.d(TAG, content);
41 | }
42 | };
43 | Logger.setLogger(context, newLogger);
44 | Log.d(TAG, "init");
45 | }
46 |
47 | public static boolean available(Context context) {
48 | try {
49 | return Class.forName("com.xiaomi.mipush.sdk.MiPushClient") != null
50 | && Class.forName("com.yy.httpproxy.thirdparty.XiaomiReceiver") != null
51 | && ServiceCheckUtil.isBroadcastReceiverAvailable(context, XiaomiReceiver.class) && getMetaDataValue(context, "XIAOMI_APP_ID") != null && getMetaDataValue(context, "XIAOMI_APP_ID") != null;
52 | } catch (Throwable e) {
53 | Log.e(TAG, "available ", e);
54 | return false;
55 | }
56 | }
57 |
58 | @Override
59 | public String getToken() {
60 | return token;
61 | }
62 |
63 | @Override
64 | public String getType() {
65 | return "xiaomi";
66 | }
67 |
68 | @Override
69 | public void setToken(String token) {
70 | this.token = token;
71 | }
72 |
73 | private static String getMetaDataValue(Context context, String metaDataName) {
74 | String metaDataValue = null;
75 | try {
76 | ApplicationInfo appInfo = context.getPackageManager()
77 | .getApplicationInfo(context.getPackageName(),
78 | PackageManager.GET_META_DATA);
79 | metaDataValue = appInfo.metaData.getString(metaDataName);
80 | } catch (PackageManager.NameNotFoundException e) {
81 | Log.e(TAG, "getMetaDataValue error ", e);
82 | }
83 | return metaDataValue;
84 |
85 | }
86 |
87 | }
88 |
--------------------------------------------------------------------------------
/android-push-sdk/src/main/java/com/yy/httpproxy/thirdparty/XiaomiReceiver.java:
--------------------------------------------------------------------------------
1 | package com.yy.httpproxy.thirdparty;
2 |
3 | import android.content.Context;
4 | import android.content.Intent;
5 | import com.yy.httpproxy.util.Log;
6 |
7 | import com.xiaomi.mipush.sdk.ErrorCode;
8 | import com.xiaomi.mipush.sdk.MiPushClient;
9 | import com.xiaomi.mipush.sdk.MiPushCommandMessage;
10 | import com.xiaomi.mipush.sdk.MiPushMessage;
11 | import com.xiaomi.mipush.sdk.PushMessageReceiver;
12 | import com.yy.httpproxy.service.ConnectionService;
13 | import com.yy.httpproxy.service.DefaultNotificationHandler;
14 | import com.yy.httpproxy.service.PushedNotification;
15 |
16 | import org.json.JSONObject;
17 |
18 | import java.util.List;
19 |
20 | public class XiaomiReceiver extends PushMessageReceiver {
21 |
22 | public final static String TAG = "XiaomiReceiver";
23 |
24 | @Override
25 | public void onNotificationMessageClicked(Context context, MiPushMessage message) {
26 | Log.d(TAG, "onNotificationMessageClicked is called. " + message.toString());
27 | String content = message.getContent();
28 | try {
29 | JSONObject obj = new JSONObject(content);
30 | PushedNotification pushedNotification = new PushedNotification(obj.getString("id"), obj.getJSONObject("android"));
31 | Intent clickIntent = new Intent(DefaultNotificationHandler.getIntentName(context));
32 | clickIntent.putExtra("cmd", ConnectionService.CMD_NOTIFICATION_CLICKED);
33 | clickIntent.putExtra("id", pushedNotification.id);
34 | clickIntent.putExtra("title", pushedNotification.title);
35 | clickIntent.putExtra("message", pushedNotification.message);
36 | clickIntent.putExtra("payload", pushedNotification.payload);
37 | context.sendBroadcast(clickIntent);
38 | Log.d(TAG, content);
39 | } catch (Exception e) {
40 | Log.e(TAG, "onNotificationMessageClicked Could not parse malformed JSON: \"" + content + "\"", e);
41 | }
42 | }
43 |
44 | @Override
45 | public void onNotificationMessageArrived(Context context, MiPushMessage message) {
46 | // Log.d(TAG, "onNotificationMessageArrived is called. " + message.toString());
47 | // String content = message.getContent();
48 | // if (!message.isNotified() && !message.isArrivedMessage()) {
49 | // try {
50 | //
51 | // JSONObject obj = new JSONObject(content);
52 | //
53 | // ConnectionService.publishNotification(new PushedNotification(obj.getString("id"), obj.getJSONObject("android")));
54 | // Log.d(TAG, content);
55 | //
56 | // } catch (Exception e) {
57 | // Log.e(TAG, "onNotificationMessageArrived Could not parse malformed JSON: \"" + content + "\"", e);
58 | // }
59 | // }
60 | }
61 |
62 | @Override
63 | public void onCommandResult(Context context, MiPushCommandMessage message) {
64 |
65 |
66 | }
67 |
68 | @Override
69 | public void onReceiveRegisterResult(Context context, MiPushCommandMessage message) {
70 | Log.d(TAG,
71 | "onReceiveRegisterResult is called. " + message.toString());
72 |
73 | String command = message.getCommand();
74 | List arguments = message.getCommandArguments();
75 | String cmdArg1 = ((arguments != null && arguments.size() > 0) ? arguments.get(0) : null);
76 | if (MiPushClient.COMMAND_REGISTER.equals(command)) {
77 | if (message.getResultCode() == ErrorCode.SUCCESS) {
78 | String regId = cmdArg1;
79 | Log.i(TAG, "get regId success " + regId);
80 | ConnectionService.setToken(regId);
81 | } else {
82 | Log.i(TAG, "get regId error " + message.getResultCode() + " " + message.getReason());
83 | }
84 | }
85 |
86 | }
87 |
88 | @Override
89 | public void onReceivePassThroughMessage(Context context, MiPushMessage message) {
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/android-push-sdk/src/main/java/com/yy/httpproxy/util/CrashHandler.java:
--------------------------------------------------------------------------------
1 | package com.yy.httpproxy.util;
2 |
3 | /**
4 | * Created by xuduo on 5/23/16.
5 | */
6 | public class CrashHandler implements Thread.UncaughtExceptionHandler {
7 |
8 | private Thread.UncaughtExceptionHandler defaultUEH;
9 |
10 | public CrashHandler() {
11 | this.defaultUEH = Thread.getDefaultUncaughtExceptionHandler();
12 | }
13 |
14 | @Override
15 | public void uncaughtException(Thread t, Throwable e) {
16 | Log.e("CrashHandler", "push-sdk crashed", e);
17 | defaultUEH.uncaughtException(t, e);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/android-push-sdk/src/main/java/com/yy/httpproxy/util/HttpUtil.java:
--------------------------------------------------------------------------------
1 | package com.yy.httpproxy.util;
2 |
3 | import java.io.IOException;
4 |
5 | import okhttp3.Call;
6 | import okhttp3.Callback;
7 | import okhttp3.MediaType;
8 | import okhttp3.OkHttpClient;
9 | import okhttp3.Request;
10 | import okhttp3.RequestBody;
11 | import okhttp3.Response;
12 |
13 | /**
14 | * Created by xuduo on 07/02/2017.
15 | */
16 |
17 | public class HttpUtil {
18 |
19 | public interface HttpCallback {
20 |
21 | void onSuccess(String result);
22 |
23 | void onError(String message);
24 |
25 | }
26 |
27 | private OkHttpClient client = new OkHttpClient();
28 | private static final MediaType JSON
29 | = MediaType.parse("application/json; charset=utf-8");
30 |
31 | public HttpUtil(){
32 | client.dispatcher().setMaxRequestsPerHost(1);
33 | }
34 |
35 | public void postJson(String url, String json, final HttpCallback callback) {
36 | RequestBody body = RequestBody.create(JSON, json);
37 | Request request = new Request.Builder()
38 | .url(url)
39 | .post(body)
40 | .build();
41 | client.newCall(request).enqueue(new Callback() {
42 | @Override
43 | public void onFailure(Call call, IOException e) {
44 | callback.onError(e.getMessage());
45 | }
46 |
47 | @Override
48 | public void onResponse(Call call, Response response) throws IOException {
49 | callback.onSuccess(response.body().string());
50 | }
51 | });
52 | }
53 |
54 | public static void main(String[] args) {
55 | new HttpUtil().postJson("http://localhost:11001/api/push", "{\"topic\":\"chatRoom\" , \"json\":{ \"message\": \"test_message\", \"nickName\": \"HttpUtil\", \"type\": \"chat_message\"}}", new HttpCallback() {
56 | @Override
57 | public void onSuccess(String result) {
58 | System.out.println("onSuccess " + result);
59 | }
60 |
61 | @Override
62 | public void onError(String message) {
63 | System.out.println("onError " + message);
64 | }
65 | });
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/android-push-sdk/src/main/java/com/yy/httpproxy/util/JSONUtil.java:
--------------------------------------------------------------------------------
1 | package com.yy.httpproxy.util;
2 |
3 | import org.json.JSONArray;
4 | import org.json.JSONException;
5 | import org.json.JSONObject;
6 |
7 | import java.util.Collection;
8 | import java.util.HashMap;
9 | import java.util.HashSet;
10 | import java.util.Iterator;
11 | import java.util.List;
12 | import java.util.Map;
13 | import java.util.Set;
14 |
15 | /**
16 | * Created by xuduo on 6/20/16.
17 | */
18 | public class JSONUtil {
19 |
20 | public static Map toMapOneLevelString(JSONObject object) {
21 | Map map = new HashMap<>();
22 | try {
23 | Iterator keysItr = object.keys();
24 | while (keysItr.hasNext()) {
25 | String key = keysItr.next();
26 | map.put(key, object.get(key).toString());
27 | }
28 | } catch (JSONException e) {
29 | }
30 |
31 | return map;
32 | }
33 |
34 | public static JSONObject toJSONObject(Map map) {
35 | JSONObject object = new JSONObject();
36 | try {
37 | if (map != null) {
38 | for (Map.Entry entry : map.entrySet()) {
39 | object.put(entry.getKey(), entry.getValue());
40 | }
41 | }
42 | } catch (JSONException e) {
43 | }
44 | return object;
45 | }
46 |
47 | public static String[] toStringArray(JSONArray jsonArray) {
48 | if (jsonArray != null) {
49 | String[] array = new String[jsonArray.length()];
50 | for (int i = 0; i < jsonArray.length(); i++) {
51 | array[i] = jsonArray.optString(i, "");
52 | }
53 | return array;
54 | } else {
55 | return new String[]{};
56 | }
57 | }
58 |
59 | public static Set toStringSet(JSONArray jsonArray) {
60 | if (jsonArray != null) {
61 | Set array = new HashSet<>(jsonArray.length());
62 | for (int i = 0; i < jsonArray.length(); i++) {
63 | array.add(jsonArray.optString(i, ""));
64 | }
65 | return array;
66 | } else {
67 | return new HashSet<>();
68 | }
69 | }
70 |
71 | public static JSONArray toJSONArray(Collection list) {
72 | JSONArray array = new JSONArray();
73 | if (list != null) {
74 | for (Object o : list) {
75 | array.put(o);
76 | }
77 | }
78 | return array;
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/android-push-sdk/src/main/java/com/yy/httpproxy/util/Log.java:
--------------------------------------------------------------------------------
1 | package com.yy.httpproxy.util;
2 |
3 | /**
4 | * Created by xuduo on 5/23/16.
5 | */
6 | public class Log {
7 |
8 | public static Logger logger;
9 |
10 | public static void d(String tag, String message) {
11 | if (logger != null) {
12 | log(Logger.DEBUG, tag, message, null);
13 | } else {
14 | android.util.Log.d(tag, message);
15 | }
16 | }
17 |
18 | public static void i(String tag, String message) {
19 | if (logger != null) {
20 | log(Logger.INFO, tag, message, null);
21 | } else {
22 | android.util.Log.i(tag, message);
23 | }
24 | }
25 |
26 | public static void e(String tag, String message) {
27 | if (logger != null) {
28 | log(Logger.ERROR, tag, message, null);
29 | } else {
30 | android.util.Log.e(tag, message);
31 | }
32 | }
33 |
34 | public static void e(String tag, String message, Throwable e) {
35 | if (logger != null) {
36 | log(Logger.ERROR, tag, message, e);
37 | } else {
38 | android.util.Log.e(tag, message, e);
39 | }
40 | }
41 |
42 | private static void log(int level, String tag, String message, Throwable e) {
43 | logger.log(level, tag + ":" + message, e);
44 | }
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/android-push-sdk/src/main/java/com/yy/httpproxy/util/LogcatLogger.java:
--------------------------------------------------------------------------------
1 | package com.yy.httpproxy.util;
2 |
3 | /**
4 | * Created by xuduo on 5/23/16.
5 | */
6 | public class LogcatLogger implements Logger {
7 |
8 | @Override
9 | public void log(int level, String message, Throwable e) {
10 | if (level == Logger.DEBUG) {
11 | android.util.Log.d("push-sdk", message, e);
12 | } else if (level == Logger.INFO) {
13 | android.util.Log.i("push-sdk", message, e);
14 | } else if (level == Logger.ERROR) {
15 | android.util.Log.e("push-sdk", message, e);
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/android-push-sdk/src/main/java/com/yy/httpproxy/util/Logger.java:
--------------------------------------------------------------------------------
1 | package com.yy.httpproxy.util;
2 |
3 | /**
4 | * Created by xuduo on 5/23/16.
5 | */
6 | public interface Logger {
7 |
8 | int DEBUG = 3;
9 |
10 | int INFO = 4;
11 |
12 | int ERROR = 6;
13 |
14 | void log(int level, String message, Throwable e);
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/android-push-sdk/src/main/java/com/yy/httpproxy/util/ServiceCheckUtil.java:
--------------------------------------------------------------------------------
1 | package com.yy.httpproxy.util;
2 |
3 | import android.content.Context;
4 | import android.content.Intent;
5 | import android.content.pm.PackageManager;
6 | import android.content.pm.ResolveInfo;
7 |
8 | import com.yy.httpproxy.service.ConnectionService;
9 | import com.yy.httpproxy.util.Log;
10 |
11 | import java.util.List;
12 |
13 | public class ServiceCheckUtil {
14 |
15 | public static boolean isBroadcastReceiverAvailable(Context context, Class className) {
16 | final PackageManager packageManager = context.getPackageManager();
17 | try {
18 | final Intent intent = new Intent(context, className);
19 | List resolveInfo =
20 | packageManager.queryBroadcastReceivers(intent,
21 | 0);
22 | Log.d("ServiceCheckUtil", "isBroadcastReceiverAvailable " + className + " " + resolveInfo.size());
23 | return resolveInfo.size() > 0;
24 | } catch (Exception e) {
25 | return false;
26 | }
27 | }
28 |
29 | public static boolean isIntentServiceAvailable(Context context, Class className) {
30 | final PackageManager packageManager = context.getPackageManager();
31 | try {
32 | final Intent intent = new Intent(context, className);
33 | List resolveInfo =
34 | packageManager.queryIntentServices(intent,
35 | 0);
36 | Log.d("ServiceCheckUtil", "isIntentServiceAvailable " + className + " " + resolveInfo.size());
37 | return resolveInfo.size() > 0;
38 | } catch (Exception e) {
39 | return false;
40 | }
41 | }
42 |
43 | public static String getPushProcessName(Context context) {
44 | final PackageManager packageManager = context.getPackageManager();
45 | try {
46 | final Intent intent = new Intent(context, ConnectionService.class);
47 | List resolveInfo =
48 | packageManager.queryIntentServices(intent,
49 | 0);
50 | if (resolveInfo.size() > 0) {
51 | String processName = resolveInfo.get(0).serviceInfo.processName;
52 | Log.d("ServiceCheckUtil", "ConnectionService process " + processName);
53 | return processName;
54 | }
55 | return "";
56 | } catch (Exception e) {
57 | return "";
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/android-push-sdk/src/main/java/com/yy/httpproxy/util/SystemProperty.java:
--------------------------------------------------------------------------------
1 | package com.yy.httpproxy.util;
2 |
3 | import android.content.Context;
4 | import java.lang.reflect.Method;
5 |
6 | public class SystemProperty {
7 |
8 | private Context mContext;
9 |
10 | public SystemProperty(Context mContext) {
11 | this.mContext = mContext;
12 | }
13 |
14 | public String get(String key) {
15 | try {
16 | ClassLoader classLoader = mContext.getClassLoader();
17 | Class SystemProperties = classLoader.loadClass("android.os.SystemProperties");
18 | Method methodGet = SystemProperties.getMethod("get", String.class);
19 | return (String) methodGet.invoke(SystemProperties, key);
20 | } catch (Exception e) {
21 | return null;
22 | }
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/android-push-sdk/src/main/java/com/yy/httpproxy/util/Version.java:
--------------------------------------------------------------------------------
1 | package com.yy.httpproxy.util;
2 |
3 | public class Version implements Comparable {
4 |
5 | private String version;
6 |
7 | public final String get() {
8 | return this.version;
9 | }
10 |
11 | public Version(String version) {
12 | if(version == null)
13 | throw new IllegalArgumentException("Version can not be null");
14 | if(!version.matches("[0-9]+(\\.[0-9]+)*"))
15 | throw new IllegalArgumentException("Invalid version format");
16 | this.version = version;
17 | }
18 |
19 | @Override public int compareTo(Version that) {
20 | if(that == null)
21 | return 1;
22 | String[] thisParts = this.get().split("\\.");
23 | String[] thatParts = that.get().split("\\.");
24 | int length = Math.max(thisParts.length, thatParts.length);
25 | for(int i = 0; i < length; i++) {
26 | int thisPart = i < thisParts.length ?
27 | Integer.parseInt(thisParts[i]) : 0;
28 | int thatPart = i < thatParts.length ?
29 | Integer.parseInt(thatParts[i]) : 0;
30 | if(thisPart < thatPart)
31 | return -1;
32 | if(thisPart > thatPart)
33 | return 1;
34 | }
35 | return 0;
36 | }
37 |
38 | @Override public boolean equals(Object that) {
39 | if(this == that)
40 | return true;
41 | if(that == null)
42 | return false;
43 | if(this.getClass() != that.getClass())
44 | return false;
45 | return this.compareTo((Version) that) == 0;
46 | }
47 |
48 | }
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:2.2.0'
9 | classpath 'com.google.gms:google-services:3.2.0'
10 | }
11 | }
12 |
13 | allprojects {
14 | repositories {
15 | mavenCentral()
16 | maven {
17 | url "https://maven.google.com" // Google's Maven repository
18 | }
19 | }
20 | tasks.withType(JavaCompile) {
21 | sourceCompatibility = 1.7
22 | targetCompatibility = 1.7
23 | }
24 | }
25 |
26 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Settings specified in this file will override any Gradle settings
5 | # configured through the IDE.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
19 | sonatypeUsername=
20 | sonatypePassword=
21 | sdk.dir=
22 | org.gradle.jvmargs=-Xms1G -Xmx4G -XX:MaxPermSize=256m
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuduo/socket.io-push-android/c5738189a79bfae036b8199d0287980c734d9d85/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Sun Oct 09 11:28:18 CST 2016
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # For Cygwin, ensure paths are in UNIX format before anything is touched.
46 | if $cygwin ; then
47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
48 | fi
49 |
50 | # Attempt to set APP_HOME
51 | # Resolve links: $0 may be a link
52 | PRG="$0"
53 | # Need this for relative symlinks.
54 | while [ -h "$PRG" ] ; do
55 | ls=`ls -ld "$PRG"`
56 | link=`expr "$ls" : '.*-> \(.*\)$'`
57 | if expr "$link" : '/.*' > /dev/null; then
58 | PRG="$link"
59 | else
60 | PRG=`dirname "$PRG"`"/$link"
61 | fi
62 | done
63 | SAVED="`pwd`"
64 | cd "`dirname \"$PRG\"`/" >&-
65 | APP_HOME="`pwd -P`"
66 | cd "$SAVED" >&-
67 |
68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
69 |
70 | # Determine the Java command to use to start the JVM.
71 | if [ -n "$JAVA_HOME" ] ; then
72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
73 | # IBM's JDK on AIX uses strange locations for the executables
74 | JAVACMD="$JAVA_HOME/jre/sh/java"
75 | else
76 | JAVACMD="$JAVA_HOME/bin/java"
77 | fi
78 | if [ ! -x "$JAVACMD" ] ; then
79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
80 |
81 | Please set the JAVA_HOME variable in your environment to match the
82 | location of your Java installation."
83 | fi
84 | else
85 | JAVACMD="java"
86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
87 |
88 | Please set the JAVA_HOME variable in your environment to match the
89 | location of your Java installation."
90 | fi
91 |
92 | # Increase the maximum file descriptors if we can.
93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
94 | MAX_FD_LIMIT=`ulimit -H -n`
95 | if [ $? -eq 0 ] ; then
96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
97 | MAX_FD="$MAX_FD_LIMIT"
98 | fi
99 | ulimit -n $MAX_FD
100 | if [ $? -ne 0 ] ; then
101 | warn "Could not set maximum file descriptor limit: $MAX_FD"
102 | fi
103 | else
104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
105 | fi
106 | fi
107 |
108 | # For Darwin, add options to specify how the application appears in the dock
109 | if $darwin; then
110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
111 | fi
112 |
113 | # For Cygwin, switch paths to Windows format before running java
114 | if $cygwin ; then
115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
158 | function splitJvmOpts() {
159 | JVM_OPTS=("$@")
160 | }
161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
163 |
164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':android-demo', ':android-push-sdk'
--------------------------------------------------------------------------------