XPush
A lightweight, pluggable Android message push framework. One key integration push (Aurora push, Friends push, Huawei, Mi push, etc.), provide effective survival mechanism, support push expansion, fully decouple push and business logic, free your hands!
Before asking an issue, please read the wisdom of Asking and fill in the issue template strictly to save your time.
Before use, please read the instructions carefully and say the important things three times!!
Before use, please read the instructions carefully and say the important things three times!!
Before use, please read the instructions carefully and say the important things three times!!
About me
Characteristics of the
-
Easy integration. Push integration takes just a few lines of code, and there are already push channels such as Aurora and Umeng, which can be expanded according to your needs.
-
Strong compatibility. Android 9.0 is now fully supported.
-
Powerful. Support push related registration, deregistration, tag increase, delete, access, alias binding, unbinding, access, push connection status access and other operations, and can return the response results; Supports push notifications, notification click events, and custom messages.
-
Unified message subscription. The framework provides a unified channel for subscribing to and unsubscribing to push messages from anywhere, no matter what kind of push you use, making it easier to receive and process messages.
-
Support for adding message filters. Interceptors, like those in OkHttp, can filter the incoming messages globally, filtering out the push messages that we really need.
-
Provide effective survival mechanism. Ensure the arrival rate and stability of notifications for applications that are connected to XPush, which many push frameworks cannot do.
The structure
This framework draws on some ideas in OnePush (which is no longer maintained), together with my 3-year experience in news push, and forms the following parts:
-
IPushClient: provides apis for the message push platform.
-
Message push event forwarder IPushDispatcher: Used to forward third-party message push events to events that can be recognized by XPush.
-
Message push receiver IPushReceiver: receives events forwarded by the IPushDispatcher in a unified manner. It is the event receiving center.
-
IMessageObservable: Manages the subscription and forwarding of push messages.
-
Filtering policy for push messages IMessageFilterStrategy: Filters, processes, and manages push messages.
The above five components can be customized to suit your own business needs.
Message Push Process
After sending a push message in the background:
Third party push platform -- (message) --> third party push platform internal receiving message Receiver --> (rewrite its receiving method) --> IPushDispatcher --> (forward message content as XPushMsg/XPushCommand) --> IPushReceiver --> (if you do not use the message management provided by XPushManager, this is the end) : --IPushReceiver-- > XPushManager -----> IMessageFilterStrategy --> IMessageObservable --> (The message is forwarded to the specific subscribed place)Copy the code
Why did you do this project
As anyone who has done Android notifications knows, not only is Android fragmented, but there are a lot of different platforms. As early as 2017, the Ministry of Industry and Information Technology (MIIT) called on all manufacturers to develop a unified Android message push platform, but so far there has been no following (the reason is that the benefits are too big and no one wants to compromise).
However, we can not put all our hopes on this completely uncertain event, code will be written after all, and function will be on, rather than being controlled by others, it is better to revolution themselves, to build a message push platform solution that can be controlled by themselves.
One might say, “Why do you want to build your own integration when both UmENG and Carrier Pigeon support vendor push integration?” It doesn’t really matter if you don’t have a requirement for promptness and availability (which, in practice, doesn’t work). What I need to explain here is that it is impossible for you to put your fate in the hands of others. Unlike other businesses, push is relatively complex and requires a large number of event messages to be processed, which requires a large demand on the server. Are you willing to give your push messages to a third-party push platform for processing? Besides, can you force your backend to access a specific third-party push platform? If not, instead of being controlled by others, why not grasp these destiny in their own hands, then write out the function of their own peace of mind ah.
Before the QQ communication group has been someone hope I open source a message push framework, in fact, I wrote a push framework in the last company, but the bundle business is too deep, coupled with the suspicion of avoiding leaks, there is no need to open source. This push framework is a complete rewrite, with a new design, will make the framework more general, flexible.
Quick Integration Guide
Add Gradle dependencies
1. Add repositories for Build. Gradle
allprojects {
repositories {
...
maven { url "https://jitpack.io" }
}
}
Copy the code
2. Add main dependencies for XPush:
dependencies { ... / / push core library implementation 'com. Making. Xuexiangjys. XPush: XPush - core: 1.0.0' / / push living library implementation 'com. Making. Xuexiangjys. XPush: keeplive: 1.0.0'}Copy the code
3. Add third-party push dependencies (add them according to your own needs, or all of them can be added)
dependencies { ... / / select what you want integration push library implementation 'com. Making. Xuexiangjys. XPush: XPush - jpush: 1.0.0' implementation 'com. Making. Xuexiangjys. XPush: XPush - umeng: 1.0.0' implementation 'com. Making. Xuexiangjys. XPush: XPush - huawei: 1.0.0' Implementation 'com. Making. Xuexiangjys. XPush: XPush - xiaomi: 1.0.0'}Copy the code
Initialize the XPush configuration
1. Register for the notification push receiver. There are two ways to do it. Just pick one.
-
If you want to use the message management provided by XPushManager, register the XPushReceiver provided by the framework default directly in AndroidManifest.xml. Of course, you can also inherit XPushReceiver and override the related methods.
-
If you want to implement your own message management, you can inherit AbstractPushReceiver class, override the methods in it, and register it in AndroidManifest.xml.
<! --> <receiver android:name=".push.customPushReceiver "> < Intent-filter > <action android:name="com.xuexiang.xpush.core.action.RECEIVE_CONNECT_STATUS_CHANGED" /> <action android:name="com.xuexiang.xpush.core.action.RECEIVE_NOTIFICATION" /> <action android:name="com.xuexiang.xpush.core.action.RECEIVE_NOTIFICATION_CLICK" /> <action android:name="com.xuexiang.xpush.core.action.RECEIVE_MESSAGE" /> <action android:name="com.xuexiang.xpush.core.action.RECEIVE_COMMAND_RESULT" /> <category android:name="${applicationId}" /> </intent-filter> </receiver> <! - the default message to push the receiver - > < receiver android: name = "com. Xuexiang. Xpush. Core. The receiver. The impl. XPushReceiver" > < intent - filter > < action android:name="com.xuexiang.xpush.core.action.RECEIVE_CONNECT_STATUS_CHANGED" /> <action android:name="com.xuexiang.xpush.core.action.RECEIVE_NOTIFICATION" /> <action android:name="com.xuexiang.xpush.core.action.RECEIVE_NOTIFICATION_CLICK" /> <action android:name="com.xuexiang.xpush.core.action.RECEIVE_MESSAGE" /> <action android:name="com.xuexiang.xpush.core.action.RECEIVE_COMMAND_RESULT" /> <category android:name="${applicationId}" /> </intent-filter> </receiver>Copy the code
Note that if your Android device is 8.0 or above, static registered broadcasts will not work properly. There are two ways to resolve this:
-
Dynamically register notification push receivers
-
Modify the emitter of the push message
If (build.version.sdk_int >= build.version_codes.o) {//Android8.0 static broadcast registration failed solution 1: Dynamic registration XPush. RegisterPushReceiver (new CustomPushReceiver ()); / / Android8.0 static radio registration failure solution 2: modify the launcher XPush. SetIPushDispatcher (new Android26PushDispatcherImpl (CustomPushReceiver. Class)); }Copy the code
2. Under the Application tag of AndroidManifest.xml, add the third party push client implementation class.
Note that the PlatformName and PlatformCode registered here must correspond to those in the push client implementation class.
<! XPush_[PlatformName]_[PlatformCode]--> <! --value format: path to the full class name of the corresponding client entity class --> <! - if introduced xpush - jpush library - > < meta - data android: name = "XPush_JPush_1000" android: value = "com. Xuexiang. Xpush. Jpush. JPushClient" / > <! <meta-data android:name="XPush_UMengPush_1001" android:value="com.xuexiang.xpush.umeng.UMengPushClient" /> <! <meta-data android:name="XPush_HuaweiPush_1002" android:value="com.xuexiang.xpush.huawei.HuaweiPushClient" /> <! <meta-data android:name="XPush_MIPush_1003" > <meta-data android:name="XPush_MIPush_1003" android:value="com.xuexiang.xpush.xiaomi.XiaoMiPushClient" />Copy the code
3. Add third-party AppKey and AppSecret.
AppKey and AppSecret need to be obtained by registering the application on the respective push platform. Note that if xpush-Xiaomi is used, then you need to add Xiaomi’s AppKey and AppSecret to AndroidManifest. XML (note that the ‘\’ below must be added, otherwise you will get float instead of String, The id and key will not get the correct data.
<! <meta-data android:name="JPUSH_CHANNEL" android:value="default_developer" /> <meta-data android:name="JPUSH_APPKEY" android:value="a32109db64ebe04e2430bb01" /> <! <meta-data android:name="UMENG_APPKEY" Android :value=" 5d5a42CE570DF37e850002e9 "/> <meta-data android:name="UMENG_MESSAGE_SECRET" android:value="4783a04255ed93ff675aca69312546f4" /> <! Static registration, huawei HMS push - > < meta - data android: name = "com. Huawei. HMS. Client. Appid" android: value = "101049475" / > <! -- Mi push static registration, the following "\" must be added, <meta-data android:name="MIPUSH_APPID" android:value="\ 2882303761518134164"/> <meta-data android:name="MIPUSH_APPKEY" android:value="\ 5371813415164"/>Copy the code
4. Initialize XPush in Application
There are two ways to initialize XPush. Select one method according to business needs.
- Static registration
/** * Static registration initialpush */ private void initPush() {xpush.debug (buildconfig.debug); Xpush. init(this, new UMengPushClient()); XPush.register(); }Copy the code
- Dynamic registration
/ / private void initPush() {xpush.debug (buildconfig.debug); // Dynamic registration, Xpush.init (this, new IPushInitCallback() {@override public Boolean onInitPush(int platformCode, String platformName) { String romName = RomUtils.getRom().getRomName(); if (romName.equals(SYS_EMUI)) { return platformCode == HuaweiPushClient.HUAWEI_PUSH_PLATFORM_CODE && platformName.equals(HuaweiPushClient.HUAWEI_PUSH_PLATFORM_NAME); } else if (romName.equals(SYS_MIUI)) { return platformCode == XiaoMiPushClient.MIPUSH_PLATFORM_CODE && platformName.equals(XiaoMiPushClient.MIPUSH_PLATFORM_NAME); } else { return platformCode == JPushClient.JPUSH_PLATFORM_CODE && platformName.equals(JPushClient.JPUSH_PLATFORM_NAME); }}}); XPush.register(); }Copy the code
How to use XPush
1. Push registration and deregistration
-
Push registration is completed by calling xpush.register ().
-
The push is logged out by calling xpush.unregister ().
-
By calling xpush.getPushToken (), you get the Token(Token) for the message push.
-
By calling xpush.getPlatformCode (), you get the code that is currently using the push platform.
2. Processing of pushed tags
-
You can addTags(passing multiple tags is supported) by calling xpush.addtags ().
-
By calling xpush.deletetags (), you can deleteTags(passing multiple tags is supported).
-
Get all the tags for the current device by calling xpush.gettags ().
It should be noted that Au push currently does not support the acquisition of labels, Huawei push does not support all the operations of labels, Xiaomi push only supports one label operation at a time.
3, push alias processing
-
The alias is bound by calling xpush.bindalias ().
-
The alias is unbound by calling xpush.unbindAlias ().
-
Get the alias to which the current device is bound by calling xpush.getalias ().
Note that UmENG Push currently does not support obtaining aliases, and Huawei Push does not support all operations on aliases.
4. Receiving push messages
-
You can receive push messages anywhere by calling the xpushManager.get ().register() method and registering for a message subscription to MessageSubscriber.
-
You can unsubscribe the message by calling the xpushManager.get ().unregister() method.
It is important to note here that the callback to the message subscription is not necessarily on the main thread, so make sure to switch to the main thread if there is any UI action in the callback. For reference, the following demo code uses XAOP, another of my open source libraries, to automatically switch to the MainThread using the @mainthread annotation alone.
/** * Initialize listeners */ @override protected void listeners () {xpushManager.get ().register(mMessageSubscriber); } private MessageSubscriber mMessageSubscriber = new MessageSubscriber() { @Override public void OnMessageReceived (CustomMessage message) {showMessage(string.format (" received CustomMessage :%s", message)); } @override public void onNotification(Notification Notification) {showMessage(String. Format (" received Notification :%s"), notification)); }}; @MainThread private void showMessage(String msg) { tvContent.setText(msg); } @Override public void onDestroyView() { XPushManager.get().unregister(mMessageSubscriber); super.onDestroyView(); }Copy the code
5. Filtering processing of push messages
-
The filtering processing of subscription push messages can be added by calling the xpushManager.get ().addfilter () method. For messages we don’t want to process, we can filter them through message filters.
-
The message filter is removed by calling the xpushManager.get ().removeFilter() method.
*/ @override protected void listeners () {xpushManager.get ().addFilter(mMessageFilter); } private IMessageFilter mMessageFilter = new IMessageFilter() { @Override public boolean filter(Notification Notification) {if (notification.getContent().contains("XPush")) {showMessage(" notification was intercepted "); return true; } return false; } @Override public boolean filter(CustomMessage message) { if (message.getMsg().contains("XPush")) { ShowMessage (" custom message intercepted "); return true; } return false; }}; @Override public void onDestroyView() { XPushManager.get().removeFilter(mMessageFilter); super.onDestroyView(); }Copy the code
6. Click processing of push notifications
We can be more elegant with notifications of click events, customizing their actions after a click and opening the page we want the user to see.
We can add the operation of opening the specified page to the onNotificationClick callback in the IPushReceiver for the global message push.
@Override public void onNotificationClick(Context context, XPushMsg msg) { super.onNotificationClick(context, msg); IntentUtils. GetIntent (context, testActivity. class, null, true); intent.putExtra(KEY_PARAM_STRING, msg.getContent()); intent.putExtra(KEY_PARAM_INT, msg.getId()); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); ActivityUtils.startActivity(intent); }Copy the code
Note that this requires you to push notifications from the messaging platform using a custom action or open a specified page type, and pass in Intent URI content in the following format:
-
Title: Indicates the title of the notification
-
Content: Indicates the content of the notification
-
ExtraMsg: An extended field attached to notifications that can hold JSON or other content
-
KeyValue: The key-value pair attached to the notification
xpush://com.xuexiang.xpush/notification? Title = this is a notification &content= this is the content of the notification &extramsg =xxxxxxxxx&keyValue={"param1": "1111", "param2": "2222"}Copy the code
Of course you can also customize the incoming Intent uri format, concrete can be reference in the project XPushNotificationClickActivity and AndroidManifest. XML
Platform Push
Currently supported push platforms
Push platform | The platform of | The platform code | Module name | The client class |
---|---|---|---|---|
The aurora push | JPush | 1000 | xpush-jpush | com.xuexiang.xpush.jpush.JPushClient |
Their Allies to push | UMengPush | 1001 | xpush-umeng | com.xuexiang.xpush.umeng.UMengPushClient |
Huawei’s push | HuaweiPush | 1002 | xpush-huawei | com.xuexiang.xpush.huawei.HuaweiPushClient |
Millet push | MIPush | 1003 | xpush-xiaomi | com.xuexiang.xpush.xiaomi.XiaoMiPushClient |
Push platform considerations
All features of aurora Push platform are supported.
Their Allies to push
-
In addition to being registered in the main process, the alliance push needs to be registered in the channel when XPush is initialized.
-
Amun push does not support the acquisition of Tag and alias
-
Umeng Push does not support monitoring the pushed connection status.
Huawei’s push
-
Huawei push needs to install the latest push service before registration. Otherwise, the registration fails (library upgrade or installation prompt is automatically displayed).
-
Huawei push does not support all Tag and alias operations.
-
Huawei push does not support notification arrival events.
Millet push
-
Xiaomi push can only operate one Tag at a time.
-
No result feedback from xiaomi push for logout.
-
Mi Push does not support monitoring the connection status of the push.
How to expand third-party push
Due to the large number of Android push platforms, it is not possible or necessary for this project to provide integration libraries for all push platforms. If I don’t have an integration library for the push platform you want to use, you’ll need to write your own.
In fact, expanding a third-party push library is not very difficult, as long as you follow the following 4 steps to complete:
-
1. Create a new Android Library Module and import the dependencies of the push platform you are going to integrate with. This includes introducing a push dependency library or SDK and configuring AndroidManifest.xml.
-
2. Create the client XXXClient of the push platform, implement the IPushClient interface, and rewrite the corresponding methods. Init, register, unRegister, getPlatformCode and getPlatformName must be overridden.
The IPushClient interface methods are as follows:
Public interface IPushClient {/** * initialize the IPushClient. ** @param context */ void init(context context); Void register(); / / void register(); Void unRegister(); /** * unRegister(); ** @param alias */ void bindAlias(String alias); /** * unBindAlias ** @param alias */ void unBindAlias(String alias); /** * Get the alias */ void getAlias(); /** * @param tag */ void addTags(String... tag); /** * @param tag */ void deleteTags(String... tag); /** * get tag */ void getTags(); /** * @return getPushToken */ String getPushToken(); /** * do not repeat [must] * @return getPlatformCode */ int getPlatformCode(); /** * do not repeat [must] * @return getPlatformName */ String getPlatformName(); }Copy the code
- 3. Create and rewrite a message Receiver (usually a rewrite Receiver) for the three-party message push. Override the three-party push to receive transparent messages and notifications method, call
XPush
The transmitXXX method of transmitXXX forwards notifications, transparent messages, notification click events, and other events to XPush.
The following five methods are invoked:
(1) xpush. transmitMessage(): forwards custom (transparent) messages.
(2) XPush. TransmitNotification () : message forwarding notice arrived.
(3) XPush. TransmitNotificationClick () : click event forwarding notice.
(4) XPush. TransmitCommandResult () : forward IPushClient command execution results.
(5) XPush. TransmitConnectStatusChanged () : forward push connection state change events.
- 4. Add code obfuscation configuration information corresponding to the push platform.
This completes the integration of the push platform. All that remains is to select the platform to push when you initialize XPush. If you still can’t, you can refer to xpush-Xiaomi and Xpush-Huawei in the project.
The entity is introduced
XPushMsg
Push message translation entity that carries the raw data of the message
The field name | type | note |
---|---|---|
mId | int | Message ID/status |
mTitle | String | Notice the title |
mContent | String | Inform the content |
mMsg | String | Custom (transparently transmitted) messages |
mExtraMsg | String | Message extension field |
mKeyValue | String | Message key-value pairs |
Notification
Push notifications, converted from XPushMsg
The field name | type | note |
---|---|---|
mId | int | Message ID/status |
mTitle | String | Notice the title |
mContent | String | Inform the content |
mExtraMsg | String | Message extension field |
mKeyValue | String | Message key-value pairs |
CustomMessage
Custom (pass-through) messages, converted from XPushMsg
The field name | type | note |
---|---|---|
mMsg | String | Custom (transparently transmitted) messages |
mExtraMsg | String | Message extension field |
mKeyValue | String | Message key-value pairs |
XPushCommand
IPushClient Indicates the result of executing commands
The field name | type | note |
---|---|---|
mType | int | Type the command |
mResultCode | int | The result code |
mContent | String | Command content |
mExtraMsg | String | Expand the fields |
mError | String | The error message |
Constant introduction
CommandType
Type of command
The command name | The command code | note |
---|---|---|
TYPE_REGISTER | 2000 | Registered push |
TYPE_UNREGISTER | 2001 | The cancellation of push |
TYPE_ADD_TAG | 2002 | Add tags |
TYPE_DEL_TAG | 2003 | Remove the label |
TYPE_GET_TAG | 2004 | The label |
TYPE_BIND_ALIAS | 2005 | Binding the alias |
TYPE_UNBIND_ALIAS | 2006 | Unbundling alias |
TYPE_GET_ALIAS | 2007 | To obtain an alias |
TYPE_AND_OR_DEL_TAG | 2008 | Add or delete labels |
ResultCode
Result code of a command
The results of | The result code | note |
---|---|---|
RESULT_OK | 0 | successful |
RESULT_ERROR | 1 | failure |
ConnectStatus
Push Connection Status
The state name | Status code | note |
---|---|---|
DISCONNECT | 10 | Has been disconnected |
CONNECTING | 11 | In the connection |
CONNECTED | 12 | The connected |
Confuse configuration
# XPush confusion - keep class * extends com. Xuexiang. XPush. Core. IPushClient {*; } -keep class * extends com.xuexiang.xpush.core.receiver.IPushReceiver{*; ** -keep class cn.jpush.** {*; } -dontwarn cn.jiguang.** -keep class cn.jiguang.** { *; } -keep class * extends cn.jpush.android.service.JPushMessageReceiver{*; } # umeng push -dontwarn com.umeng.** -dontwarn com.taobao.** -dontwarn anet.channel.** -dontwarn org.android.** -dontwarn org.apache.thrift.** -dontwarn com.xiaomi.** -dontwarn com.huawei.** -dontwarn com.meizu.** -keep class com.taobao.** {*; } -keep class org.android.** {*; } -keep class anet.channel.** {*; } -keep class com.xiaomi.** {*; } -keep class com.huawei.** {*; } -keep class com.meizu.** {*; } -keep class org.apache.thrift.** {*; } -keep class com.alibaba.sdk.android.**{*; } -keep class com.ut.**{*; } -keep class com.ta.**{*; } # keep class com.huawei.hms.**{*; } -keep class com.huawei.android.hms.agent.**{*; } # millet push - keep class * extends com. Xiaomi. Mipush. SDK. PushMessageReceiver {*; }Copy the code
Special thanks to
- OnePush
- keeplive
Wechat official account
For more information, please search wechat official account: “My Android Open Source Journey”