├── start.bat ├── README.md ├── libs ├── greendao-1.3.7.jar ├── monitor_protoc.jar ├── android-support-v4.jar ├── protobuf-java-2.5.0.jar ├── netty-buffer-4.0.23.Final.jar ├── netty-codec-4.0.23.Final.jar ├── netty-common-4.0.23.Final.jar └── netty-transport-4.0.23.Final.jar ├── jar └── anetty_client_1.0.jar ├── bin └── com │ └── netty │ └── client │ ├── R.class │ ├── R$attr.class │ ├── R$style.class │ ├── R$string.class │ ├── BuildConfig.class │ ├── R$drawable.class │ ├── utils │ └── Md5Util.class │ ├── android │ ├── dao │ │ ├── Device.class │ │ ├── DaoMaster.class │ │ ├── DaoSession.class │ │ ├── DeviceDao.class │ │ ├── DaoMaster$OpenHelper.class │ │ ├── DeviceDao$Properties.class │ │ └── DaoMaster$DevOpenHelper.class │ ├── NettyServerManager.class │ ├── NettyServerManager$1.class │ ├── NettyServerManager$2.class │ ├── NettyServerManager$3.class │ ├── handler │ │ ├── MessageObject.class │ │ ├── NettyProcessorHandler.class │ │ └── NettyProcessorHandler$1.class │ ├── service │ │ ├── PushDbService.class │ │ ├── RemoteService.class │ │ ├── RemoteService$1.class │ │ └── RemoteService$NettyServiceClientImpl.class │ ├── aidl │ │ ├── NettyServiceClient.class │ │ ├── NettyServiceClient$Stub.class │ │ └── NettyServiceClient$Stub$Proxy.class │ ├── broadcast │ │ ├── AlarmReceiver.class │ │ ├── NettyAlarmManager.class │ │ └── ClientBroadcastReceiver.class │ ├── network │ │ ├── INetworkCallback.class │ │ └── DefaultNetworkCallback.class │ ├── listener │ │ ├── ConnectionListener.class │ │ ├── ReConnectionListener.class │ │ ├── ServerStatusListener.class │ │ ├── INettyHandlerListener.class │ │ └── RegistrationResultListener.class │ └── notification │ │ └── INotificationView.class │ ├── consts │ └── SystemConsts.class │ ├── api │ ├── ConnectionManager.class │ ├── NettyConnectionClient$1.class │ ├── NettyConnectionClient.class │ └── listener │ │ ├── IConnectionListener.class │ │ ├── IRegisterListener.class │ │ └── DefaultNotificationListener.class │ ├── handler │ ├── PushMessageHandler.class │ └── PushMessageHandler$1.class │ └── context │ └── ApplicationContextClient.class ├── res ├── drawable-hdpi │ └── ic_launcher.png ├── drawable-mdpi │ └── ic_launcher.png ├── drawable-xhdpi │ └── ic_launcher.png ├── values │ ├── strings.xml │ └── styles.xml ├── values-v11 │ └── styles.xml └── values-v14 │ └── styles.xml ├── gen └── com │ └── netty │ └── client │ ├── BuildConfig.java │ ├── R.java │ └── android │ └── aidl │ └── NettyServiceClient.java ├── src └── com │ └── netty │ └── client │ ├── android │ ├── aidl │ │ └── NettyServiceClient.aidl │ ├── network │ │ ├── INetworkCallback.java │ │ └── DefaultNetworkCallback.java │ ├── listener │ │ ├── INettyHandlerListener.java │ │ ├── ServerStatusListener.java │ │ ├── ReConnectionListener.java │ │ ├── ConnectionListener.java │ │ └── RegistrationResultListener.java │ ├── notification │ │ └── INotificationView.java │ ├── handler │ │ ├── MessageObject.java │ │ └── NettyProcessorHandler.java │ ├── dao │ │ ├── DaoSession.java │ │ ├── Device.java │ │ ├── DaoMaster.java │ │ └── DeviceDao.java │ ├── service │ │ ├── PushDbService.java │ │ └── RemoteService.java │ ├── broadcast │ │ ├── AlarmReceiver.java │ │ ├── ClientBroadcastReceiver.java │ │ └── NettyAlarmManager.java │ └── NettyServerManager.java │ ├── api │ ├── listener │ │ ├── IRegisterListener.java │ │ ├── IConnectionListener.java │ │ └── DefaultNotificationListener.java │ ├── ConnectionManager.java │ └── NettyConnectionClient.java │ ├── consts │ └── SystemConsts.java │ ├── handler │ └── PushMessageHandler.java │ ├── utils │ └── Md5Util.java │ └── context │ └── ApplicationContextClient.java ├── .gitignore ├── AndroidManifest.xml ├── .classpath ├── project.properties ├── proguard-project.txt ├── .project └── LICENSE /start.bat: -------------------------------------------------------------------------------- 1 | ant build -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | anetty_client 2 | ============= 3 | 4 | Netty Client For Android 5 | -------------------------------------------------------------------------------- /libs/greendao-1.3.7.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/libs/greendao-1.3.7.jar -------------------------------------------------------------------------------- /libs/monitor_protoc.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/libs/monitor_protoc.jar -------------------------------------------------------------------------------- /jar/anetty_client_1.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/jar/anetty_client_1.0.jar -------------------------------------------------------------------------------- /bin/com/netty/client/R.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/bin/com/netty/client/R.class -------------------------------------------------------------------------------- /libs/android-support-v4.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/libs/android-support-v4.jar -------------------------------------------------------------------------------- /libs/protobuf-java-2.5.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/libs/protobuf-java-2.5.0.jar -------------------------------------------------------------------------------- /bin/com/netty/client/R$attr.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/bin/com/netty/client/R$attr.class -------------------------------------------------------------------------------- /bin/com/netty/client/R$style.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/bin/com/netty/client/R$style.class -------------------------------------------------------------------------------- /libs/netty-buffer-4.0.23.Final.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/libs/netty-buffer-4.0.23.Final.jar -------------------------------------------------------------------------------- /libs/netty-codec-4.0.23.Final.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/libs/netty-codec-4.0.23.Final.jar -------------------------------------------------------------------------------- /libs/netty-common-4.0.23.Final.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/libs/netty-common-4.0.23.Final.jar -------------------------------------------------------------------------------- /res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /bin/com/netty/client/R$string.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/bin/com/netty/client/R$string.class -------------------------------------------------------------------------------- /res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | monitor_nettyclient 4 | 5 | 6 | -------------------------------------------------------------------------------- /bin/com/netty/client/BuildConfig.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/bin/com/netty/client/BuildConfig.class -------------------------------------------------------------------------------- /bin/com/netty/client/R$drawable.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/bin/com/netty/client/R$drawable.class -------------------------------------------------------------------------------- /libs/netty-transport-4.0.23.Final.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/libs/netty-transport-4.0.23.Final.jar -------------------------------------------------------------------------------- /bin/com/netty/client/utils/Md5Util.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/bin/com/netty/client/utils/Md5Util.class -------------------------------------------------------------------------------- /bin/com/netty/client/android/dao/Device.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/bin/com/netty/client/android/dao/Device.class -------------------------------------------------------------------------------- /bin/com/netty/client/consts/SystemConsts.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/bin/com/netty/client/consts/SystemConsts.class -------------------------------------------------------------------------------- /bin/com/netty/client/android/dao/DaoMaster.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/bin/com/netty/client/android/dao/DaoMaster.class -------------------------------------------------------------------------------- /bin/com/netty/client/android/dao/DaoSession.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/bin/com/netty/client/android/dao/DaoSession.class -------------------------------------------------------------------------------- /bin/com/netty/client/android/dao/DeviceDao.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/bin/com/netty/client/android/dao/DeviceDao.class -------------------------------------------------------------------------------- /bin/com/netty/client/api/ConnectionManager.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/bin/com/netty/client/api/ConnectionManager.class -------------------------------------------------------------------------------- /bin/com/netty/client/android/NettyServerManager.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/bin/com/netty/client/android/NettyServerManager.class -------------------------------------------------------------------------------- /bin/com/netty/client/api/NettyConnectionClient$1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/bin/com/netty/client/api/NettyConnectionClient$1.class -------------------------------------------------------------------------------- /bin/com/netty/client/api/NettyConnectionClient.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/bin/com/netty/client/api/NettyConnectionClient.class -------------------------------------------------------------------------------- /bin/com/netty/client/handler/PushMessageHandler.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/bin/com/netty/client/handler/PushMessageHandler.class -------------------------------------------------------------------------------- /bin/com/netty/client/android/NettyServerManager$1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/bin/com/netty/client/android/NettyServerManager$1.class -------------------------------------------------------------------------------- /bin/com/netty/client/android/NettyServerManager$2.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/bin/com/netty/client/android/NettyServerManager$2.class -------------------------------------------------------------------------------- /bin/com/netty/client/android/NettyServerManager$3.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/bin/com/netty/client/android/NettyServerManager$3.class -------------------------------------------------------------------------------- /bin/com/netty/client/android/handler/MessageObject.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/bin/com/netty/client/android/handler/MessageObject.class -------------------------------------------------------------------------------- /bin/com/netty/client/android/service/PushDbService.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/bin/com/netty/client/android/service/PushDbService.class -------------------------------------------------------------------------------- /bin/com/netty/client/android/service/RemoteService.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/bin/com/netty/client/android/service/RemoteService.class -------------------------------------------------------------------------------- /bin/com/netty/client/handler/PushMessageHandler$1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/bin/com/netty/client/handler/PushMessageHandler$1.class -------------------------------------------------------------------------------- /bin/com/netty/client/android/aidl/NettyServiceClient.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/bin/com/netty/client/android/aidl/NettyServiceClient.class -------------------------------------------------------------------------------- /bin/com/netty/client/android/broadcast/AlarmReceiver.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/bin/com/netty/client/android/broadcast/AlarmReceiver.class -------------------------------------------------------------------------------- /bin/com/netty/client/android/dao/DaoMaster$OpenHelper.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/bin/com/netty/client/android/dao/DaoMaster$OpenHelper.class -------------------------------------------------------------------------------- /bin/com/netty/client/android/dao/DeviceDao$Properties.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/bin/com/netty/client/android/dao/DeviceDao$Properties.class -------------------------------------------------------------------------------- /bin/com/netty/client/android/network/INetworkCallback.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/bin/com/netty/client/android/network/INetworkCallback.class -------------------------------------------------------------------------------- /bin/com/netty/client/android/service/RemoteService$1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/bin/com/netty/client/android/service/RemoteService$1.class -------------------------------------------------------------------------------- /bin/com/netty/client/api/listener/IConnectionListener.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/bin/com/netty/client/api/listener/IConnectionListener.class -------------------------------------------------------------------------------- /bin/com/netty/client/api/listener/IRegisterListener.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/bin/com/netty/client/api/listener/IRegisterListener.class -------------------------------------------------------------------------------- /bin/com/netty/client/context/ApplicationContextClient.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/bin/com/netty/client/context/ApplicationContextClient.class -------------------------------------------------------------------------------- /bin/com/netty/client/android/aidl/NettyServiceClient$Stub.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/bin/com/netty/client/android/aidl/NettyServiceClient$Stub.class -------------------------------------------------------------------------------- /bin/com/netty/client/android/broadcast/NettyAlarmManager.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/bin/com/netty/client/android/broadcast/NettyAlarmManager.class -------------------------------------------------------------------------------- /bin/com/netty/client/android/dao/DaoMaster$DevOpenHelper.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/bin/com/netty/client/android/dao/DaoMaster$DevOpenHelper.class -------------------------------------------------------------------------------- /bin/com/netty/client/android/handler/NettyProcessorHandler.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/bin/com/netty/client/android/handler/NettyProcessorHandler.class -------------------------------------------------------------------------------- /bin/com/netty/client/android/listener/ConnectionListener.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/bin/com/netty/client/android/listener/ConnectionListener.class -------------------------------------------------------------------------------- /bin/com/netty/client/android/listener/ReConnectionListener.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/bin/com/netty/client/android/listener/ReConnectionListener.class -------------------------------------------------------------------------------- /bin/com/netty/client/android/listener/ServerStatusListener.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/bin/com/netty/client/android/listener/ServerStatusListener.class -------------------------------------------------------------------------------- /bin/com/netty/client/android/handler/NettyProcessorHandler$1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/bin/com/netty/client/android/handler/NettyProcessorHandler$1.class -------------------------------------------------------------------------------- /bin/com/netty/client/android/listener/INettyHandlerListener.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/bin/com/netty/client/android/listener/INettyHandlerListener.class -------------------------------------------------------------------------------- /bin/com/netty/client/android/network/DefaultNetworkCallback.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/bin/com/netty/client/android/network/DefaultNetworkCallback.class -------------------------------------------------------------------------------- /bin/com/netty/client/android/notification/INotificationView.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/bin/com/netty/client/android/notification/INotificationView.class -------------------------------------------------------------------------------- /bin/com/netty/client/android/aidl/NettyServiceClient$Stub$Proxy.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/bin/com/netty/client/android/aidl/NettyServiceClient$Stub$Proxy.class -------------------------------------------------------------------------------- /bin/com/netty/client/android/broadcast/ClientBroadcastReceiver.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/bin/com/netty/client/android/broadcast/ClientBroadcastReceiver.class -------------------------------------------------------------------------------- /bin/com/netty/client/api/listener/DefaultNotificationListener.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/bin/com/netty/client/api/listener/DefaultNotificationListener.class -------------------------------------------------------------------------------- /bin/com/netty/client/android/listener/RegistrationResultListener.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/bin/com/netty/client/android/listener/RegistrationResultListener.class -------------------------------------------------------------------------------- /bin/com/netty/client/android/service/RemoteService$NettyServiceClientImpl.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maofw/anetty_client/HEAD/bin/com/netty/client/android/service/RemoteService$NettyServiceClientImpl.class -------------------------------------------------------------------------------- /gen/com/netty/client/BuildConfig.java: -------------------------------------------------------------------------------- 1 | /** Automatically generated file. DO NOT MODIFY */ 2 | package com.netty.client; 3 | 4 | public final class BuildConfig { 5 | public final static boolean DEBUG = true; 6 | } -------------------------------------------------------------------------------- /src/com/netty/client/android/aidl/NettyServiceClient.aidl: -------------------------------------------------------------------------------- 1 | package com.netty.client.android.aidl; 2 | interface NettyServiceClient { 3 | void regist(String appKey,String appPackage); 4 | 5 | void deviceOffline(String appPackage); 6 | } -------------------------------------------------------------------------------- /src/com/netty/client/android/network/INetworkCallback.java: -------------------------------------------------------------------------------- 1 | package com.netty.client.android.network; 2 | 3 | public interface INetworkCallback { 4 | public void connectSuccess(); 5 | 6 | public void connectFailed(); 7 | 8 | public void setConnected(boolean isConnected); 9 | } 10 | -------------------------------------------------------------------------------- /src/com/netty/client/android/listener/INettyHandlerListener.java: -------------------------------------------------------------------------------- 1 | package com.netty.client.android.listener; 2 | 3 | /** 4 | * android Handler 回调监听 5 | * 6 | * @author maofw 7 | * 8 | * @param 9 | */ 10 | public interface INettyHandlerListener { 11 | public void callback(T t); 12 | } 13 | -------------------------------------------------------------------------------- /src/com/netty/client/api/listener/IRegisterListener.java: -------------------------------------------------------------------------------- 1 | package com.netty.client.api.listener; 2 | 3 | /** 4 | * 注册消息客户端监听 5 | * 6 | * @类名称:IRegisterListener 7 | * @类描述: 8 | * @创建人:maofw 9 | * @创建时间:2014-10-30 上午11:21:05 10 | * 11 | */ 12 | public interface IRegisterListener { 13 | public void receive(String regId); 14 | } 15 | -------------------------------------------------------------------------------- /res/values-v11/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/com/netty/client/android/notification/INotificationView.java: -------------------------------------------------------------------------------- 1 | package com.netty.client.android.notification; 2 | 3 | import android.widget.RemoteViews; 4 | 5 | /** 6 | * 自定义通知布局 7 | * 8 | * @类名称:INotificationView 9 | * @类描述: 10 | * @创建人:maofw 11 | * @创建时间:2014-10-24 上午10:37:47 12 | * 13 | */ 14 | public interface INotificationView { 15 | public RemoteViews customView(); 16 | } 17 | -------------------------------------------------------------------------------- /src/com/netty/client/api/listener/IConnectionListener.java: -------------------------------------------------------------------------------- 1 | package com.netty.client.api.listener; 2 | 3 | import com.xwtec.protoc.CommandProtoc; 4 | 5 | /** 6 | * 客户端连接监听器 7 | * 8 | * @类名称:IConnectionListener 9 | * @类描述: 10 | * @创建人:maofw 11 | * @创建时间:2014-10-28 下午12:41:04 12 | * 13 | */ 14 | public interface IConnectionListener { 15 | public void receive(CommandProtoc.Message message); 16 | } 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # Files for the Dalvik VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # Generated files 12 | bin/ 13 | gen/ 14 | 15 | # Gradle files 16 | .gradle/ 17 | build/ 18 | 19 | # Local configuration file (sdk path, etc) 20 | local.properties 21 | 22 | # Proguard folder generated by Eclipse 23 | proguard/ 24 | 25 | # Log Files 26 | *.log 27 | -------------------------------------------------------------------------------- /res/values-v14/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 9 | 10 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/com/netty/client/android/handler/MessageObject.java: -------------------------------------------------------------------------------- 1 | package com.netty.client.android.handler; 2 | 3 | public class MessageObject { 4 | private String appPackage; 5 | private Object obj; 6 | 7 | public MessageObject() { 8 | } 9 | 10 | public String getAppPackage() { 11 | return appPackage; 12 | } 13 | 14 | public void setAppPackage(String appPackage) { 15 | this.appPackage = appPackage; 16 | } 17 | 18 | public Object getObj() { 19 | return obj; 20 | } 21 | 22 | public void setObj(Object obj) { 23 | this.obj = obj; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/com/netty/client/consts/SystemConsts.java: -------------------------------------------------------------------------------- 1 | package com.netty.client.consts; 2 | 3 | public class SystemConsts { 4 | /** 5 | * db名称 6 | */ 7 | public static final String DATABASE_NAME = "push.db"; 8 | /** 9 | * 主机IP地址 10 | */ 11 | public static final String HOST = "221.130.48.67"; 12 | public static final int PORT = 16319; 13 | public static final String CHANNEL = "android"; 14 | public static final String NOTIFICATION_MESSAGE = "notification_message"; 15 | public static final String REGISTRATION_MESSAGE = "registration_message"; 16 | } 17 | -------------------------------------------------------------------------------- /.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /project.properties: -------------------------------------------------------------------------------- 1 | # This file is automatically generated by Android Tools. 2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED! 3 | # 4 | # This file must be checked in Version Control Systems. 5 | # 6 | # To customize properties used by the Ant build system edit 7 | # "ant.properties", and override values to adapt the script to your 8 | # project structure. 9 | # 10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): 11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt 12 | 13 | # Project target. 14 | target=android-19 15 | android.library=true 16 | -------------------------------------------------------------------------------- /res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 14 | 15 | 16 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /proguard-project.txt: -------------------------------------------------------------------------------- 1 | # To enable ProGuard in your project, edit project.properties 2 | # to define the proguard.config property as described in that file. 3 | # 4 | # Add project specific ProGuard rules here. 5 | # By default, the flags in this file are appended to flags specified 6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt 7 | # You can edit the include path and order by changing the ProGuard 8 | # include property in project.properties. 9 | # 10 | # For more details, see 11 | # http://developer.android.com/guide/developing/tools/proguard.html 12 | 13 | # Add any project specific keep options here: 14 | 15 | # If your project uses WebView with JS, uncomment the following 16 | # and specify the fully qualified class name to the JavaScript interface 17 | # class: 18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 19 | # public *; 20 | #} 21 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | anetty_client 4 | 5 | 6 | 7 | 8 | 9 | com.android.ide.eclipse.adt.ResourceManagerBuilder 10 | 11 | 12 | 13 | 14 | com.android.ide.eclipse.adt.PreCompilerBuilder 15 | 16 | 17 | 18 | 19 | org.eclipse.jdt.core.javabuilder 20 | 21 | 22 | 23 | 24 | com.android.ide.eclipse.adt.ApkBuilder 25 | 26 | 27 | 28 | 29 | 30 | com.android.ide.eclipse.adt.AndroidNature 31 | org.eclipse.jdt.core.javanature 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/com/netty/client/android/listener/ServerStatusListener.java: -------------------------------------------------------------------------------- 1 | package com.netty.client.android.listener; 2 | 3 | import java.util.ArrayList; 4 | 5 | /** 6 | * 服务器连接成功 回調處理 7 | * 8 | * @类名称:ServerStatusListener 9 | * @类描述: 10 | * @创建人:maofw 11 | * @创建时间:2014-10-20 上午9:31:31 12 | * 13 | */ 14 | @SuppressWarnings("rawtypes") 15 | public class ServerStatusListener implements INettyHandlerListener { 16 | private ArrayList nettyHandlerListeners = new ArrayList(); 17 | 18 | public void registNettyHandlerListener(INettyHandlerListener nettyHandlerListener) { 19 | if (nettyHandlerListener != null && !nettyHandlerListeners.contains(nettyHandlerListener)) { 20 | nettyHandlerListeners.add(nettyHandlerListener); 21 | } 22 | } 23 | 24 | @SuppressWarnings("unchecked") 25 | @Override 26 | public void callback(Object t) { 27 | // 服务器连接成功后通知 28 | if (nettyHandlerListeners != null && !nettyHandlerListeners.isEmpty()) { 29 | for (INettyHandlerListener nettyHandlerListener : nettyHandlerListeners) { 30 | nettyHandlerListener.callback(t); 31 | } 32 | } 33 | } 34 | 35 | public void destory(){ 36 | if(nettyHandlerListeners!=null){ 37 | nettyHandlerListeners.clear() ; 38 | nettyHandlerListeners = null ; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/com/netty/client/android/listener/ReConnectionListener.java: -------------------------------------------------------------------------------- 1 | package com.netty.client.android.listener; 2 | 3 | import java.util.Iterator; 4 | import java.util.Map; 5 | 6 | import com.netty.client.android.dao.Device; 7 | import com.netty.client.android.service.RemoteService; 8 | import com.netty.client.context.ApplicationContextClient; 9 | 10 | /** 11 | * 服务器连接成功 回調處理 12 | * 13 | * @类名称:ConnectionListener 14 | * @类描述: 15 | * @创建人:maofw 16 | * @创建时间:2014-10-20 上午9:31:31 17 | * 18 | */ 19 | public class ReConnectionListener implements INettyHandlerListener { 20 | private ApplicationContextClient applicationContextClient = RemoteService.getApplicationContextClient(); 21 | 22 | @Override 23 | public void callback(Device t) { 24 | Device deviceInfo = null; 25 | // 服务器连接成功后发送设备注册信息给服务器 26 | Map devices = applicationContextClient.getDeviceInfos(); 27 | if (devices != null && !devices.isEmpty()) { 28 | // 循环发送设备注册消息 29 | Iterator> iterator = devices.entrySet().iterator(); 30 | while (iterator.hasNext()) { 31 | Map.Entry entry = iterator.next(); 32 | if (entry != null) { 33 | // 獲取設備信息 34 | deviceInfo = entry.getValue(); 35 | applicationContextClient.sendRegistrationMessage(deviceInfo, null); 36 | } 37 | } 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/com/netty/client/android/listener/ConnectionListener.java: -------------------------------------------------------------------------------- 1 | package com.netty.client.android.listener; 2 | 3 | import android.content.Context; 4 | import android.util.Log; 5 | 6 | import com.netty.client.android.dao.Device; 7 | import com.netty.client.android.service.RemoteService; 8 | import com.netty.client.context.ApplicationContextClient; 9 | 10 | /** 11 | * 服务器连接成功 回調處理 12 | * 13 | * @类名称:ConnectionListener 14 | * @类描述: 15 | * @创建人:maofw 16 | * @创建时间:2014-10-20 上午9:31:31 17 | * 18 | */ 19 | public class ConnectionListener implements INettyHandlerListener { 20 | private ApplicationContextClient applicationContextClient = RemoteService.getApplicationContextClient(); 21 | 22 | private Device deviceInfo; 23 | 24 | private Context mContext; 25 | 26 | public ConnectionListener(Context context, String appKey, String appPackage) { 27 | Log.i(ApplicationContextClient.class.getName(), "ConnectionListener"); 28 | mContext = context; 29 | // 获取设备缓存信息 30 | deviceInfo = applicationContextClient.makeDevice(context, appKey, appPackage); 31 | } 32 | 33 | @Override 34 | public void callback(Device t) { 35 | // 服务器连接成功后发送设备注册信息给服务器 36 | // 发送设备注册消息 37 | if (deviceInfo != null && deviceInfo.getIsOnline() == ApplicationContextClient.DEVICE_OFFLINE) { 38 | // 如果设备不在线 则发送注册请求 39 | applicationContextClient.sendRegistrationMessage(deviceInfo, new RegistrationResultListener(mContext, deviceInfo)); 40 | } 41 | 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/com/netty/client/android/dao/DaoSession.java: -------------------------------------------------------------------------------- 1 | package com.netty.client.android.dao; 2 | 3 | import android.database.sqlite.SQLiteDatabase; 4 | 5 | import java.util.Map; 6 | 7 | import de.greenrobot.dao.AbstractDao; 8 | import de.greenrobot.dao.AbstractDaoSession; 9 | import de.greenrobot.dao.identityscope.IdentityScopeType; 10 | import de.greenrobot.dao.internal.DaoConfig; 11 | 12 | import com.netty.client.android.dao.Device; 13 | 14 | import com.netty.client.android.dao.DeviceDao; 15 | 16 | // THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT. 17 | 18 | /** 19 | * {@inheritDoc} 20 | * 21 | * @see de.greenrobot.dao.AbstractDaoSession 22 | */ 23 | public class DaoSession extends AbstractDaoSession { 24 | 25 | private final DaoConfig deviceDaoConfig; 26 | 27 | private final DeviceDao deviceDao; 28 | 29 | public DaoSession(SQLiteDatabase db, IdentityScopeType type, Map>, DaoConfig> 30 | daoConfigMap) { 31 | super(db); 32 | 33 | deviceDaoConfig = daoConfigMap.get(DeviceDao.class).clone(); 34 | deviceDaoConfig.initIdentityScope(type); 35 | 36 | deviceDao = new DeviceDao(deviceDaoConfig, this); 37 | 38 | registerDao(Device.class, deviceDao); 39 | } 40 | 41 | public void clear() { 42 | deviceDaoConfig.getIdentityScope().clear(); 43 | } 44 | 45 | public DeviceDao getDeviceDao() { 46 | return deviceDao; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/com/netty/client/android/listener/RegistrationResultListener.java: -------------------------------------------------------------------------------- 1 | package com.netty.client.android.listener; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | 6 | import com.netty.client.android.broadcast.ClientBroadcastReceiver; 7 | import com.netty.client.android.dao.Device; 8 | import com.netty.client.android.service.RemoteService; 9 | import com.netty.client.consts.SystemConsts; 10 | import com.netty.client.context.ApplicationContextClient; 11 | import com.xwtec.protoc.CommandProtoc; 12 | 13 | /** 14 | * 系统默认的注册listener实现 15 | * 16 | * @author maofw 17 | * 18 | */ 19 | public class RegistrationResultListener implements INettyHandlerListener { 20 | private ApplicationContextClient applicationContextClient = RemoteService.getApplicationContextClient(); 21 | 22 | private Device deviceInfo; 23 | private Context mContext; 24 | 25 | public RegistrationResultListener(Context context, Device deviceInfo) { 26 | this.deviceInfo = deviceInfo; 27 | this.mContext = context; 28 | } 29 | 30 | @Override 31 | public void callback(CommandProtoc.RegistrationResult t) { 32 | if (t != null && t.getRegistrationId() != null) { 33 | deviceInfo.setRegId(t.getRegistrationId()); 34 | // 注册成功 缓存设备信息 35 | applicationContextClient.saveOrUpdateDevice(deviceInfo); 36 | // 注册成功了 设备上线消息处理 37 | applicationContextClient.sendDeviceOnlineMessage(deviceInfo, null); 38 | 39 | if (mContext != null) { 40 | // 发送广播给客户端 41 | Intent intent = new Intent(); 42 | intent.setAction(ClientBroadcastReceiver.REG_ACTION); 43 | intent.putExtra(SystemConsts.REGISTRATION_MESSAGE, t); 44 | mContext.sendBroadcast(intent); 45 | } 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /gen/com/netty/client/R.java: -------------------------------------------------------------------------------- 1 | /* AUTO-GENERATED FILE. DO NOT MODIFY. 2 | * 3 | * This class was automatically generated by the 4 | * aapt tool from the resource data it found. It 5 | * should not be modified by hand. 6 | */ 7 | 8 | package com.netty.client; 9 | 10 | public final class R { 11 | public static final class attr { 12 | } 13 | public static final class drawable { 14 | public static int ic_launcher=0x7f020000; 15 | } 16 | public static final class string { 17 | public static int app_name=0x7f030000; 18 | } 19 | public static final class style { 20 | /** 21 | Base application theme, dependent on API level. This theme is replaced 22 | by AppBaseTheme from res/values-vXX/styles.xml on newer devices. 23 | 24 | 25 | Theme customizations available in newer API levels can go in 26 | res/values-vXX/styles.xml, while customizations related to 27 | backward-compatibility can go here. 28 | 29 | 30 | Base application theme for API 11+. This theme completely replaces 31 | AppBaseTheme from res/values/styles.xml on API 11+ devices. 32 | 33 | API 11 theme customizations can go here. 34 | 35 | Base application theme for API 14+. This theme completely replaces 36 | AppBaseTheme from BOTH res/values/styles.xml and 37 | res/values-v11/styles.xml on API 14+ devices. 38 | 39 | API 14 theme customizations can go here. 40 | */ 41 | public static int AppBaseTheme=0x7f040000; 42 | /** Application theme. 43 | All customizations that are NOT specific to a particular API-level can go here. 44 | */ 45 | public static int AppTheme=0x7f040001; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/com/netty/client/android/service/PushDbService.java: -------------------------------------------------------------------------------- 1 | package com.netty.client.android.service; 2 | 3 | import java.util.HashMap; 4 | import java.util.List; 5 | import java.util.Map; 6 | 7 | import android.content.Context; 8 | 9 | import com.netty.client.android.dao.Device; 10 | import com.netty.client.android.dao.DeviceDao; 11 | import com.netty.client.context.ApplicationContextClient; 12 | 13 | import de.greenrobot.dao.query.QueryBuilder; 14 | 15 | public class PushDbService { 16 | 17 | private DeviceDao deviceDao; 18 | 19 | private static PushDbService instance; 20 | 21 | public static PushDbService getInstance(Context context) { 22 | if (instance == null) { 23 | instance = new PushDbService(); 24 | instance.deviceDao = RemoteService.getDaoSession(context).getDeviceDao(); 25 | } 26 | return instance; 27 | } 28 | 29 | /** 30 | * 从数据库中获取设备信息 31 | * 32 | * @return 33 | */ 34 | public Map queryDevicesForMap() { 35 | QueryBuilder qb = this.deviceDao.queryBuilder(); 36 | List list = qb.list(); 37 | if (list != null && list.size() > 0) { 38 | Map map = new HashMap(); 39 | for (Device device : list) { 40 | if (device != null) { 41 | // 设备从数据库中取出来默认为已经离线 42 | device.setIsOnline(ApplicationContextClient.DEVICE_OFFLINE); 43 | map.put(device.getAppPackage(), device); 44 | } 45 | } 46 | return map; 47 | } 48 | return null; 49 | } 50 | 51 | /** 52 | * 保存设备信息到数据库中 53 | * 54 | * @param device 55 | * @return 56 | */ 57 | public int saveOrUpdateDevice(Device device) { 58 | if (device == null) { 59 | return -1; 60 | } 61 | long id = this.deviceDao.insertOrReplace(device); 62 | if (id > 0) { 63 | device.setId(id); 64 | return 1; 65 | } 66 | return 0; 67 | } 68 | 69 | public void deleteDevice(Device device) { 70 | if (device != null) { 71 | this.deviceDao.delete(device); 72 | } 73 | } 74 | 75 | public void saveOrUpdateDevices(List devices) { 76 | if (devices != null && devices.size() > 0) { 77 | this.deviceDao.insertInTx(devices); 78 | } 79 | 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/com/netty/client/android/network/DefaultNetworkCallback.java: -------------------------------------------------------------------------------- 1 | package com.netty.client.android.network; 2 | 3 | import android.app.AlarmManager; 4 | import android.app.PendingIntent; 5 | import android.content.Context; 6 | import android.content.Intent; 7 | 8 | import com.netty.client.android.broadcast.AlarmReceiver; 9 | 10 | public class DefaultNetworkCallback implements INetworkCallback { 11 | // 是否正在处理网络重连操作 12 | private boolean isConnected = false; 13 | private boolean ISDEALING = false; 14 | private AlarmManager alarmManager = null; 15 | 16 | private PendingIntent sender; 17 | // 重连时间 10s 18 | private static final long RECONN_TIMESOUT = 10 * 1000L; 19 | 20 | // 重连次数限制 3 21 | private static final int RECONN_MAXCNT = 3; 22 | 23 | // 重连次数 24 | private int reconnCnt = 0; 25 | 26 | private Context context; 27 | 28 | public DefaultNetworkCallback(Context context) { 29 | this.context = context; 30 | } 31 | 32 | @Override 33 | public void connectFailed() { 34 | if (!isConnected && !ISDEALING) { 35 | ISDEALING = true; 36 | if (reconnCnt >= RECONN_MAXCNT) { 37 | // 已经达到了规定限制 则停止一切活动运行 38 | stopAlarm(); 39 | reconnCnt = 0; 40 | return; 41 | } 42 | 43 | reconnCnt++; 44 | 45 | if (alarmManager == null) { 46 | alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); 47 | } 48 | // 操作:发送一个广播,广播接收后Toast提示定时操作完成 49 | Intent intent = new Intent(); 50 | intent.setAction(AlarmReceiver.CONNECT_ACTION); 51 | sender = PendingIntent.getBroadcast(context, 0, intent, 0); 52 | // 15s后重新发送连接请求 53 | ISDEALING = false; 54 | alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + RECONN_TIMESOUT, sender); 55 | } 56 | 57 | } 58 | 59 | @Override 60 | public void connectSuccess() { 61 | isConnected = true; 62 | ISDEALING = false; 63 | stopAlarm(); 64 | reconnCnt = 0; 65 | } 66 | 67 | /** 68 | * 停止定时时钟 69 | */ 70 | private void stopAlarm() { 71 | if (alarmManager != null && sender != null) { 72 | alarmManager.cancel(sender); 73 | } 74 | } 75 | 76 | @Override 77 | public void setConnected(boolean isConnected) { 78 | this.isConnected = isConnected; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/com/netty/client/android/dao/Device.java: -------------------------------------------------------------------------------- 1 | package com.netty.client.android.dao; 2 | 3 | // THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT. Enable "keep" sections if you want to edit. 4 | /** 5 | * Entity mapped to table t_device. 6 | */ 7 | public class Device { 8 | 9 | private Long id; 10 | private String appKey; 11 | private String deviceId; 12 | private String imei; 13 | private String appPackage; 14 | private String regId; 15 | private Integer isOnline; 16 | 17 | public Device() { 18 | } 19 | 20 | public Device(Long id) { 21 | this.id = id; 22 | } 23 | 24 | public Device(Long id, String appKey, String deviceId, String imei, String appPackage, String regId, Integer isOnline) { 25 | this.id = id; 26 | this.appKey = appKey; 27 | this.deviceId = deviceId; 28 | this.imei = imei; 29 | this.appPackage = appPackage; 30 | this.regId = regId; 31 | this.isOnline = isOnline; 32 | } 33 | 34 | public Long getId() { 35 | return id; 36 | } 37 | 38 | public void setId(Long id) { 39 | this.id = id; 40 | } 41 | 42 | public String getAppKey() { 43 | return appKey; 44 | } 45 | 46 | public void setAppKey(String appKey) { 47 | this.appKey = appKey; 48 | } 49 | 50 | public String getDeviceId() { 51 | return deviceId; 52 | } 53 | 54 | public void setDeviceId(String deviceId) { 55 | this.deviceId = deviceId; 56 | } 57 | 58 | public String getImei() { 59 | return imei; 60 | } 61 | 62 | public void setImei(String imei) { 63 | this.imei = imei; 64 | } 65 | 66 | public String getAppPackage() { 67 | return appPackage; 68 | } 69 | 70 | public void setAppPackage(String appPackage) { 71 | this.appPackage = appPackage; 72 | } 73 | 74 | public String getRegId() { 75 | return regId; 76 | } 77 | 78 | public void setRegId(String regId) { 79 | this.regId = regId; 80 | } 81 | 82 | public Integer getIsOnline() { 83 | return isOnline; 84 | } 85 | 86 | public void setIsOnline(Integer isOnline) { 87 | this.isOnline = isOnline; 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /src/com/netty/client/api/ConnectionManager.java: -------------------------------------------------------------------------------- 1 | package com.netty.client.api; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Iterator; 5 | 6 | import com.netty.client.api.listener.IConnectionListener; 7 | import com.netty.client.api.listener.IRegisterListener; 8 | import com.xwtec.protoc.CommandProtoc; 9 | 10 | /** 11 | * 连接管理器 12 | * 13 | * @类名称:ConnectionManager 14 | * @类描述: 15 | * @创建人:maofw 16 | * @创建时间:2014-10-28 下午12:46:21 17 | * 18 | */ 19 | public class ConnectionManager { 20 | 21 | // private static ConnectionManager connectionManager = new ConnectionManager(); 22 | 23 | private static ArrayList connectionListeners = new ArrayList(); 24 | 25 | private static ArrayList registerListeners = new ArrayList(); 26 | 27 | // private ConnectionManager() { 28 | // } 29 | // 30 | // public static ConnectionManager getInstance() { 31 | // return connectionManager; 32 | // } 33 | 34 | /** 35 | * 添加 监听器 36 | * 37 | * @param connectionListener 38 | */ 39 | public static void addConnectionListener(IConnectionListener connectionListener) { 40 | if (connectionListener != null && !connectionListeners.contains(connectionListener)) { 41 | connectionListeners.add(connectionListener); 42 | } 43 | } 44 | 45 | public static void addRegisterListener(IRegisterListener registerListener) { 46 | if (registerListener != null && !registerListeners.contains(registerListener)) { 47 | registerListeners.add(registerListener); 48 | } 49 | } 50 | 51 | /** 52 | * 53 | */ 54 | public static void notificationMessageListeners(CommandProtoc.Message message) { 55 | if (connectionListeners != null && !connectionListeners.isEmpty()) { 56 | Iterator iterator = connectionListeners.iterator(); 57 | while (iterator.hasNext()) { 58 | iterator.next().receive(message); 59 | } 60 | } 61 | } 62 | 63 | public static void notificationRegisterListeners(String regId) { 64 | if (registerListeners != null && !registerListeners.isEmpty()) { 65 | Iterator iterator = registerListeners.iterator(); 66 | while (iterator.hasNext()) { 67 | iterator.next().receive(regId); 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/com/netty/client/android/broadcast/AlarmReceiver.java: -------------------------------------------------------------------------------- 1 | package com.netty.client.android.broadcast; 2 | 3 | import android.content.BroadcastReceiver; 4 | import android.content.Context; 5 | import android.content.Intent; 6 | import android.net.ConnectivityManager; 7 | import android.net.NetworkInfo; 8 | import android.util.Log; 9 | 10 | import com.netty.client.android.NettyServerManager; 11 | import com.netty.client.android.service.RemoteService; 12 | import com.netty.client.context.ApplicationContextClient; 13 | 14 | public class AlarmReceiver extends BroadcastReceiver { 15 | public static String ACTION = "HEART_BEAT"; 16 | public static String CONNECT_ACTION = "CONNECT_ACTION"; 17 | private ConnectivityManager manager = null;// 18 | private ApplicationContextClient applicationContextClient = RemoteService.getApplicationContextClient(); 19 | 20 | private void connectivityManager(Context context) { 21 | if (manager == null) { 22 | manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); 23 | } 24 | } 25 | 26 | @Override 27 | public void onReceive(Context context, Intent intent) { 28 | try { 29 | Log.i(ApplicationContextClient.class.getName(), "AlarmReceiver:" + intent.getAction()); 30 | } catch (Exception e) { 31 | System.out.println("AlarmReceiver"); 32 | } 33 | if (ACTION.equals(intent.getAction())) { 34 | // 心跳广播 35 | applicationContextClient.sendHeartBeatMessage(); 36 | } else if (CONNECT_ACTION.equals(intent.getAction())) { 37 | // 重连广播监听 38 | try { 39 | NettyServerManager.reconnect(); 40 | } catch (Exception e) { 41 | e.printStackTrace(); 42 | } 43 | 44 | } else if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) { 45 | // 网络状态监听广播接收 46 | connectivityManager(context); 47 | NetworkInfo gprs = manager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE); 48 | NetworkInfo wifi = manager.getNetworkInfo(ConnectivityManager.TYPE_WIFI); 49 | if (!gprs.isConnected() && !wifi.isConnected()) { 50 | // 網絡斷開 了 51 | // 停止心跳消息发送 52 | NettyAlarmManager.stopHeart(); 53 | // 停止重连 54 | NettyAlarmManager.stopReconnection(); 55 | } else { 56 | // 启动重连 57 | NettyAlarmManager.startReconnection(context); 58 | } 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/com/netty/client/android/broadcast/ClientBroadcastReceiver.java: -------------------------------------------------------------------------------- 1 | package com.netty.client.android.broadcast; 2 | 3 | import android.content.BroadcastReceiver; 4 | import android.content.Context; 5 | import android.content.Intent; 6 | import android.util.Log; 7 | 8 | import com.netty.client.api.ConnectionManager; 9 | import com.netty.client.consts.SystemConsts; 10 | import com.netty.client.context.ApplicationContextClient; 11 | import com.xwtec.protoc.CommandProtoc; 12 | 13 | /** 14 | * 消息通知广播接收器 15 | * 16 | * @类名称:NotificationReceiver 17 | * @类描述: 18 | * @创建人:maofw 19 | * @创建时间:2014-10-24 上午10:33:48 20 | * 21 | */ 22 | public class ClientBroadcastReceiver extends BroadcastReceiver { 23 | // 消息通知 24 | public static final String NOTIFICATION_ACTION = "com.netty.NOTIFICATION"; 25 | // 注册成功广播通知 26 | public static final String REG_ACTION = "com.netty.REG"; 27 | 28 | @Override 29 | public void onReceive(Context context, Intent intent) { 30 | try { 31 | Log.i(ApplicationContextClient.class.getName(), "NotificationReceiver:" + intent.getAction() + ":" + context); 32 | } catch (Exception e) { 33 | System.out.println("NotificationReceiver"); 34 | } 35 | if (REG_ACTION.equals(intent.getAction())) { 36 | // 接收广播通知 展示notification 37 | CommandProtoc.RegistrationResult message = (CommandProtoc.RegistrationResult) intent.getSerializableExtra(SystemConsts.REGISTRATION_MESSAGE); 38 | // 通知所有监听器 39 | if (message != null) { 40 | // 获取本应用AppPackage名称 41 | if (isSelfContext(context, message.getAppPackage())) { 42 | ConnectionManager.notificationRegisterListeners(message.getRegistrationId()); 43 | } 44 | } 45 | 46 | } else if (NOTIFICATION_ACTION.equals(intent.getAction())) { 47 | // 接收广播通知 展示notification 48 | CommandProtoc.Message message = (CommandProtoc.Message) intent.getSerializableExtra(SystemConsts.NOTIFICATION_MESSAGE); 49 | // 通知所有监听器 50 | if (message != null) { 51 | // 获取本应用AppPackage名称 52 | if (isSelfContext(context, message.getAppPackage())) { 53 | ConnectionManager.notificationMessageListeners(message); 54 | } 55 | } 56 | } 57 | } 58 | 59 | /** 60 | * 判断是否是属于本应用 61 | * 62 | * @param context 63 | * @param appPackage 64 | * @return 65 | */ 66 | private boolean isSelfContext(Context context, String appPackage) { 67 | boolean b = false; 68 | if (appPackage != null && appPackage.equals(context.getPackageName())) { 69 | b = true; 70 | } 71 | return b; 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /src/com/netty/client/api/NettyConnectionClient.java: -------------------------------------------------------------------------------- 1 | package com.netty.client.api; 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.IBinder; 8 | import android.os.RemoteException; 9 | import android.util.Log; 10 | 11 | import com.netty.client.android.aidl.NettyServiceClient; 12 | import com.netty.client.android.aidl.NettyServiceClient.Stub; 13 | 14 | /** 15 | * 连接客户端jar 16 | * 17 | * @类名称:NettyConnectionClient 18 | * @类描述: 19 | * @创建人:maofw 20 | * @创建时间:2014-10-20 上午11:08:32 21 | * 22 | */ 23 | public class NettyConnectionClient { 24 | 25 | private NettyServiceClient nettyServiceClient = null; 26 | private Context mContext; 27 | private String mAppKey; 28 | 29 | private Intent aidlIntent = new Intent(NettyServiceClient.class.getName()); 30 | 31 | public NettyConnectionClient(Context context, String appKey) { 32 | this.mContext = context; 33 | this.mAppKey = appKey; 34 | // 启动service 35 | // if(!isMyServiceExisted()){ 36 | // 如果service不存在 则启动 37 | mContext.startService(aidlIntent); 38 | // } 39 | } 40 | 41 | ServiceConnection mConnection = new ServiceConnection() { 42 | 43 | @Override 44 | public void onServiceDisconnected(ComponentName name) { 45 | Log.i("NettyConnectionClient", "### aidl disconnected."); 46 | } 47 | 48 | @Override 49 | public void onServiceConnected(ComponentName name, IBinder service) { 50 | Log.i("NettyConnectionClient", "### aidl onServiceConnected. service : " + service.getClass().getName()); 51 | 52 | nettyServiceClient = Stub.asInterface(service); 53 | Log.i("NettyConnectionClient", "### after asInterface : " + nettyServiceClient.getClass().getName()); 54 | try { 55 | nettyServiceClient.regist(mAppKey, mContext.getPackageName()); 56 | } catch (RemoteException e) { 57 | e.printStackTrace(); 58 | } 59 | } 60 | }; 61 | 62 | /** 63 | * 綁定service服务 64 | * 65 | * @param host 66 | * @param port 67 | */ 68 | public void bindNettyService() { 69 | // 服务端的action 70 | mContext.bindService(aidlIntent, mConnection, Context.BIND_AUTO_CREATE); 71 | } 72 | 73 | public void unbindNettyService() { 74 | mContext.unbindService(mConnection); 75 | } 76 | 77 | /** 78 | * 解除设备注册 (删除service中缓存的设备信息内容) 79 | * 80 | * @param context 81 | */ 82 | public void unregist() { 83 | if (nettyServiceClient != null && mContext != null) { 84 | try { 85 | // 想service发送 设备下线消息 86 | nettyServiceClient.deviceOffline(mContext.getPackageName()); 87 | 88 | } catch (RemoteException e) { 89 | e.printStackTrace(); 90 | } 91 | } 92 | } 93 | 94 | } 95 | -------------------------------------------------------------------------------- /src/com/netty/client/android/dao/DaoMaster.java: -------------------------------------------------------------------------------- 1 | package com.netty.client.android.dao; 2 | 3 | import android.content.Context; 4 | import android.database.sqlite.SQLiteDatabase; 5 | import android.database.sqlite.SQLiteDatabase.CursorFactory; 6 | import android.database.sqlite.SQLiteOpenHelper; 7 | import android.util.Log; 8 | import de.greenrobot.dao.AbstractDaoMaster; 9 | import de.greenrobot.dao.identityscope.IdentityScopeType; 10 | 11 | import com.netty.client.android.dao.DeviceDao; 12 | 13 | // THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT. 14 | /** 15 | * Master of DAO (schema version 1): knows all DAOs. 16 | */ 17 | public class DaoMaster extends AbstractDaoMaster { 18 | public static final int SCHEMA_VERSION = 1; 19 | 20 | /** Creates underlying database table using DAOs. */ 21 | public static void createAllTables(SQLiteDatabase db, boolean ifNotExists) { 22 | DeviceDao.createTable(db, ifNotExists); 23 | } 24 | 25 | /** Drops underlying database table using DAOs. */ 26 | public static void dropAllTables(SQLiteDatabase db, boolean ifExists) { 27 | DeviceDao.dropTable(db, ifExists); 28 | } 29 | 30 | public static abstract class OpenHelper extends SQLiteOpenHelper { 31 | 32 | public OpenHelper(Context context, String name, CursorFactory factory) { 33 | super(context, name, factory, SCHEMA_VERSION); 34 | } 35 | 36 | @Override 37 | public void onCreate(SQLiteDatabase db) { 38 | Log.i("greenDAO", "Creating tables for schema version " + SCHEMA_VERSION); 39 | createAllTables(db, false); 40 | } 41 | } 42 | 43 | /** WARNING: Drops all table on Upgrade! Use only during development. */ 44 | public static class DevOpenHelper extends OpenHelper { 45 | public DevOpenHelper(Context context, String name, CursorFactory factory) { 46 | super(context, name, factory); 47 | } 48 | 49 | @Override 50 | public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 51 | Log.i("greenDAO", "Upgrading schema from version " + oldVersion + " to " + newVersion + " by dropping all tables"); 52 | dropAllTables(db, true); 53 | onCreate(db); 54 | } 55 | } 56 | 57 | public DaoMaster(SQLiteDatabase db) { 58 | super(db, SCHEMA_VERSION); 59 | registerDaoClass(DeviceDao.class); 60 | } 61 | 62 | public DaoSession newSession() { 63 | return new DaoSession(db, IdentityScopeType.Session, daoConfigMap); 64 | } 65 | 66 | public DaoSession newSession(IdentityScopeType type) { 67 | return new DaoSession(db, type, daoConfigMap); 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /src/com/netty/client/api/listener/DefaultNotificationListener.java: -------------------------------------------------------------------------------- 1 | package com.netty.client.api.listener; 2 | 3 | import java.text.ParseException; 4 | import java.text.SimpleDateFormat; 5 | import java.util.Locale; 6 | 7 | import android.app.Notification; 8 | import android.app.NotificationManager; 9 | import android.app.PendingIntent; 10 | import android.content.Context; 11 | import android.content.Intent; 12 | import android.content.pm.PackageManager; 13 | import android.util.Log; 14 | 15 | import com.xwtec.protoc.CommandProtoc; 16 | import com.xwtec.protoc.CommandProtoc.Message; 17 | 18 | /** 19 | * 默认消息通知监听实现 20 | * 21 | * @类名称:DefaultNotificationListener 22 | * @类描述: 23 | * @创建人:maofw 24 | * @创建时间:2014-10-28 下午12:41:54 25 | * 26 | */ 27 | public class DefaultNotificationListener implements IConnectionListener { 28 | private static final SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy", Locale.US); 29 | 30 | private NotificationManager notificationManager; 31 | 32 | private Context mContext; 33 | private int mIconId; 34 | private boolean mIsShowSysMsg = false ; 35 | 36 | public DefaultNotificationListener(Context context,boolean isShowSysMsg) { 37 | mContext = context; 38 | mIconId = context.getApplicationInfo().icon ; 39 | mIsShowSysMsg = isShowSysMsg ; 40 | } 41 | 42 | @Override 43 | public void receive(Message message) { 44 | Log.i(getClass().getName(), "receive:mContext:"+mContext.getClass().getName()+"-mIconId:"+mIconId); 45 | if(message.getType()==1|| (message.getType() == 0&&mIsShowSysMsg)){ 46 | //系统消息并且需要展示的进行消息提醒 |用户消息必须提醒 47 | notification(mContext, mIconId, message); 48 | } 49 | 50 | 51 | } 52 | 53 | /** 54 | * 消息通知 55 | * 56 | * @param icon 57 | * @param title 58 | * @param content 59 | */ 60 | @SuppressWarnings("deprecation") 61 | private void notification(Context context, int icon, CommandProtoc.Message message) { 62 | if (notificationManager == null) { 63 | notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); 64 | } 65 | int idx = message.getMsgId() == null ? 1 : Integer.parseInt(message.getMsgId()); 66 | String title = message.getTitle(); 67 | String content = message.getContent().toStringUtf8(); 68 | PackageManager packageManager = context.getPackageManager(); 69 | Intent appIntent = new Intent(); 70 | appIntent = packageManager.getLaunchIntentForPackage(message.getAppPackage()); 71 | appIntent.addCategory(Intent.CATEGORY_LAUNCHER); 72 | // appIntent.setPackage(message.getAppPackage()); 73 | // appIntent.set 74 | appIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); 75 | PendingIntent pendingIntent = PendingIntent.getActivity(context, idx, appIntent, PendingIntent.FLAG_UPDATE_CURRENT); 76 | 77 | Notification notification = new Notification(); 78 | try { 79 | notification.when = sdf.parse(message.getPushTime()).getTime(); 80 | } catch (ParseException e) { 81 | e.printStackTrace(); 82 | notification.when = System.currentTimeMillis(); 83 | } 84 | notification.defaults = Notification.DEFAULT_SOUND; 85 | notification.flags = Notification.FLAG_AUTO_CANCEL; 86 | 87 | // 使用系统默认样式 88 | notification.icon = icon; 89 | notification.tickerText = title; 90 | notification.setLatestEventInfo(context, title, content, pendingIntent); 91 | 92 | notificationManager.notify(idx, notification); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/com/netty/client/android/broadcast/NettyAlarmManager.java: -------------------------------------------------------------------------------- 1 | package com.netty.client.android.broadcast; 2 | 3 | import android.app.AlarmManager; 4 | import android.app.PendingIntent; 5 | import android.content.Context; 6 | import android.content.Intent; 7 | import android.os.SystemClock; 8 | import android.util.Log; 9 | 10 | public class NettyAlarmManager { 11 | private static AlarmManager alarmManager = null; 12 | 13 | private static PendingIntent sender = null; 14 | 15 | private static PendingIntent reconnectSender = null; 16 | // 心跳週期 默认30s 17 | public static long PERIOD = 30 * 1000L; 18 | 19 | // 间隔重连时间次数 20 | public static long reconnectTimes = 1L; 21 | public static long RECONNECT_PERIOD = 500L; 22 | 23 | private static AlarmManager getAlarmManager(Context context) { 24 | if (alarmManager == null) { 25 | alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); 26 | } 27 | return alarmManager; 28 | } 29 | 30 | /** 31 | * 启动心跳监控 32 | * 33 | * @param period 34 | */ 35 | public static void startHeart(Context context) { 36 | getAlarmManager(context); 37 | // 操作:发送一个广播,广播接收后Toast提示定时操作完成 38 | if (sender == null) { 39 | Intent intent = new Intent(); 40 | intent.setAction(AlarmReceiver.ACTION); 41 | sender = PendingIntent.getBroadcast(context, 0, intent, 0); 42 | } 43 | // 开始时间 44 | long firstime = SystemClock.elapsedRealtime() + 10 * 1000L; 45 | Log.i(NettyAlarmManager.class.getName(), "startHeart"); 46 | // 一个周期,不停的发送广播 47 | alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstime, PERIOD, sender); 48 | } 49 | 50 | /** 51 | * 停止心跳監控 52 | */ 53 | public static void stopHeart() { 54 | Log.i(NettyAlarmManager.class.getName(), "stopHeart"); 55 | if (alarmManager != null && sender != null) { 56 | alarmManager.cancel(sender); 57 | } 58 | } 59 | 60 | /** 61 | * 启动重连 62 | * 63 | * @param period 64 | */ 65 | public static void startReconnection(Context context) { 66 | getAlarmManager(context); 67 | // 操作:发送一个广播,广播接收后Toast提示定时操作完成 68 | if (reconnectSender == null) { 69 | Intent intent = new Intent(); 70 | intent.setAction(AlarmReceiver.CONNECT_ACTION); 71 | reconnectSender = PendingIntent.getBroadcast(context, 0, intent, 0); 72 | } 73 | Log.i(NettyAlarmManager.class.getName(), "startReconnection"); 74 | // 一个周期,不停的发送广播 75 | // 或者以下面方式简化 76 | alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + reconnectTimes * RECONNECT_PERIOD, reconnectSender); 77 | increaseReconnectTimes(); 78 | // alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstime, PERIOD, sender); 79 | } 80 | 81 | /** 82 | * 重置 83 | */ 84 | public static void resetReconnectTimes() { 85 | reconnectTimes = 1L; 86 | RECONNECT_PERIOD = 500L; 87 | } 88 | 89 | /** 90 | * 重新计算重连间隔 91 | */ 92 | public static void increaseReconnectTimes() { 93 | // 以2的冪次進行递增 94 | // if (reconnectTimes > 0) { 95 | // if (reconnectTimes + 100L >= Long.MAX_VALUE) { 96 | // resetReconnectTimes(); 97 | // } else { 98 | // reconnectTimes += (reconnectTimes++) * 100L; 99 | // 100 | // } 101 | // } else if (reconnectTimes < 0) { 102 | // resetReconnectTimes(); 103 | // } 104 | 105 | if (((++reconnectTimes) * (RECONNECT_PERIOD + 500L)) >= Long.MAX_VALUE) { 106 | resetReconnectTimes(); 107 | } else { 108 | RECONNECT_PERIOD += 500L; 109 | } 110 | } 111 | 112 | /** 113 | * 停止重连監控 114 | */ 115 | public static void stopReconnection() { 116 | Log.i(NettyAlarmManager.class.getName(), "stopReconnection"); 117 | if (alarmManager != null && reconnectSender != null) { 118 | alarmManager.cancel(reconnectSender); 119 | } 120 | resetReconnectTimes(); 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /src/com/netty/client/android/handler/NettyProcessorHandler.java: -------------------------------------------------------------------------------- 1 | package com.netty.client.android.handler; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.os.Handler; 6 | import android.os.Message; 7 | import android.util.Log; 8 | import android.widget.Toast; 9 | 10 | import com.netty.client.android.broadcast.ClientBroadcastReceiver; 11 | import com.netty.client.android.listener.INettyHandlerListener; 12 | import com.netty.client.android.service.RemoteService; 13 | import com.netty.client.consts.SystemConsts; 14 | import com.netty.client.context.ApplicationContextClient; 15 | import com.xwtec.protoc.CommandProtoc; 16 | 17 | public class NettyProcessorHandler extends Handler { 18 | 19 | public static final int REGISTRATION_RESULT = 100; 20 | public static final int DEVICE_ONLINE_RESULT = 101; 21 | public static final int DEVICE_OFFLINE_RESULT = 102; 22 | public static final int MESSAGE = 103; 23 | private Context context; 24 | private ApplicationContextClient applicationContextClient; 25 | 26 | public NettyProcessorHandler(Context context) { 27 | this.context = context; 28 | this.applicationContextClient = RemoteService.getApplicationContextClient(); 29 | } 30 | 31 | /** 32 | * 消息处理方法 33 | */ 34 | @SuppressWarnings({ "rawtypes", "unchecked" }) 35 | @Override 36 | public void handleMessage(Message msg) { 37 | if (msg != null) { 38 | Log.i(getClass().getName(), "-handleMessage:msg.what=" + msg.what); 39 | MessageObject mo = (MessageObject) msg.obj; 40 | if (mo == null) { 41 | return; 42 | } 43 | INettyHandlerListener listener = applicationContextClient.getNettyHandlerListener(mo.getAppPackage(), msg.what); 44 | if (listener != null) { 45 | Log.i(getClass().getName(), "-handleMessage:listener.callback=" + listener.toString()); 46 | listener.callback(mo.getObj()); 47 | return; 48 | } 49 | 50 | switch (msg.what) { 51 | case DEVICE_ONLINE_RESULT: 52 | // 上线结果消息 53 | handleOnlineResult((CommandProtoc.DeviceOnoffResult.ResultCode) mo.getObj()); 54 | break; 55 | case DEVICE_OFFLINE_RESULT: 56 | // 下线结果消息 57 | handleOfflineResult((CommandProtoc.DeviceOnoffResult.ResultCode) mo.getObj()); 58 | break; 59 | case MESSAGE: 60 | // 消息 61 | handlePushMessage((CommandProtoc.Message) mo.getObj()); 62 | break; 63 | default: 64 | break; 65 | } 66 | } 67 | } 68 | 69 | /** 70 | * 上线消息结果处理 71 | * 72 | * @param resCode 73 | */ 74 | protected void handleOnlineResult(CommandProtoc.DeviceOnoffResult.ResultCode resultCode) { 75 | if (context != null) { 76 | switch (resultCode) { 77 | case SUCCESS: 78 | Toast.makeText(context, "设备上线成功", Toast.LENGTH_LONG).show(); 79 | break; 80 | case FAILED: 81 | Toast.makeText(context, "设备上线失败", Toast.LENGTH_LONG).show(); 82 | break; 83 | default: 84 | break; 85 | } 86 | } 87 | } 88 | 89 | /** 90 | * 下线消息结果处理 91 | * 92 | * @param resCode 93 | */ 94 | protected void handleOfflineResult(CommandProtoc.DeviceOnoffResult.ResultCode resultCode) { 95 | if (context != null) { 96 | switch (resultCode) { 97 | case SUCCESS: 98 | Toast.makeText(context, "设备下线成功", Toast.LENGTH_LONG).show(); 99 | break; 100 | case FAILED: 101 | Toast.makeText(context, "设备下线失败", Toast.LENGTH_LONG).show(); 102 | break; 103 | default: 104 | break; 105 | } 106 | } 107 | } 108 | 109 | /** 110 | * PUSH消息处理 111 | * 112 | * @param message 113 | */ 114 | protected void handlePushMessage(CommandProtoc.Message message) { 115 | if (message != null) { 116 | // 发送广播 117 | Intent intent = new Intent(); 118 | intent.setAction(ClientBroadcastReceiver.NOTIFICATION_ACTION); 119 | intent.putExtra(SystemConsts.NOTIFICATION_MESSAGE, message); 120 | context.sendBroadcast(intent); 121 | // 获取app icon id 122 | // int icon = context.getApplicationInfo().icon; 123 | // 系统通知消息 124 | // notification(icon, message); 125 | } 126 | } 127 | 128 | } 129 | -------------------------------------------------------------------------------- /gen/com/netty/client/android/aidl/NettyServiceClient.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is auto-generated. DO NOT MODIFY. 3 | * Original file: E:\\android_workspace\\anetty_client\\src\\com\\netty\\client\\android\\aidl\\NettyServiceClient.aidl 4 | */ 5 | package com.netty.client.android.aidl; 6 | public interface NettyServiceClient extends android.os.IInterface 7 | { 8 | /** Local-side IPC implementation stub class. */ 9 | public static abstract class Stub extends android.os.Binder implements com.netty.client.android.aidl.NettyServiceClient 10 | { 11 | private static final java.lang.String DESCRIPTOR = "com.netty.client.android.aidl.NettyServiceClient"; 12 | /** Construct the stub at attach it to the interface. */ 13 | public Stub() 14 | { 15 | this.attachInterface(this, DESCRIPTOR); 16 | } 17 | /** 18 | * Cast an IBinder object into an com.netty.client.android.aidl.NettyServiceClient interface, 19 | * generating a proxy if needed. 20 | */ 21 | public static com.netty.client.android.aidl.NettyServiceClient asInterface(android.os.IBinder obj) 22 | { 23 | if ((obj==null)) { 24 | return null; 25 | } 26 | android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR); 27 | if (((iin!=null)&&(iin instanceof com.netty.client.android.aidl.NettyServiceClient))) { 28 | return ((com.netty.client.android.aidl.NettyServiceClient)iin); 29 | } 30 | return new com.netty.client.android.aidl.NettyServiceClient.Stub.Proxy(obj); 31 | } 32 | @Override public android.os.IBinder asBinder() 33 | { 34 | return this; 35 | } 36 | @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException 37 | { 38 | switch (code) 39 | { 40 | case INTERFACE_TRANSACTION: 41 | { 42 | reply.writeString(DESCRIPTOR); 43 | return true; 44 | } 45 | case TRANSACTION_regist: 46 | { 47 | data.enforceInterface(DESCRIPTOR); 48 | java.lang.String _arg0; 49 | _arg0 = data.readString(); 50 | java.lang.String _arg1; 51 | _arg1 = data.readString(); 52 | this.regist(_arg0, _arg1); 53 | reply.writeNoException(); 54 | return true; 55 | } 56 | case TRANSACTION_deviceOffline: 57 | { 58 | data.enforceInterface(DESCRIPTOR); 59 | java.lang.String _arg0; 60 | _arg0 = data.readString(); 61 | this.deviceOffline(_arg0); 62 | reply.writeNoException(); 63 | return true; 64 | } 65 | } 66 | return super.onTransact(code, data, reply, flags); 67 | } 68 | private static class Proxy implements com.netty.client.android.aidl.NettyServiceClient 69 | { 70 | private android.os.IBinder mRemote; 71 | Proxy(android.os.IBinder remote) 72 | { 73 | mRemote = remote; 74 | } 75 | @Override public android.os.IBinder asBinder() 76 | { 77 | return mRemote; 78 | } 79 | public java.lang.String getInterfaceDescriptor() 80 | { 81 | return DESCRIPTOR; 82 | } 83 | @Override public void regist(java.lang.String appKey, java.lang.String appPackage) throws android.os.RemoteException 84 | { 85 | android.os.Parcel _data = android.os.Parcel.obtain(); 86 | android.os.Parcel _reply = android.os.Parcel.obtain(); 87 | try { 88 | _data.writeInterfaceToken(DESCRIPTOR); 89 | _data.writeString(appKey); 90 | _data.writeString(appPackage); 91 | mRemote.transact(Stub.TRANSACTION_regist, _data, _reply, 0); 92 | _reply.readException(); 93 | } 94 | finally { 95 | _reply.recycle(); 96 | _data.recycle(); 97 | } 98 | } 99 | @Override public void deviceOffline(java.lang.String appPackage) throws android.os.RemoteException 100 | { 101 | android.os.Parcel _data = android.os.Parcel.obtain(); 102 | android.os.Parcel _reply = android.os.Parcel.obtain(); 103 | try { 104 | _data.writeInterfaceToken(DESCRIPTOR); 105 | _data.writeString(appPackage); 106 | mRemote.transact(Stub.TRANSACTION_deviceOffline, _data, _reply, 0); 107 | _reply.readException(); 108 | } 109 | finally { 110 | _reply.recycle(); 111 | _data.recycle(); 112 | } 113 | } 114 | } 115 | static final int TRANSACTION_regist = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0); 116 | static final int TRANSACTION_deviceOffline = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1); 117 | } 118 | public void regist(java.lang.String appKey, java.lang.String appPackage) throws android.os.RemoteException; 119 | public void deviceOffline(java.lang.String appPackage) throws android.os.RemoteException; 120 | } 121 | -------------------------------------------------------------------------------- /src/com/netty/client/android/dao/DeviceDao.java: -------------------------------------------------------------------------------- 1 | package com.netty.client.android.dao; 2 | 3 | import android.database.Cursor; 4 | import android.database.sqlite.SQLiteDatabase; 5 | import android.database.sqlite.SQLiteStatement; 6 | 7 | import de.greenrobot.dao.AbstractDao; 8 | import de.greenrobot.dao.Property; 9 | import de.greenrobot.dao.internal.DaoConfig; 10 | 11 | import com.netty.client.android.dao.Device; 12 | 13 | // THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT. 14 | /** 15 | * DAO for table t_device. 16 | */ 17 | public class DeviceDao extends AbstractDao { 18 | 19 | public static final String TABLENAME = "t_device"; 20 | 21 | /** 22 | * Properties of entity Device.
23 | * Can be used for QueryBuilder and for referencing column names. 24 | */ 25 | public static class Properties { 26 | public final static Property Id = new Property(0, Long.class, "id", true, "_id"); 27 | public final static Property AppKey = new Property(1, String.class, "appKey", false, "APP_KEY"); 28 | public final static Property DeviceId = new Property(2, String.class, "deviceId", false, "DEVICE_ID"); 29 | public final static Property Imei = new Property(3, String.class, "imei", false, "IMEI"); 30 | public final static Property AppPackage = new Property(4, String.class, "appPackage", false, "APP_PACKAGE"); 31 | public final static Property RegId = new Property(5, String.class, "regId", false, "REG_ID"); 32 | public final static Property IsOnline = new Property(6, Integer.class, "isOnline", false, "IS_ONLINE"); 33 | }; 34 | 35 | 36 | public DeviceDao(DaoConfig config) { 37 | super(config); 38 | } 39 | 40 | public DeviceDao(DaoConfig config, DaoSession daoSession) { 41 | super(config, daoSession); 42 | } 43 | 44 | /** Creates the underlying database table. */ 45 | public static void createTable(SQLiteDatabase db, boolean ifNotExists) { 46 | String constraint = ifNotExists? "IF NOT EXISTS ": ""; 47 | db.execSQL("CREATE TABLE " + constraint + "'t_device' (" + // 48 | "'_id' INTEGER PRIMARY KEY AUTOINCREMENT ," + // 0: id 49 | "'APP_KEY' TEXT," + // 1: appKey 50 | "'DEVICE_ID' TEXT," + // 2: deviceId 51 | "'IMEI' TEXT," + // 3: imei 52 | "'APP_PACKAGE' TEXT," + // 4: appPackage 53 | "'REG_ID' TEXT," + // 5: regId 54 | "'IS_ONLINE' INTEGER);"); // 6: isOnline 55 | } 56 | 57 | /** Drops the underlying database table. */ 58 | public static void dropTable(SQLiteDatabase db, boolean ifExists) { 59 | String sql = "DROP TABLE " + (ifExists ? "IF EXISTS " : "") + "'t_device'"; 60 | db.execSQL(sql); 61 | } 62 | 63 | /** @inheritdoc */ 64 | @Override 65 | protected void bindValues(SQLiteStatement stmt, Device entity) { 66 | stmt.clearBindings(); 67 | 68 | Long id = entity.getId(); 69 | if (id != null) { 70 | stmt.bindLong(1, id); 71 | } 72 | 73 | String appKey = entity.getAppKey(); 74 | if (appKey != null) { 75 | stmt.bindString(2, appKey); 76 | } 77 | 78 | String deviceId = entity.getDeviceId(); 79 | if (deviceId != null) { 80 | stmt.bindString(3, deviceId); 81 | } 82 | 83 | String imei = entity.getImei(); 84 | if (imei != null) { 85 | stmt.bindString(4, imei); 86 | } 87 | 88 | String appPackage = entity.getAppPackage(); 89 | if (appPackage != null) { 90 | stmt.bindString(5, appPackage); 91 | } 92 | 93 | String regId = entity.getRegId(); 94 | if (regId != null) { 95 | stmt.bindString(6, regId); 96 | } 97 | 98 | Integer isOnline = entity.getIsOnline(); 99 | if (isOnline != null) { 100 | stmt.bindLong(7, isOnline); 101 | } 102 | } 103 | 104 | /** @inheritdoc */ 105 | @Override 106 | public Long readKey(Cursor cursor, int offset) { 107 | return cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0); 108 | } 109 | 110 | /** @inheritdoc */ 111 | @Override 112 | public Device readEntity(Cursor cursor, int offset) { 113 | Device entity = new Device( // 114 | cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0), // id 115 | cursor.isNull(offset + 1) ? null : cursor.getString(offset + 1), // appKey 116 | cursor.isNull(offset + 2) ? null : cursor.getString(offset + 2), // deviceId 117 | cursor.isNull(offset + 3) ? null : cursor.getString(offset + 3), // imei 118 | cursor.isNull(offset + 4) ? null : cursor.getString(offset + 4), // appPackage 119 | cursor.isNull(offset + 5) ? null : cursor.getString(offset + 5), // regId 120 | cursor.isNull(offset + 6) ? null : cursor.getInt(offset + 6) // isOnline 121 | ); 122 | return entity; 123 | } 124 | 125 | /** @inheritdoc */ 126 | @Override 127 | public void readEntity(Cursor cursor, Device entity, int offset) { 128 | entity.setId(cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0)); 129 | entity.setAppKey(cursor.isNull(offset + 1) ? null : cursor.getString(offset + 1)); 130 | entity.setDeviceId(cursor.isNull(offset + 2) ? null : cursor.getString(offset + 2)); 131 | entity.setImei(cursor.isNull(offset + 3) ? null : cursor.getString(offset + 3)); 132 | entity.setAppPackage(cursor.isNull(offset + 4) ? null : cursor.getString(offset + 4)); 133 | entity.setRegId(cursor.isNull(offset + 5) ? null : cursor.getString(offset + 5)); 134 | entity.setIsOnline(cursor.isNull(offset + 6) ? null : cursor.getInt(offset + 6)); 135 | } 136 | 137 | /** @inheritdoc */ 138 | @Override 139 | protected Long updateKeyAfterInsert(Device entity, long rowId) { 140 | entity.setId(rowId); 141 | return rowId; 142 | } 143 | 144 | /** @inheritdoc */ 145 | @Override 146 | public Long getKey(Device entity) { 147 | if(entity != null) { 148 | return entity.getId(); 149 | } else { 150 | return null; 151 | } 152 | } 153 | 154 | /** @inheritdoc */ 155 | @Override 156 | protected boolean isEntityUpdateable() { 157 | return true; 158 | } 159 | 160 | } 161 | -------------------------------------------------------------------------------- /src/com/netty/client/handler/PushMessageHandler.java: -------------------------------------------------------------------------------- 1 | package com.netty.client.handler; 2 | 3 | import io.netty.channel.ChannelHandlerContext; 4 | import io.netty.channel.SimpleChannelInboundHandler; 5 | import android.os.Handler; 6 | import android.os.Message; 7 | import android.util.Log; 8 | 9 | import com.netty.client.android.NettyServerManager; 10 | import com.netty.client.android.dao.Device; 11 | import com.netty.client.android.handler.MessageObject; 12 | import com.netty.client.android.handler.NettyProcessorHandler; 13 | import com.netty.client.android.service.RemoteService; 14 | import com.netty.client.context.ApplicationContextClient; 15 | import com.xwtec.protoc.CommandProtoc; 16 | import com.xwtec.protoc.CommandProtoc.PushMessage; 17 | 18 | /** 19 | * 客户端消息处理Handler 20 | * 21 | * @author maofw 22 | * 23 | */ 24 | public class PushMessageHandler extends SimpleChannelInboundHandler { 25 | private ApplicationContextClient applicationContextClient; 26 | 27 | private NettyServerManager mConnectionManager; 28 | private Handler mHandler; 29 | 30 | public PushMessageHandler(NettyServerManager connectionManager, Handler handler) { 31 | this.mConnectionManager = connectionManager; 32 | this.mHandler = handler; 33 | this.applicationContextClient = RemoteService.getApplicationContextClient(); 34 | } 35 | 36 | /** 37 | * 此方法会在连接到服务器后被调用 38 | */ 39 | @Override 40 | public void channelActive(ChannelHandlerContext ctx) throws Exception { 41 | // 激活后发送设备注册请求 42 | applicationContextClient.setCtx(ctx); 43 | // applicationContextClient.sendRegistrationMessage(null); 44 | } 45 | 46 | @Override 47 | protected void channelRead0(ChannelHandlerContext ctx, PushMessage t) throws Exception { 48 | try { 49 | Log.i(getClass().getName(), "channelRead0:" + t.toString()); 50 | } catch (Exception e) { 51 | System.out.println("channelRead0:======================\n" + t); 52 | } 53 | 54 | } 55 | 56 | private void channelReadMe(ChannelHandlerContext ctx, PushMessage t) { 57 | try { 58 | Log.i(getClass().getName(), "channelReadMe:" + t.toString()); 59 | } catch (Exception e) { 60 | System.out.println("channelReadMe:======================\n" + t); 61 | } 62 | if (t != null) { 63 | CommandProtoc.PushMessage.Type type = t.getType(); 64 | int what = -1; 65 | Object obj = null; 66 | String appPackage = null; 67 | switch (type) { 68 | case REGISTRATION_RESULT: 69 | // 註冊結果消息 70 | CommandProtoc.RegistrationResult registrationResult = t.getRegistrationResult(); 71 | what = NettyProcessorHandler.REGISTRATION_RESULT; 72 | obj = registrationResult; 73 | appPackage = registrationResult.getAppPackage(); 74 | break; 75 | case DEVICE_ONOFFLINE_RESULT: 76 | // 上下线结果消息 77 | CommandProtoc.DeviceOnoffResult deviceOnoffResult = t.getDeviceOnoffResult(); 78 | if (deviceOnoffResult != null) { 79 | CommandProtoc.Message.UserStatus userStatus = deviceOnoffResult.getUserStatus(); 80 | switch (userStatus) { 81 | case ONLINE: 82 | // 上线结果消息 83 | what = NettyProcessorHandler.DEVICE_ONLINE_RESULT; 84 | obj = deviceOnoffResult.getResCode(); 85 | appPackage = deviceOnoffResult.getAppPackage(); 86 | if (deviceOnoffResult.getResCode() == CommandProtoc.DeviceOnoffResult.ResultCode.SUCCESS) { 87 | // 更新设备信息 88 | Device device = applicationContextClient.getDeviceInfoByAppPackage(appPackage); 89 | if (device != null) { 90 | device.setIsOnline(ApplicationContextClient.DEVICE_ONLINE); 91 | //applicationContextClient.saveOrUpdateDevice(device); 92 | } 93 | } 94 | break; 95 | case OFFLINE: 96 | // 下线结果消息 97 | what = NettyProcessorHandler.DEVICE_OFFLINE_RESULT; 98 | obj = deviceOnoffResult.getResCode(); 99 | appPackage = deviceOnoffResult.getAppPackage(); 100 | if (deviceOnoffResult.getResCode() == CommandProtoc.DeviceOnoffResult.ResultCode.SUCCESS) { 101 | // 更新设备信息 102 | Device device = applicationContextClient.getDeviceInfoByAppPackage(appPackage); 103 | if (device != null) { 104 | // 删除设备信息 不会发送消息了 (客户端中设备 在线状态与服务端设备状态时不一样的:客户端设备下线标识需要向发送登陆消息 ,上线成功后不需要重复发送登陆请求,而不需要发送消息的时候需要将客户端service数据缓存清除 105 | // ,服务端设备上下线仅更新状态内容,不会删除信息) 106 | applicationContextClient.deleteDeviceInfo(device); 107 | // device.setIsOnline(ApplicationContextClient.DEVICE_OFFLINE); 108 | // applicationContextClient.saveOrUpdateDevice(device); 109 | } 110 | } 111 | break; 112 | default: 113 | break; 114 | } 115 | } 116 | break; 117 | case MESSAGE: 118 | // 消息处理 119 | CommandProtoc.Message commandMessage = t.getMessage(); 120 | if (commandMessage != null) { 121 | // 判断是否需要发送回执消息 122 | if (commandMessage.getIsReceipt()) { 123 | Device deviceInfo = applicationContextClient.getDeviceInfoByAppPackage(commandMessage.getAppPackage()); 124 | // 收到消息 需要通知服务器 发送消息回执内容 125 | applicationContextClient.sendReceiptMessage(deviceInfo, commandMessage.getMsgId()); 126 | } 127 | what = NettyProcessorHandler.MESSAGE; 128 | obj = commandMessage; 129 | appPackage = commandMessage.getAppPackage(); 130 | } 131 | break; 132 | default: 133 | break; 134 | } 135 | if (mHandler != null) { 136 | MessageObject mo = new MessageObject(); 137 | mo.setAppPackage(appPackage); 138 | mo.setObj(obj); 139 | // handler sendMessage 140 | Message message = mHandler.obtainMessage(); 141 | message.what = what; 142 | message.obj = mo; 143 | mHandler.sendMessage(message); 144 | } 145 | } 146 | } 147 | 148 | @Override 149 | public void channelRead(ChannelHandlerContext ctx, Object obj) throws Exception { 150 | if (obj != null && obj instanceof CommandProtoc.PushMessage) { 151 | channelReadMe(ctx, (CommandProtoc.PushMessage) obj); 152 | } 153 | } 154 | 155 | /** 156 | * 捕捉到异常 157 | */ 158 | @Override 159 | public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { 160 | Log.i(getClass().getName(), cause.getMessage()); 161 | cause.printStackTrace(); 162 | /** 163 | * 异常关闭连接启动重连操作 164 | */ 165 | // 首先更新连接状态 166 | mConnectionManager.setConnectState(NettyServerManager.CONNECT_EXCEPTION); 167 | // 更新设备状态 信息为离线 168 | applicationContextClient.offlineAllDevices(); 169 | ctx.close(); 170 | } 171 | 172 | @Override 173 | public void channelInactive(ChannelHandlerContext ctx) throws Exception { 174 | Log.i(getClass().getName(), "channelInactive"); 175 | /** 176 | * 异常关闭连接启动重连操作 177 | */ 178 | // 首先更新连接状态 179 | mConnectionManager.setConnectState(NettyServerManager.CONNECT_CLOSED); 180 | // 更新设备状态 信息为离线 181 | applicationContextClient.offlineAllDevices(); 182 | ctx.close(); 183 | } 184 | 185 | } 186 | -------------------------------------------------------------------------------- /src/com/netty/client/android/service/RemoteService.java: -------------------------------------------------------------------------------- 1 | package com.netty.client.android.service; 2 | 3 | import android.app.Service; 4 | import android.content.Context; 5 | import android.content.Intent; 6 | import android.content.IntentFilter; 7 | import android.net.ConnectivityManager; 8 | import android.os.IBinder; 9 | import android.os.RemoteException; 10 | import android.util.Log; 11 | 12 | import com.netty.client.android.NettyServerManager; 13 | import com.netty.client.android.aidl.NettyServiceClient.Stub; 14 | import com.netty.client.android.broadcast.AlarmReceiver; 15 | import com.netty.client.android.dao.DaoMaster; 16 | import com.netty.client.android.dao.DaoMaster.OpenHelper; 17 | import com.netty.client.android.dao.DaoSession; 18 | import com.netty.client.android.dao.Device; 19 | import com.netty.client.android.handler.NettyProcessorHandler; 20 | import com.netty.client.android.listener.ConnectionListener; 21 | import com.netty.client.android.listener.ServerStatusListener; 22 | import com.netty.client.consts.SystemConsts; 23 | import com.netty.client.context.ApplicationContextClient; 24 | 25 | /** 26 | * 远程服务 27 | * 28 | * @author maofw 29 | * 30 | */ 31 | public class RemoteService extends Service { 32 | 33 | private static ApplicationContextClient applicationContextClient = null;// ApplicationContextClient.getInstance(); 34 | 35 | private NettyServerManager mConnectionManager = null; 36 | private NettyProcessorHandler mNettyProcessorHandler = null; 37 | // 服務器连接成功后监听 38 | private ServerStatusListener mServerStatusListener = null; 39 | 40 | // 广播通知 41 | private AlarmReceiver alarmReceiver = null; 42 | 43 | /** 44 | * 45 | */ 46 | IBinder mBinder = new NettyServiceClientImpl(); 47 | 48 | Thread thread = null; 49 | 50 | /** 51 | * dao操作类 52 | */ 53 | private static DaoMaster daoMaster; 54 | 55 | private static DaoSession daoSession; 56 | 57 | private static Context mContext; 58 | 59 | @Override 60 | public void onCreate() { 61 | super.onCreate(); 62 | // 初始化 63 | init(); 64 | // 连接服务器 65 | connectServer(); 66 | // 注册广播 67 | if (alarmReceiver == null) { 68 | alarmReceiver = new AlarmReceiver(); 69 | } 70 | // 註冊廣播 71 | IntentFilter filter = new IntentFilter(); 72 | // 心跳action 73 | filter.addAction(AlarmReceiver.ACTION); 74 | // 连接action 75 | filter.addAction(AlarmReceiver.CONNECT_ACTION); 76 | // 切换网络action 77 | filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); 78 | registerReceiver(alarmReceiver, filter); 79 | } 80 | 81 | /** 82 | * 初始化 83 | */ 84 | private void init() { 85 | mContext = this; 86 | if (mNettyProcessorHandler == null) { 87 | mNettyProcessorHandler = new NettyProcessorHandler(this); 88 | } 89 | if (mServerStatusListener == null) { 90 | mServerStatusListener = new ServerStatusListener(); 91 | } 92 | 93 | if (applicationContextClient == null) { 94 | applicationContextClient = new ApplicationContextClient(mContext); 95 | } 96 | } 97 | 98 | @Override 99 | public void onDestroy() { 100 | Log.i(getClass().getName(), "onDestroy"); 101 | if (applicationContextClient != null) { 102 | // 下线所有设备 并且设置数据库下线状态 103 | applicationContextClient.offlineAllDevices(); 104 | applicationContextClient.destory(); 105 | applicationContextClient = null; 106 | } 107 | if (mServerStatusListener != null) { 108 | mServerStatusListener.destory(); 109 | mServerStatusListener = null; 110 | } 111 | mNettyProcessorHandler = null; 112 | daoSession.clear(); 113 | daoMaster = null; 114 | if (thread != null) { 115 | thread.interrupt(); 116 | thread = null; 117 | } 118 | if (alarmReceiver != null) { 119 | // 解除广播 120 | unregisterReceiver(alarmReceiver); 121 | } 122 | super.onDestroy(); 123 | } 124 | 125 | /** 126 | * 连接服务器 127 | */ 128 | private void connectServer() { 129 | Log.i(RemoteService.class.getName(), "connectServer"); 130 | if (mConnectionManager == null) { 131 | mConnectionManager = NettyServerManager.getInstance(RemoteService.this, mNettyProcessorHandler); 132 | } 133 | Log.i(RemoteService.class.getName(), "connectServer connectState:" + mConnectionManager.getConnectState()); 134 | if (mConnectionManager != null && !mConnectionManager.isConnected()) { 135 | if (thread == null) { 136 | thread = new Thread() { 137 | public void run() { 138 | 139 | try { 140 | mConnectionManager.connect(SystemConsts.HOST, SystemConsts.PORT, mServerStatusListener); 141 | } catch (Exception e) { 142 | e.printStackTrace(); 143 | } 144 | } 145 | }; 146 | } 147 | thread.start(); 148 | } 149 | } 150 | 151 | /** 152 | * @author mrsimple 153 | */ 154 | class NettyServiceClientImpl extends Stub { 155 | 156 | @Override 157 | public void regist(String appKey, String appPackage) throws RemoteException { 158 | Log.i(RemoteService.class.getName(), "connect"); 159 | if (mConnectionManager == null) { 160 | mConnectionManager = NettyServerManager.getInstance(RemoteService.this, mNettyProcessorHandler); 161 | } 162 | if (mConnectionManager != null) { 163 | Log.i(RemoteService.class.getName(), "regist connectState:" + mConnectionManager.getConnectState()); 164 | // 服务连接成功 后监听 165 | ConnectionListener connectionListener = new ConnectionListener(RemoteService.this, appKey, appPackage); 166 | if (mConnectionManager.isConnecting()) { 167 | // 注册ConnectionListener 当服务器连接成功 后通知 168 | mServerStatusListener.registNettyHandlerListener(connectionListener); 169 | } else if (mConnectionManager.isConnected()) { 170 | // 如果已经连接成功了 则 直接执行ConnectionListener 171 | connectionListener.callback(null); 172 | connectionListener = null; 173 | } else { 174 | // 服务器尚未连接 则进行server连接工作 175 | try { 176 | // 如果服务器正在连接状态则 等待 177 | mConnectionManager.connect(SystemConsts.HOST, SystemConsts.PORT, connectionListener); 178 | } catch (Exception e) { 179 | e.printStackTrace(); 180 | } 181 | } 182 | } 183 | } 184 | 185 | // @Override 186 | // public void deviceOnline(String appPackage) throws RemoteException { 187 | // Log.i(RemoteService.class.getName(), "deviceOnline"); 188 | // DeviceInfo deviceInfo = applicationContextClient.getDeviceInfoByAppPackage(appPackage); 189 | // applicationContextClient.sendDeviceOnlineMessage(deviceInfo, null); 190 | // 191 | // } 192 | 193 | @Override 194 | public void deviceOffline(String appPackage) throws RemoteException { 195 | Log.i(RemoteService.class.getName(), "deviceOffline"); 196 | Device deviceInfo = applicationContextClient.getDeviceInfoByAppPackage(appPackage); 197 | applicationContextClient.sendDeviceOfflineMessage(deviceInfo, null); 198 | } 199 | 200 | } 201 | 202 | /* 203 | * 返回Binder实例,即实现了ILogin接口的Stub的子类,这里为LoginStubImpl [url=home.php?mod=space&uid=133757]@see[/url] android.app.Service#onBind(android.content.Intent) 204 | */ 205 | @Override 206 | public IBinder onBind(Intent intent) { 207 | // 初始化 208 | init(); 209 | return mBinder; 210 | } 211 | 212 | @Override 213 | public boolean onUnbind(Intent intent) { 214 | return super.onUnbind(intent); 215 | } 216 | 217 | /** 218 | * 获取上下文环境 219 | * 220 | * @return 221 | */ 222 | public static final ApplicationContextClient getApplicationContextClient() { 223 | if (applicationContextClient == null) { 224 | applicationContextClient = new ApplicationContextClient(mContext); 225 | } 226 | return applicationContextClient; 227 | } 228 | 229 | /** 230 | * 取得DaoMaster 231 | * 232 | * @param context 233 | * @return 234 | */ 235 | public static DaoMaster getDaoMaster(Context context) { 236 | if (daoMaster == null) { 237 | OpenHelper helper = new DaoMaster.DevOpenHelper(context, SystemConsts.DATABASE_NAME, null); 238 | daoMaster = new DaoMaster(helper.getWritableDatabase()); 239 | } 240 | return daoMaster; 241 | } 242 | 243 | /** 244 | * 取得DaoSession 245 | * 246 | * @param context 247 | * @return 248 | */ 249 | public static DaoSession getDaoSession(Context context) { 250 | if (daoSession == null) { 251 | if (daoMaster == null) { 252 | daoMaster = getDaoMaster(context); 253 | } 254 | daoSession = daoMaster.newSession(); 255 | } 256 | return daoSession; 257 | } 258 | 259 | } 260 | -------------------------------------------------------------------------------- /src/com/netty/client/android/NettyServerManager.java: -------------------------------------------------------------------------------- 1 | package com.netty.client.android; 2 | 3 | import io.netty.bootstrap.Bootstrap; 4 | import io.netty.channel.ChannelFuture; 5 | import io.netty.channel.ChannelFutureListener; 6 | import io.netty.channel.ChannelInitializer; 7 | import io.netty.channel.ChannelOption; 8 | import io.netty.channel.ChannelPipeline; 9 | import io.netty.channel.EventLoopGroup; 10 | import io.netty.channel.nio.NioEventLoopGroup; 11 | import io.netty.channel.socket.SocketChannel; 12 | import io.netty.channel.socket.nio.NioSocketChannel; 13 | import io.netty.handler.codec.protobuf.ProtobufDecoder; 14 | import io.netty.handler.codec.protobuf.ProtobufEncoder; 15 | import io.netty.handler.codec.protobuf.ProtobufVarint32FrameDecoder; 16 | import io.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender; 17 | 18 | import java.net.InetSocketAddress; 19 | import java.net.SocketAddress; 20 | 21 | import android.content.Context; 22 | import android.util.Log; 23 | 24 | import com.google.protobuf.ExtensionRegistry; 25 | import com.netty.client.android.broadcast.NettyAlarmManager; 26 | import com.netty.client.android.handler.NettyProcessorHandler; 27 | import com.netty.client.android.listener.INettyHandlerListener; 28 | import com.netty.client.android.listener.ReConnectionListener; 29 | import com.netty.client.context.ApplicationContextClient; 30 | import com.netty.client.handler.PushMessageHandler; 31 | import com.xwtec.protoc.CommandProtoc; 32 | 33 | /** 34 | * 客户端连接类 35 | * 36 | * @author maofw 37 | * 38 | */ 39 | public class NettyServerManager { 40 | 41 | // 心跳監控週期 30s 42 | private EventLoopGroup group; 43 | // private ChannelFuture channelFuture; 44 | 45 | // private ApplicationContextClient applicationContextClient; 46 | 47 | private static NettyProcessorHandler mNettyProcessorHandler; 48 | 49 | private static NettyServerManager connectionManager = null; 50 | 51 | private static Context mContext; 52 | private String mHost; 53 | private int mPort; 54 | 55 | // private INetworkCallback mNetworkCallback; 56 | 57 | /** 58 | * 连接状态常量 59 | */ 60 | // 初始化 61 | public static final int CONNECT_INIT = 0; 62 | // 正在处理中 63 | public static final int CONNECT_PROCESSORING = 1; 64 | // 連接成功 65 | public static final int CONNECT_SUCCESS = 2; 66 | // 連接失敗 67 | public static final int CONNECT_FAILED = -1; 68 | // 連接关闭 69 | public static final int CONNECT_CLOSED = -2; 70 | // 連接超時 71 | public static final int CONNECT_TIMEOUT = -3; 72 | // 連接异常 73 | public static final int CONNECT_EXCEPTION = -4; 74 | // 连接状态 75 | private int connectState = CONNECT_INIT; 76 | 77 | public int getConnectState() { 78 | return connectState; 79 | } 80 | 81 | public void setConnectState(int connectState) { 82 | this.connectState = connectState; 83 | } 84 | 85 | /** 86 | * 构造方法传递Context和 appKey 87 | * 88 | * @param context 89 | * @param appKey 90 | */ 91 | private NettyServerManager(Context context, NettyProcessorHandler nettyProcessorHandler) { 92 | mContext = context; 93 | // mNetworkCallback = new DefaultNetworkCallback(context); 94 | mNettyProcessorHandler = nettyProcessorHandler; 95 | } 96 | 97 | public static NettyServerManager getInstance(Context context, NettyProcessorHandler nettyProcessorHandler) { 98 | if (connectionManager == null) { 99 | connectionManager = new NettyServerManager(context, nettyProcessorHandler); 100 | } 101 | return connectionManager; 102 | } 103 | 104 | /** 105 | * 重连 106 | */ 107 | public static void reconnect() throws Exception { 108 | if (connectionManager == null) { 109 | connectionManager = new NettyServerManager(mContext, mNettyProcessorHandler); 110 | } 111 | // connectionManager.mNetworkCallback.setConnected(false); 112 | connectionManager.reconnection(); 113 | } 114 | 115 | private void reconnection() throws Exception { 116 | this.connect(mHost, mPort, new ReConnectionListener()); 117 | } 118 | 119 | /** 120 | * 连接方法 121 | * 122 | * @param host 123 | * @param port 124 | * @throws Exception 125 | */ 126 | @SuppressWarnings("rawtypes") 127 | public void connect(final String host, final int port, final INettyHandlerListener connectionListener) throws Exception { 128 | Log.i(getClass().getName(), "connect come in!connectState=" + connectState); 129 | if (isConnected() || connectState == CONNECT_PROCESSORING) { 130 | // 連接成功 停止重连 131 | NettyAlarmManager.stopReconnection(); 132 | return; 133 | } 134 | Log.i(getClass().getName(), "connect come in!CONNECT_PROCESSORING!"); 135 | connectState = CONNECT_PROCESSORING; 136 | mHost = host; 137 | mPort = port; 138 | System.setProperty("java.net.preferIPv4Stack", "true"); 139 | System.setProperty("java.net.preferIPv6Addresses", "false"); 140 | ChannelFuture channelFuture = null; 141 | group = new NioEventLoopGroup(); 142 | try { 143 | Bootstrap b = new Bootstrap(); 144 | b.group(group); 145 | b.channel(NioSocketChannel.class); 146 | b.option(ChannelOption.SO_KEEPALIVE, true); 147 | b.option(ChannelOption.TCP_NODELAY, true); 148 | b.remoteAddress(new InetSocketAddress(mHost, mPort)); 149 | // 有连接到达时会创建一个channel 150 | final ExtensionRegistry registry = ExtensionRegistry.newInstance(); 151 | CommandProtoc.registerAllExtensions(registry); 152 | b.handler(new ChannelInitializer() { 153 | public void initChannel(SocketChannel ch) throws Exception { 154 | ChannelPipeline pipeline = ch.pipeline(); 155 | pipeline.addLast("frameDecoder", new ProtobufVarint32FrameDecoder()); 156 | pipeline.addLast("protobufDecoder", new ProtobufDecoder(CommandProtoc.PushMessage.getDefaultInstance(), registry)); 157 | pipeline.addLast("frameEncoder", new ProtobufVarint32LengthFieldPrepender()); 158 | pipeline.addLast("protobufEncoder", new ProtobufEncoder()); 159 | pipeline.addLast(new PushMessageHandler(connectionManager, mNettyProcessorHandler)); 160 | } 161 | }); 162 | channelFuture = b.connect().sync(); 163 | channelFuture.addListener(new ChannelFutureListener() { 164 | @SuppressWarnings("unchecked") 165 | public void operationComplete(ChannelFuture future) throws Exception { 166 | if (future.isSuccess()) { 167 | SocketAddress sa = future.channel().remoteAddress(); 168 | if(sa!=null){ 169 | Log.i(getClass().getName(), "netty server connected success! host:" + sa); 170 | // 連接成功 171 | connectState = CONNECT_SUCCESS; 172 | if (connectionListener != null) { 173 | connectionListener.callback(null); 174 | } 175 | // 启动心跳程序 176 | NettyAlarmManager.startHeart(mContext); 177 | // 連接成功 停止重连 178 | NettyAlarmManager.stopReconnection(); 179 | }else{ 180 | Log.i(getClass().getName(), "netty server connected failed! host:" + sa); 181 | // 連接失敗 182 | connectState = CONNECT_FAILED; 183 | // 連接 失敗 啟動重連 184 | future.cause().printStackTrace(); 185 | future.channel().close(); 186 | } 187 | } else { 188 | Log.i(getClass().getName(), "netty server attemp failed! host:" + future.channel().remoteAddress()); 189 | // 連接失敗 190 | connectState = CONNECT_FAILED; 191 | // 連接 失敗 啟動重連 192 | future.cause().printStackTrace(); 193 | future.channel().close(); 194 | // NettyAlarmManager.startReconnection(mContext); 195 | // if (mNetworkCallback != null) { 196 | // mNetworkCallback.connectFailed(); 197 | // } 198 | } 199 | } 200 | }); 201 | // Wait until the connection is closed. 202 | // channelFuture.channel().closeFuture().sync(); 203 | } catch (Exception e) { 204 | Log.i(getClass().getName(), e.getMessage()); 205 | connectState = CONNECT_EXCEPTION; 206 | // 连接关闭后启动重连 207 | NettyAlarmManager.startReconnection(mContext); 208 | } finally { 209 | Log.i(getClass().getName(), "connect finally!connectState=" + connectState); 210 | disconnect(channelFuture); 211 | } 212 | } 213 | 214 | // /** 215 | // * 设备上线消息请求 216 | // * 217 | // * @return 218 | // */ 219 | // public void sendDeviceOnlineMessage(INettyHandlerListener listener) { 220 | // this.applicationContextClient.sendDeviceOnlineMessage(listener); 221 | // } 222 | // 223 | // /** 224 | // * 设备上线消息请求 225 | // * 226 | // * @return 227 | // */ 228 | // public void sendDeviceOfflineMessage(INettyHandlerListener listener) { 229 | // this.applicationContextClient.sendDeviceOfflineMessage(listener); 230 | // } 231 | // 232 | // /** 233 | // * 添加用户自定义消息接收器 234 | // * 235 | // * @param listener 236 | // */ 237 | // public void addMessageListener(INettyHandlerListener listener) { 238 | // this.applicationContextClient.registListener(NettyProcessorHandler.MESSAGE, listener); 239 | // } 240 | 241 | /** 242 | * 断开连接 243 | */ 244 | public void disconnect(ChannelFuture channelFuture) throws Exception { 245 | if (channelFuture != null) { 246 | channelFuture.channel().closeFuture().addListener(new ChannelFutureListener() { 247 | @Override 248 | public void operationComplete(ChannelFuture channelFuture) throws Exception { 249 | if (channelFuture != null) { 250 | connectState = CONNECT_CLOSED; 251 | if (!group.isShutdown() && !group.isShuttingDown()) { 252 | group.shutdownGracefully();// .sync(); 253 | } 254 | // 已经关闭了 关闭心跳监控 255 | NettyAlarmManager.stopHeart(); 256 | if (ApplicationContextClient.isClosed) { 257 | // 主动关闭行为 258 | // 关闭重新连接定时任务 259 | NettyAlarmManager.stopReconnection(); 260 | Log.i(getClass().getName(), "stop netty server connection!" + channelFuture.channel().remoteAddress()); 261 | } else { 262 | // 被动关闭行为 263 | // 连接关闭后启动重连 264 | NettyAlarmManager.startReconnection(mContext); 265 | Log.i(getClass().getName(), "netty server closed success!" + channelFuture.channel().remoteAddress()); 266 | } 267 | } 268 | } 269 | }); 270 | } 271 | } 272 | 273 | /** 274 | * 是否連接 275 | * 276 | * @return 277 | */ 278 | public boolean isConnected() { 279 | return connectState == CONNECT_SUCCESS ? true : false; 280 | } 281 | 282 | /** 283 | * 是否連接正在进行中 284 | * 285 | * @return 286 | */ 287 | public boolean isConnecting() { 288 | boolean b = false; 289 | switch (connectState) { 290 | case CONNECT_INIT: 291 | case CONNECT_PROCESSORING: 292 | b = true; 293 | break; 294 | default: 295 | break; 296 | } 297 | return b; 298 | } 299 | 300 | public static void main(String[] args) { 301 | try { 302 | new NettyServerManager(null, null).connect("127.0.0.1", 6319, null); 303 | } catch (Exception e) { 304 | // TODO Auto-generated catch block 305 | e.printStackTrace(); 306 | } 307 | } 308 | } 309 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | 203 | -------------------------------------------------------------------------------- /src/com/netty/client/utils/Md5Util.java: -------------------------------------------------------------------------------- 1 | package com.netty.client.utils; 2 | 3 | /** 4 | *

5 | * Title: 6 | *

7 | *

8 | * Description: MD5数据加密 9 | *

10 | *

11 | * Copyright: Copyright (c) 2006 12 | *

13 | *

14 | * Company: 15 | *

16 | * 17 | * @author Tongzy 18 | * @version 1.0 19 | */ 20 | public class Md5Util { 21 | /* 22 | * 下面这些S11-S44实际上是一个4*4的矩阵,在原始的C实现中是用#define 实现的, 这里把它们实现成为static 23 | * final是表示了只读,切能在同一个进程空间内的多个 Instance间共享 24 | */ 25 | static final int S11 = 7; 26 | static final int S12 = 12; 27 | static final int S13 = 17; 28 | static final int S14 = 22; 29 | 30 | static final int S21 = 5; 31 | static final int S22 = 9; 32 | static final int S23 = 14; 33 | static final int S24 = 20; 34 | 35 | static final int S31 = 4; 36 | static final int S32 = 11; 37 | static final int S33 = 16; 38 | static final int S34 = 23; 39 | 40 | static final int S41 = 6; 41 | static final int S42 = 10; 42 | static final int S43 = 15; 43 | static final int S44 = 21; 44 | 45 | static final byte[] PADDING = { -128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48 | 0, 0, 0, 0, 0, 0, 0 }; 49 | /* 50 | * 下面的三个成员是MD5计算过程中用到的3个核心数据,在原始的C实现中 被定义到MD5_CTX结构中 51 | * 52 | */ 53 | private long[] state = new long[4]; // state (ABCD) 54 | private long[] count = new long[2]; // number of bits, modulo 2^64 (lsb 55 | // first) 56 | private byte[] buffer = new byte[64]; // input buffer 57 | 58 | /* 59 | * digestHexStr是MD5的唯一一个公共成员,是最新一次计算结果的 16进制ASCII表示. 60 | */ 61 | public String digestHexStr; 62 | 63 | /* 64 | * digest,是最新一次计算结果的2进制内部表示,表示128bit的MD5值. 65 | */ 66 | private byte[] digest = new byte[16]; 67 | 68 | /* 69 | * getMD5ofStr是类MD5最主要的公共方法,入口参数是你想要进行MD5变换的字符串 70 | * 返回的是变换完的结果,这个结果是从公共成员digestHexStr取得的. 71 | */ 72 | public String getMD5ofStr(String inbuf) { 73 | md5Init(); 74 | md5Update(inbuf.getBytes(), inbuf.length()); 75 | md5Final(); 76 | digestHexStr = ""; 77 | for (int i = 0; i < 16; i++) { 78 | digestHexStr += byteHEX(digest[i]); 79 | } 80 | return digestHexStr; 81 | } 82 | 83 | // 这是MD5这个类的标准构造函数,JavaBean要求有一个public的并且没有参数的构造函数 84 | public Md5Util() { 85 | md5Init(); 86 | return; 87 | } 88 | 89 | /* md5Init是一个初始化函数,初始化核心变量,装入标准的幻数 */ 90 | private void md5Init() { 91 | count[0] = 0L; 92 | count[1] = 0L; 93 | // /* Load magic initialization constants. 94 | 95 | state[0] = 0x67452301L; 96 | state[1] = 0xefcdab89L; 97 | state[2] = 0x98badcfeL; 98 | state[3] = 0x10325476L; 99 | 100 | return; 101 | } 102 | 103 | /* 104 | * F, G, H ,I 是4个基本的MD5函数,在原始的MD5的C实现中,由于它们是 105 | * 简单的位运算,可能出于效率的考虑把它们实现成了宏,在java中,我们把它们 实现成了private方法,名字保持了原来C中的。 106 | */ 107 | 108 | private long F(long x, long y, long z) { 109 | return (x & y) | ((~x) & z); 110 | 111 | } 112 | 113 | private long G(long x, long y, long z) { 114 | return (x & z) | (y & (~z)); 115 | 116 | } 117 | 118 | private long H(long x, long y, long z) { 119 | return x ^ y ^ z; 120 | } 121 | 122 | private long I(long x, long y, long z) { 123 | return y ^ (x | (~z)); 124 | } 125 | 126 | /* 127 | * FF,GG,HH和II将调用F,G,H,I进行近一步变换 FF, GG, HH, and II transformations for 128 | * rounds 1, 2, 3, and 4. Rotation is separate from addition to prevent 129 | * recomputation. 130 | */ 131 | 132 | private long FF(long a, long b, long c, long d, long x, long s, long ac) { 133 | a += F(b, c, d) + x + ac; 134 | a = ((int) a << s) | ((int) a >>> (32 - s)); 135 | a += b; 136 | return a; 137 | } 138 | 139 | private long GG(long a, long b, long c, long d, long x, long s, long ac) { 140 | a += G(b, c, d) + x + ac; 141 | a = ((int) a << s) | ((int) a >>> (32 - s)); 142 | a += b; 143 | return a; 144 | } 145 | 146 | private long HH(long a, long b, long c, long d, long x, long s, long ac) { 147 | a += H(b, c, d) + x + ac; 148 | a = ((int) a << s) | ((int) a >>> (32 - s)); 149 | a += b; 150 | return a; 151 | } 152 | 153 | private long II(long a, long b, long c, long d, long x, long s, long ac) { 154 | a += I(b, c, d) + x + ac; 155 | a = ((int) a << s) | ((int) a >>> (32 - s)); 156 | a += b; 157 | return a; 158 | } 159 | 160 | /* 161 | * md5Update是MD5的主计算过程,inbuf是要变换的字节串,inputlen是长度,这个 162 | * 函数由getMD5ofStr调用,调用之前需要调用md5init,因此把它设计成private的 163 | */ 164 | private void md5Update(byte[] inbuf, int inputLen) { 165 | 166 | int i, index, partLen; 167 | byte[] block = new byte[64]; 168 | index = (int) (count[0] >>> 3) & 0x3F; 169 | // /* Update number of bits */ 170 | if ((count[0] += (inputLen << 3)) < (inputLen << 3)) { 171 | count[1]++; 172 | } 173 | count[1] += (inputLen >>> 29); 174 | 175 | partLen = 64 - index; 176 | 177 | // Transform as many times as possible. 178 | if (inputLen >= partLen) { 179 | md5Memcpy(buffer, inbuf, index, 0, partLen); 180 | md5Transform(buffer); 181 | 182 | for (i = partLen; i + 63 < inputLen; i += 64) { 183 | 184 | md5Memcpy(block, inbuf, 0, i, 64); 185 | md5Transform(block); 186 | } 187 | index = 0; 188 | 189 | } else { 190 | 191 | i = 0; 192 | } 193 | 194 | // /* Buffer remaining input */ 195 | md5Memcpy(buffer, inbuf, index, i, inputLen - i); 196 | 197 | } 198 | 199 | /* 200 | * md5Final整理和填写输出结果 201 | */ 202 | private void md5Final() { 203 | byte[] bits = new byte[8]; 204 | int index, padLen; 205 | 206 | // /* Save number of bits */ 207 | Encode(bits, count, 8); 208 | 209 | // /* Pad out to 56 mod 64. 210 | index = (int) (count[0] >>> 3) & 0x3f; 211 | padLen = (index < 56) ? (56 - index) : (120 - index); 212 | md5Update(PADDING, padLen); 213 | 214 | // /* Append length (before padding) */ 215 | md5Update(bits, 8); 216 | 217 | // /* Store state in digest */ 218 | Encode(digest, state, 16); 219 | 220 | } 221 | 222 | /* 223 | * md5Memcpy是一个内部使用的byte数组的块拷贝函数,从input的inpos开始把len长度的 224 | * 字节拷贝到output的outpos位置开始 225 | */ 226 | 227 | private void md5Memcpy(byte[] output, byte[] input, int outpos, int inpos, 228 | int len) { 229 | int i; 230 | 231 | for (i = 0; i < len; i++) { 232 | output[outpos + i] = input[inpos + i]; 233 | } 234 | } 235 | 236 | /* 237 | * md5Transform是MD5核心变换程序,有md5Update调用,block是分块的原始字节 238 | */ 239 | private void md5Transform(byte block[]) { 240 | long a = state[0], b = state[1], c = state[2], d = state[3]; 241 | long[] x = new long[16]; 242 | 243 | Decode(x, block, 64); 244 | 245 | /* Round 1 */ 246 | a = FF(a, b, c, d, x[0], S11, 0xd76aa478L); /* 1 */ 247 | d = FF(d, a, b, c, x[1], S12, 0xe8c7b756L); /* 2 */ 248 | c = FF(c, d, a, b, x[2], S13, 0x242070dbL); /* 3 */ 249 | b = FF(b, c, d, a, x[3], S14, 0xc1bdceeeL); /* 4 */ 250 | a = FF(a, b, c, d, x[4], S11, 0xf57c0fafL); /* 5 */ 251 | d = FF(d, a, b, c, x[5], S12, 0x4787c62aL); /* 6 */ 252 | c = FF(c, d, a, b, x[6], S13, 0xa8304613L); /* 7 */ 253 | b = FF(b, c, d, a, x[7], S14, 0xfd469501L); /* 8 */ 254 | a = FF(a, b, c, d, x[8], S11, 0x698098d8L); /* 9 */ 255 | d = FF(d, a, b, c, x[9], S12, 0x8b44f7afL); /* 10 */ 256 | c = FF(c, d, a, b, x[10], S13, 0xffff5bb1L); /* 11 */ 257 | b = FF(b, c, d, a, x[11], S14, 0x895cd7beL); /* 12 */ 258 | a = FF(a, b, c, d, x[12], S11, 0x6b901122L); /* 13 */ 259 | d = FF(d, a, b, c, x[13], S12, 0xfd987193L); /* 14 */ 260 | c = FF(c, d, a, b, x[14], S13, 0xa679438eL); /* 15 */ 261 | b = FF(b, c, d, a, x[15], S14, 0x49b40821L); /* 16 */ 262 | 263 | /* Round 2 */ 264 | a = GG(a, b, c, d, x[1], S21, 0xf61e2562L); /* 17 */ 265 | d = GG(d, a, b, c, x[6], S22, 0xc040b340L); /* 18 */ 266 | c = GG(c, d, a, b, x[11], S23, 0x265e5a51L); /* 19 */ 267 | b = GG(b, c, d, a, x[0], S24, 0xe9b6c7aaL); /* 20 */ 268 | a = GG(a, b, c, d, x[5], S21, 0xd62f105dL); /* 21 */ 269 | d = GG(d, a, b, c, x[10], S22, 0x2441453L); /* 22 */ 270 | c = GG(c, d, a, b, x[15], S23, 0xd8a1e681L); /* 23 */ 271 | b = GG(b, c, d, a, x[4], S24, 0xe7d3fbc8L); /* 24 */ 272 | a = GG(a, b, c, d, x[9], S21, 0x21e1cde6L); /* 25 */ 273 | d = GG(d, a, b, c, x[14], S22, 0xc33707d6L); /* 26 */ 274 | c = GG(c, d, a, b, x[3], S23, 0xf4d50d87L); /* 27 */ 275 | b = GG(b, c, d, a, x[8], S24, 0x455a14edL); /* 28 */ 276 | a = GG(a, b, c, d, x[13], S21, 0xa9e3e905L); /* 29 */ 277 | d = GG(d, a, b, c, x[2], S22, 0xfcefa3f8L); /* 30 */ 278 | c = GG(c, d, a, b, x[7], S23, 0x676f02d9L); /* 31 */ 279 | b = GG(b, c, d, a, x[12], S24, 0x8d2a4c8aL); /* 32 */ 280 | 281 | /* Round 3 */ 282 | a = HH(a, b, c, d, x[5], S31, 0xfffa3942L); /* 33 */ 283 | d = HH(d, a, b, c, x[8], S32, 0x8771f681L); /* 34 */ 284 | c = HH(c, d, a, b, x[11], S33, 0x6d9d6122L); /* 35 */ 285 | b = HH(b, c, d, a, x[14], S34, 0xfde5380cL); /* 36 */ 286 | a = HH(a, b, c, d, x[1], S31, 0xa4beea44L); /* 37 */ 287 | d = HH(d, a, b, c, x[4], S32, 0x4bdecfa9L); /* 38 */ 288 | c = HH(c, d, a, b, x[7], S33, 0xf6bb4b60L); /* 39 */ 289 | b = HH(b, c, d, a, x[10], S34, 0xbebfbc70L); /* 40 */ 290 | a = HH(a, b, c, d, x[13], S31, 0x289b7ec6L); /* 41 */ 291 | d = HH(d, a, b, c, x[0], S32, 0xeaa127faL); /* 42 */ 292 | c = HH(c, d, a, b, x[3], S33, 0xd4ef3085L); /* 43 */ 293 | b = HH(b, c, d, a, x[6], S34, 0x4881d05L); /* 44 */ 294 | a = HH(a, b, c, d, x[9], S31, 0xd9d4d039L); /* 45 */ 295 | d = HH(d, a, b, c, x[12], S32, 0xe6db99e5L); /* 46 */ 296 | c = HH(c, d, a, b, x[15], S33, 0x1fa27cf8L); /* 47 */ 297 | b = HH(b, c, d, a, x[2], S34, 0xc4ac5665L); /* 48 */ 298 | 299 | /* Round 4 */ 300 | a = II(a, b, c, d, x[0], S41, 0xf4292244L); /* 49 */ 301 | d = II(d, a, b, c, x[7], S42, 0x432aff97L); /* 50 */ 302 | c = II(c, d, a, b, x[14], S43, 0xab9423a7L); /* 51 */ 303 | b = II(b, c, d, a, x[5], S44, 0xfc93a039L); /* 52 */ 304 | a = II(a, b, c, d, x[12], S41, 0x655b59c3L); /* 53 */ 305 | d = II(d, a, b, c, x[3], S42, 0x8f0ccc92L); /* 54 */ 306 | c = II(c, d, a, b, x[10], S43, 0xffeff47dL); /* 55 */ 307 | b = II(b, c, d, a, x[1], S44, 0x85845dd1L); /* 56 */ 308 | a = II(a, b, c, d, x[8], S41, 0x6fa87e4fL); /* 57 */ 309 | d = II(d, a, b, c, x[15], S42, 0xfe2ce6e0L); /* 58 */ 310 | c = II(c, d, a, b, x[6], S43, 0xa3014314L); /* 59 */ 311 | b = II(b, c, d, a, x[13], S44, 0x4e0811a1L); /* 60 */ 312 | a = II(a, b, c, d, x[4], S41, 0xf7537e82L); /* 61 */ 313 | d = II(d, a, b, c, x[11], S42, 0xbd3af235L); /* 62 */ 314 | c = II(c, d, a, b, x[2], S43, 0x2ad7d2bbL); /* 63 */ 315 | b = II(b, c, d, a, x[9], S44, 0xeb86d391L); /* 64 */ 316 | 317 | state[0] += a; 318 | state[1] += b; 319 | state[2] += c; 320 | state[3] += d; 321 | 322 | } 323 | 324 | /* 325 | * Encode把long数组按顺序拆成byte数组,因为java的long类型是64bit的, 只拆低32bit,以适应原始C实现的用途 326 | */ 327 | private void Encode(byte[] output, long[] input, int len) { 328 | int i, j; 329 | 330 | for (i = 0, j = 0; j < len; i++, j += 4) { 331 | output[j] = (byte) (input[i] & 0xffL); 332 | output[j + 1] = (byte) ((input[i] >>> 8) & 0xffL); 333 | output[j + 2] = (byte) ((input[i] >>> 16) & 0xffL); 334 | output[j + 3] = (byte) ((input[i] >>> 24) & 0xffL); 335 | } 336 | } 337 | 338 | /* 339 | * Decode把byte数组按顺序合成成long数组,因为java的long类型是64bit的, 340 | * 只合成低32bit,高32bit清零,以适应原始C实现的用途 341 | */ 342 | private void Decode(long[] output, byte[] input, int len) { 343 | int i, j; 344 | 345 | for (i = 0, j = 0; j < len; i++, j += 4) { 346 | output[i] = b2iu(input[j]) | (b2iu(input[j + 1]) << 8) 347 | | (b2iu(input[j + 2]) << 16) | (b2iu(input[j + 3]) << 24); 348 | } 349 | 350 | return; 351 | } 352 | 353 | /* 354 | * b2iu是我写的一个把byte按照不考虑正负号的原则的"升位"程序,因为java没有unsigned运算 355 | */ 356 | public static long b2iu(byte b) { 357 | return b < 0 ? b & 0x7F + 128 : b; 358 | } 359 | 360 | /* 361 | * byteHEX(),用来把一个byte类型的数转换成十六进制的ASCII表示, 362 | * 因为java中的byte的toString无法实现这一点,我们又没有C语言中的 sprintf(outbuf,"%02X",ib) 363 | */ 364 | public static String byteHEX(byte ib) { 365 | char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 366 | 'B', 'C', 'D', 'E', 'F' }; 367 | char[] ob = new char[2]; 368 | ob[0] = Digit[(ib >>> 4) & 0X0F]; 369 | ob[1] = Digit[ib & 0X0F]; 370 | String s = new String(ob); 371 | return s; 372 | } 373 | 374 | public static String toMD5(String source) { 375 | Md5Util md5 = new Md5Util(); 376 | return md5.getMD5ofStr(source); 377 | } 378 | 379 | public static void main(String[] args) { 380 | String s = "13775362424HC19HTW02452" + System.currentTimeMillis(); 381 | 382 | System.out.println(toMD5(s)); 383 | System.out.println(toMD5(s).length()); 384 | } 385 | 386 | } 387 | -------------------------------------------------------------------------------- /src/com/netty/client/context/ApplicationContextClient.java: -------------------------------------------------------------------------------- 1 | package com.netty.client.context; 2 | 3 | import io.netty.channel.ChannelHandlerContext; 4 | 5 | import java.util.ArrayList; 6 | import java.util.HashMap; 7 | import java.util.Iterator; 8 | import java.util.List; 9 | import java.util.Map; 10 | 11 | import android.content.Context; 12 | import android.net.wifi.WifiInfo; 13 | import android.net.wifi.WifiManager; 14 | import android.telephony.TelephonyManager; 15 | import android.util.Log; 16 | 17 | import com.netty.client.android.dao.Device; 18 | import com.netty.client.android.handler.NettyProcessorHandler; 19 | import com.netty.client.android.listener.INettyHandlerListener; 20 | import com.netty.client.android.listener.RegistrationResultListener; 21 | import com.netty.client.android.service.PushDbService; 22 | import com.netty.client.consts.SystemConsts; 23 | import com.netty.client.utils.Md5Util; 24 | import com.xwtec.protoc.CommandProtoc; 25 | 26 | /** 27 | * 客户端调用 28 | * 29 | * @author maofw 30 | * 31 | */ 32 | public class ApplicationContextClient { 33 | 34 | // 设备在线状态 35 | public static final int DEVICE_ONLINE = 1; 36 | public static final int DEVICE_OFFLINE = 0; 37 | 38 | // 是否关闭状态 39 | public static boolean isClosed = false; 40 | private ChannelHandlerContext ctx; 41 | private Map deviceInfos = new HashMap(); 42 | 43 | // 保存handler 回调Listener 44 | @SuppressWarnings("rawtypes") 45 | private Map> nettyHandlerListeners = new HashMap>(); 46 | 47 | private PushDbService pushDbService; 48 | private Context mContext; 49 | 50 | public ApplicationContextClient(Context context) { 51 | this.mContext = context; 52 | this.pushDbService = PushDbService.getInstance(context); 53 | } 54 | 55 | public ChannelHandlerContext getCtx() { 56 | return ctx; 57 | } 58 | 59 | public void setCtx(ChannelHandlerContext ctx) { 60 | this.ctx = ctx; 61 | } 62 | 63 | public void writeAndFlush(CommandProtoc.PushMessage pushMessage) { 64 | if (this.ctx != null) { 65 | this.ctx.writeAndFlush(pushMessage); 66 | } 67 | } 68 | 69 | public Map getDeviceInfos() { 70 | if (deviceInfos == null || deviceInfos.isEmpty()) { 71 | Map map = this.pushDbService.queryDevicesForMap(); 72 | if (map != null && map.size() > 0) { 73 | deviceInfos.putAll(map); 74 | } 75 | } 76 | return deviceInfos; 77 | } 78 | 79 | /** 80 | * 根据app包名获取设备信息 81 | * 82 | * @param appPackage 83 | * @return 84 | */ 85 | public Device getDeviceInfoByAppPackage(String appPackage) { 86 | Map map = this.getDeviceInfos(); 87 | if (map != null && !map.isEmpty()) { 88 | return map.get(appPackage); 89 | } 90 | return null; 91 | } 92 | 93 | /** 94 | * 註冊設備 95 | * 96 | * @param appKey 97 | * @param appPackage 98 | * @param deviceId 99 | * @param imei 100 | * @param regId 101 | * @return 102 | */ 103 | public void saveOrUpdateDevice(Device device) { 104 | if (device != null) { 105 | deviceInfos.put(device.getAppPackage(), device); 106 | this.pushDbService.saveOrUpdateDevice(device); 107 | } 108 | } 109 | 110 | /** 111 | * 生成Device对象 112 | * 113 | * @param appKey 114 | * @param appPackage 115 | * @param deviceId 116 | * @param imei 117 | * @return 118 | */ 119 | 120 | public Device makeDevice(Context context, String appKey, String appPackage) { 121 | 122 | Device deviceInfo = this.getDeviceInfoByAppPackage(appPackage); 123 | if (deviceInfo == null || (deviceInfo.getAppKey() != null && !deviceInfo.getAppKey().equals(appKey))) { 124 | TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); 125 | String imei = tm.getDeviceId(); 126 | 127 | String macAddress = null; 128 | WifiManager wifiMgr = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); 129 | WifiInfo info = (null == wifiMgr ? null : wifiMgr.getConnectionInfo()); 130 | if (null != info) { 131 | macAddress = info.getMacAddress(); 132 | } 133 | 134 | String deviceId = Md5Util.toMD5(SystemConsts.CHANNEL + appKey + macAddress + imei); 135 | if (deviceInfo == null) { 136 | deviceInfo = new Device(); 137 | } 138 | deviceInfo.setAppKey(appKey); 139 | deviceInfo.setAppPackage(appPackage); 140 | deviceInfo.setDeviceId(deviceId); 141 | deviceInfo.setImei(imei); 142 | deviceInfo.setIsOnline(DEVICE_OFFLINE); 143 | } 144 | return deviceInfo; 145 | } 146 | 147 | /** 148 | * 删除设备 149 | * 150 | * @param appPackage 151 | */ 152 | public void deleteDeviceInfo(Device deviceInfo) { 153 | if (deviceInfo != null) { 154 | this.pushDbService.deleteDevice(deviceInfo); 155 | // 删除缓存内容 156 | deviceInfos.remove(deviceInfo.getAppPackage()); 157 | } 158 | } 159 | 160 | public void offlineAllDevices() { 161 | if (deviceInfos != null && !deviceInfos.isEmpty()) { 162 | List list = new ArrayList(); 163 | Iterator> iterator = deviceInfos.entrySet().iterator(); 164 | while (iterator.hasNext()) { 165 | Map.Entry entry = iterator.next(); 166 | Device device = entry.getValue(); 167 | if (device != null) { 168 | device.setIsOnline(DEVICE_OFFLINE); 169 | list.add(device); 170 | } 171 | } 172 | this.pushDbService.saveOrUpdateDevices(list); 173 | list = null; 174 | } 175 | 176 | } 177 | 178 | @SuppressWarnings("rawtypes") 179 | public void registListener(String appPackage, Integer type, INettyHandlerListener listener) { 180 | if (listener != null) { 181 | Map mNettyHandlerListeners = nettyHandlerListeners.get(appPackage); 182 | INettyHandlerListener nettyHandlerListener = null; 183 | if (mNettyHandlerListeners == null) { 184 | mNettyHandlerListeners = new HashMap(); 185 | nettyHandlerListeners.put(appPackage, mNettyHandlerListeners); 186 | } else { 187 | nettyHandlerListener = mNettyHandlerListeners.get(type); 188 | if (nettyHandlerListener != null) { 189 | nettyHandlerListener = null; 190 | } 191 | } 192 | mNettyHandlerListeners.put(type, listener); 193 | } 194 | } 195 | 196 | @SuppressWarnings("rawtypes") 197 | public INettyHandlerListener getNettyHandlerListener(String appPackage, Integer type) { 198 | if (appPackage != null && type != null && nettyHandlerListeners.containsKey(appPackage)) { 199 | Map mNettyHandlerListeners = nettyHandlerListeners.get(appPackage); 200 | INettyHandlerListener nettyHandlerListener = mNettyHandlerListeners == null ? null : mNettyHandlerListeners.get(type); 201 | return nettyHandlerListener; 202 | } 203 | return null; 204 | } 205 | 206 | /** 207 | * 心跳请求 208 | * 209 | * @param listener 210 | */ 211 | public void sendHeartBeatMessage() { 212 | try { 213 | Log.i(ApplicationContextClient.class.getName(), "sendHeartBeatMessage"); 214 | } catch (Exception e) { 215 | System.out.println("sendHeartBeatMessage"); 216 | } 217 | if (ctx != null) { 218 | // 心跳请求 219 | CommandProtoc.PushMessage.Builder builder = this.createCommandPushMessage(CommandProtoc.PushMessage.Type.HEART_BEAT); 220 | ctx.writeAndFlush(builder.build()); 221 | } 222 | } 223 | 224 | /** 225 | * 设备注册请求 226 | * 227 | * @param ctx 228 | * @param imei 229 | * @param deviceId 230 | * @param appKey 231 | * @param appPackage 232 | */ 233 | public void sendRegistrationMessage(Device deviceInfo, INettyHandlerListener listener) { 234 | try { 235 | Log.i(ApplicationContextClient.class.getName(), "sendRegistrationMessage"); 236 | } catch (Exception e) { 237 | System.out.println("sendRegistrationMessage"); 238 | } 239 | // Log.i(ApplicationContextClient.class.getName(),"sendRegistrationMessage"); 240 | // 激活后发送设备注册请求 241 | if (deviceInfo != null) { 242 | if (listener == null && this.getNettyHandlerListener(deviceInfo.getAppPackage(), NettyProcessorHandler.REGISTRATION_RESULT) == null) { 243 | this.registListener(deviceInfo.getAppPackage(), NettyProcessorHandler.REGISTRATION_RESULT, new RegistrationResultListener(mContext, deviceInfo)); 244 | } else { 245 | this.registListener(deviceInfo.getAppPackage(), NettyProcessorHandler.REGISTRATION_RESULT, listener); 246 | } 247 | CommandProtoc.PushMessage pushMessage = this.createCommandRegistration(deviceInfo.getImei(), deviceInfo.getDeviceId(), deviceInfo.getAppKey(), 248 | deviceInfo.getAppPackage()); 249 | ctx.writeAndFlush(pushMessage); 250 | } 251 | } 252 | 253 | /** 254 | * 发送设备上线消息 255 | * 256 | * @param ctx 257 | * @param deviceId 258 | */ 259 | public void sendDeviceOnlineMessage(Device deviceInfo, INettyHandlerListener listener) { 260 | try { 261 | Log.i(ApplicationContextClient.class.getName(), "sendDeviceOnlineMessage"); 262 | } catch (Exception e) { 263 | System.out.println("sendDeviceOnlineMessage"); 264 | } 265 | if (deviceInfo != null) { 266 | this.registListener(deviceInfo.getAppPackage(), NettyProcessorHandler.DEVICE_ONLINE_RESULT, listener); 267 | CommandProtoc.PushMessage pushMessage = this.createCommandDeviceOnline(deviceInfo.getDeviceId()); 268 | ctx.writeAndFlush(pushMessage); 269 | } 270 | } 271 | 272 | /** 273 | * 发送设备下线消息 274 | * 275 | * @param ctx 276 | * @param deviceId 277 | */ 278 | public void sendDeviceOfflineMessage(Device deviceInfo, INettyHandlerListener listener) { 279 | try { 280 | Log.i(ApplicationContextClient.class.getName(), "sendDeviceOfflineMessage"); 281 | } catch (Exception e) { 282 | System.out.println("sendDeviceOfflineMessage"); 283 | } 284 | if (deviceInfo != null) { 285 | this.registListener(deviceInfo.getAppPackage(), NettyProcessorHandler.DEVICE_OFFLINE_RESULT, listener); 286 | CommandProtoc.PushMessage pushMessage = this.createCommandDeviceOffline(deviceInfo.getDeviceId()); 287 | ctx.writeAndFlush(pushMessage); 288 | } 289 | } 290 | 291 | /** 292 | * 发送消息确认回执消息 293 | * 294 | * @param ctx 295 | * @param appKey 296 | * @param msgId 297 | */ 298 | public void sendReceiptMessage(Device deviceInfo, String msgId) { 299 | try { 300 | Log.i(ApplicationContextClient.class.getName(), "sendReceiptMessage"); 301 | } catch (Exception e) { 302 | System.out.println("sendReceiptMessage"); 303 | } 304 | if (deviceInfo != null) { 305 | CommandProtoc.PushMessage pushMessage = this.createCommandMessageReceipt(deviceInfo.getAppKey(), deviceInfo.getRegId(), msgId); 306 | ctx.writeAndFlush(pushMessage); 307 | } 308 | } 309 | 310 | /** 311 | * 创建Registration对象 312 | * 313 | * @param type 314 | * @return 315 | */ 316 | public CommandProtoc.PushMessage createCommandRegistration(String imei, String deviceId, String appKey, String appPackage) { 317 | CommandProtoc.Registration.Builder builder = CommandProtoc.Registration.newBuilder(); 318 | builder.setImei(imei); 319 | builder.setDeviceId(deviceId); 320 | builder.setAppKey(appKey); 321 | builder.setAppPackage(appPackage); 322 | builder.setChannel(SystemConsts.CHANNEL); 323 | CommandProtoc.Registration commandProtoc = builder.build(); 324 | 325 | // 创建消息对象 326 | CommandProtoc.PushMessage.Builder messageBuilder = this.createCommandPushMessage(CommandProtoc.PushMessage.Type.REGISTRATION); 327 | messageBuilder.setRegistration(commandProtoc); 328 | return messageBuilder.build(); 329 | } 330 | 331 | /** 332 | * 创建DeviceOnline对象 333 | * 334 | * @param type 335 | * @return 336 | */ 337 | public CommandProtoc.PushMessage createCommandDeviceOnline(String deviceId) { 338 | CommandProtoc.DeviceOnline.Builder builder = CommandProtoc.DeviceOnline.newBuilder(); 339 | builder.setDeviceId(deviceId); 340 | CommandProtoc.DeviceOnline commandProtoc = builder.build(); 341 | 342 | // 创建消息对象 343 | CommandProtoc.PushMessage.Builder messageBuilder = this.createCommandPushMessage(CommandProtoc.PushMessage.Type.DEVICE_ONLINE); 344 | messageBuilder.setDeviceOnline(commandProtoc); 345 | return messageBuilder.build(); 346 | } 347 | 348 | /** 349 | * 创建DeviceOffline对象 350 | * 351 | * @param type 352 | * @return 353 | */ 354 | public CommandProtoc.PushMessage createCommandDeviceOffline(String deviceId) { 355 | CommandProtoc.DeviceOffline.Builder builder = CommandProtoc.DeviceOffline.newBuilder(); 356 | builder.setDeviceId(deviceId); 357 | CommandProtoc.DeviceOffline commandProtoc = builder.build(); 358 | 359 | // 创建消息对象 360 | CommandProtoc.PushMessage.Builder messageBuilder = this.createCommandPushMessage(CommandProtoc.PushMessage.Type.DEVICE_OFFLINE); 361 | messageBuilder.setDeviceOffline(commandProtoc); 362 | return messageBuilder.build(); 363 | } 364 | 365 | /** 366 | * 创建MessageReceipt对象 367 | * 368 | * @param type 369 | * @return 370 | */ 371 | public CommandProtoc.PushMessage createCommandMessageReceipt(String appKey, String registrationId, String msgId) { 372 | CommandProtoc.MessageReceipt.Builder builder = CommandProtoc.MessageReceipt.newBuilder(); 373 | builder.setAppKey(appKey); 374 | builder.setRegistrationId(registrationId); 375 | builder.setMsgId(msgId); 376 | CommandProtoc.MessageReceipt commandProtoc = builder.build(); 377 | // 创建消息对象 378 | CommandProtoc.PushMessage.Builder messageBuilder = this.createCommandPushMessage(CommandProtoc.PushMessage.Type.MESSAGE_RECEIPT); 379 | messageBuilder.setMessageReceipt(commandProtoc); 380 | return messageBuilder.build(); 381 | } 382 | 383 | /** 384 | * 创建发送消息对象 385 | * 386 | * @param type 387 | * @return 388 | */ 389 | private CommandProtoc.PushMessage.Builder createCommandPushMessage(CommandProtoc.PushMessage.Type type) { 390 | CommandProtoc.PushMessage.Builder builder = CommandProtoc.PushMessage.newBuilder(); 391 | builder.setType(type); 392 | return builder; 393 | } 394 | 395 | public void destory() { 396 | isClosed = true; 397 | if (this.deviceInfos != null) { 398 | this.deviceInfos.clear(); 399 | this.deviceInfos = null; 400 | } 401 | 402 | if (nettyHandlerListeners != null) { 403 | nettyHandlerListeners.clear(); 404 | nettyHandlerListeners = null; 405 | } 406 | 407 | pushDbService = null; 408 | if (ctx != null) { 409 | ctx.close(); 410 | ctx = null; 411 | } 412 | } 413 | } 414 | --------------------------------------------------------------------------------