├── .gitignore
├── app
├── .gitignore
├── app-release.apk
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── bearever
│ │ └── pushdemo
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── bearever
│ │ │ └── pushdemo
│ │ │ ├── MainActivity.java
│ │ │ └── MyApplication.java
│ └── res
│ │ ├── layout
│ │ └── activity_main.xml
│ │ ├── mipmap-hdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-mdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ └── values
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test
│ └── java
│ └── com
│ └── bearever
│ └── pushdemo
│ └── ExampleUnitTest.java
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── img
├── PushMind.png
├── folder.png
├── 微信截图_20180531110846.png
├── 微信截图_20180531111009.png
├── 微信截图_20180531111115.png
└── 微信截图_20181009150639.png
├── push
├── .gitignore
├── build.gradle
├── libs
│ ├── HMS_SDK_2.6.0.301.jar
│ ├── MiPush_SDK_Client_3_6_2.jar
│ ├── arm64-v8a
│ │ └── libjcore121.so
│ ├── armeabi-v7a
│ │ └── libjcore121.so
│ ├── armeabi
│ │ └── libjcore121.so
│ ├── com.coloros.mcssdk.jar
│ ├── jcore-android-1.2.1.jar
│ ├── jpush-android-3.1.3.jar
│ ├── mips
│ │ └── libjcore121.so
│ ├── mips64
│ │ └── libjcore121.so
│ ├── push-internal-3.8.1.aar
│ ├── pushsdk_v2.3.4.jar
│ ├── x86
│ │ └── libjcore121.so
│ └── x86_64
│ │ └── libjcore121.so
├── proguard-rules.pro
├── readme.md
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ ├── bearever
│ │ └── push
│ │ │ ├── OnTokenGetListener.java
│ │ │ ├── PushTargetManager.java
│ │ │ ├── model
│ │ │ ├── PushTarget.java
│ │ │ ├── PushTargetEnum.java
│ │ │ └── ReceiverInfo.java
│ │ │ ├── receiver
│ │ │ ├── BasePushBroadcastReceiver.java
│ │ │ └── PushReceiverHandleManager.java
│ │ │ ├── target
│ │ │ ├── BasePushTargetInit.java
│ │ │ ├── huawei
│ │ │ │ ├── HuaweiInit.java
│ │ │ │ ├── HuaweiLoadActivity.java
│ │ │ │ └── HuaweiPushBroadcastReceiver.java
│ │ │ ├── jiguang
│ │ │ │ ├── IJPushEventReceiver.java
│ │ │ │ ├── JPushBroadcastReceiver.java
│ │ │ │ └── JPushInit.java
│ │ │ ├── meizu
│ │ │ │ ├── MeizuInit.java
│ │ │ │ └── MeizuMessageReceiver.java
│ │ │ ├── oppo
│ │ │ │ ├── OppoInit.java
│ │ │ │ ├── OppoLoadActivity.java
│ │ │ │ └── OppoMessageService.java
│ │ │ ├── vivo
│ │ │ │ ├── VivoBroadcastReceiver.java
│ │ │ │ └── VivoInit.java
│ │ │ └── xiaomi
│ │ │ │ ├── XiaomiBroadcastReceiver.java
│ │ │ │ └── XiaomiInit.java
│ │ │ └── util
│ │ │ └── ApplicationUtil.java
│ │ └── huawei
│ │ └── android
│ │ └── hms
│ │ └── agent
│ │ ├── HMSAgent.java
│ │ ├── common
│ │ ├── ActivityMgr.java
│ │ ├── ApiClientMgr.java
│ │ ├── BaseAgentActivity.java
│ │ ├── BaseApiAgent.java
│ │ ├── CallbackCodeRunnable.java
│ │ ├── CallbackResultRunnable.java
│ │ ├── EmptyConnectCallback.java
│ │ ├── HMSAgentActivity.java
│ │ ├── HMSAgentLog.java
│ │ ├── IActivityDestroyedCallback.java
│ │ ├── IActivityPauseCallback.java
│ │ ├── IActivityResumeCallback.java
│ │ ├── ICallbackCode.java
│ │ ├── ICallbackResult.java
│ │ ├── IClientConnectCallback.java
│ │ ├── INoProguard.java
│ │ ├── IOUtils.java
│ │ ├── StrUtils.java
│ │ ├── ThreadUtil.java
│ │ └── handler
│ │ │ └── ConnectHandler.java
│ │ └── push
│ │ ├── DeleteTokenApi.java
│ │ ├── EnableReceiveNormalMsgApi.java
│ │ ├── EnableReceiveNotifyMsgApi.java
│ │ ├── GetPushStateApi.java
│ │ ├── GetTokenApi.java
│ │ ├── QueryAgreementApi.java
│ │ └── handler
│ │ ├── DeleteTokenHandler.java
│ │ ├── EnableReceiveNormalMsgHandler.java
│ │ ├── EnableReceiveNotifyMsgHandler.java
│ │ ├── GetPushStateHandler.java
│ │ ├── GetTokenHandler.java
│ │ └── QueryAgreementHandler.java
│ └── res
│ ├── values-zh-rCN
│ └── hms_values-zh-rCN.xml
│ └── values
│ ├── colors.xml
│ ├── hms_values.xml
│ ├── strings.xml
│ └── styles.xml
├── pushdemo.jks
├── readme.md
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | .idea
5 | .DS_Store
6 | /build
7 | /captures
8 | .externalNativeBuild
9 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/app-release.apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Luomingbear/Push/49c3e097f97f403eec6ed903a4a81ca3044ec844/app/app-release.apk
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 26
5 | buildToolsVersion '26.0.2'
6 | defaultConfig {
7 | applicationId "com.bearever.pushdemo"
8 | minSdkVersion 15
9 | targetSdkVersion 26
10 | versionCode 1
11 | versionName "1.0"
12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
13 |
14 | }
15 |
16 | signingConfigs {
17 | // debug {
18 | // keyAlias 'pushdemo'
19 | // keyPassword '123456'
20 | // storeFile file('E:/AndroidStudioProjects/PushDemo/pushdemo.jks')
21 | // storePassword '123456'
22 | // }
23 | }
24 |
25 | buildTypes {
26 | release {
27 | minifyEnabled false
28 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
29 | }
30 |
31 | debug {
32 | // signingConfig signingConfigs.debug
33 |
34 | }
35 | }
36 |
37 | repositories {
38 | flatDir {
39 | dirs project(':push').file('libs')
40 | }
41 | }
42 |
43 | }
44 |
45 | dependencies {
46 |
47 | compile fileTree(include: ['*.jar'], dir: 'libs')
48 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
49 | exclude group: 'com.android.support', module: 'support-annotations'
50 | })
51 | compile 'com.android.support:appcompat-v7:26.+'
52 | compile 'com.android.support.constraint:constraint-layout:1.0.2'
53 | testCompile 'junit:junit:4.12'
54 | compile project(':push')
55 | }
56 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in D:\sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
19 | # Uncomment this to preserve the line number information for
20 | # debugging stack traces.
21 | #-keepattributes SourceFile,LineNumberTable
22 |
23 | # If you keep the line number information, uncomment this to
24 | # hide the original source file name.
25 | #-renamesourcefileattribute SourceFile
26 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/bearever/pushdemo/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.bearever.pushdemo;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumentation test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() throws Exception {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("com.bearever.pushdemo", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/java/com/bearever/pushdemo/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.bearever.pushdemo;
2 |
3 | import android.support.v7.app.AppCompatActivity;
4 | import android.os.Bundle;
5 |
6 | import com.bearever.push.PushTargetManager;
7 |
8 | public class MainActivity extends AppCompatActivity {
9 |
10 | @Override
11 | protected void onCreate(Bundle savedInstanceState) {
12 | super.onCreate(savedInstanceState);
13 | setContentView(R.layout.activity_main);
14 |
15 | PushTargetManager.getInstance().init(getApplication());
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/app/src/main/java/com/bearever/pushdemo/MyApplication.java:
--------------------------------------------------------------------------------
1 | package com.bearever.pushdemo;
2 |
3 | import android.app.Application;
4 |
5 | import com.bearever.push.PushTargetManager;
6 |
7 | /**
8 | * Created by luoming on 2018/5/28.
9 | */
10 |
11 | public class MyApplication extends Application {
12 | @Override
13 | public void onCreate() {
14 | super.onCreate();
15 |
16 | PushTargetManager.getInstance().init(this);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Luomingbear/Push/49c3e097f97f403eec6ed903a4a81ca3044ec844/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Luomingbear/Push/49c3e097f97f403eec6ed903a4a81ca3044ec844/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Luomingbear/Push/49c3e097f97f403eec6ed903a4a81ca3044ec844/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Luomingbear/Push/49c3e097f97f403eec6ed903a4a81ca3044ec844/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Luomingbear/Push/49c3e097f97f403eec6ed903a4a81ca3044ec844/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Luomingbear/Push/49c3e097f97f403eec6ed903a4a81ca3044ec844/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Luomingbear/Push/49c3e097f97f403eec6ed903a4a81ca3044ec844/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Luomingbear/Push/49c3e097f97f403eec6ed903a4a81ca3044ec844/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Luomingbear/Push/49c3e097f97f403eec6ed903a4a81ca3044ec844/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Luomingbear/Push/49c3e097f97f403eec6ed903a4a81ca3044ec844/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | PushDemo
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/test/java/com/bearever/pushdemo/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.bearever.pushdemo;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:2.3.3'
9 |
10 | // NOTE: Do not place your application dependencies here; they belong
11 | // in the individual module build.gradle files
12 | }
13 | }
14 |
15 | allprojects {
16 | repositories {
17 | jcenter()
18 | }
19 | }
20 |
21 | task clean(type: Delete) {
22 | delete rootProject.buildDir
23 | }
24 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | org.gradle.jvmargs=-Xmx1536m
13 |
14 | # When configured, Gradle will run in incubating parallel mode.
15 | # This option should only be used with decoupled projects. More details, visit
16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
17 | # org.gradle.parallel=true
18 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Luomingbear/Push/49c3e097f97f403eec6ed903a4a81ca3044ec844/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri May 25 16:35:40 CST 2018
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/img/PushMind.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Luomingbear/Push/49c3e097f97f403eec6ed903a4a81ca3044ec844/img/PushMind.png
--------------------------------------------------------------------------------
/img/folder.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Luomingbear/Push/49c3e097f97f403eec6ed903a4a81ca3044ec844/img/folder.png
--------------------------------------------------------------------------------
/img/微信截图_20180531110846.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Luomingbear/Push/49c3e097f97f403eec6ed903a4a81ca3044ec844/img/微信截图_20180531110846.png
--------------------------------------------------------------------------------
/img/微信截图_20180531111009.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Luomingbear/Push/49c3e097f97f403eec6ed903a4a81ca3044ec844/img/微信截图_20180531111009.png
--------------------------------------------------------------------------------
/img/微信截图_20180531111115.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Luomingbear/Push/49c3e097f97f403eec6ed903a4a81ca3044ec844/img/微信截图_20180531111115.png
--------------------------------------------------------------------------------
/img/微信截图_20181009150639.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Luomingbear/Push/49c3e097f97f403eec6ed903a4a81ca3044ec844/img/微信截图_20181009150639.png
--------------------------------------------------------------------------------
/push/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/push/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | android {
4 | compileSdkVersion 26
5 | buildToolsVersion '26.0.2'
6 |
7 | defaultConfig {
8 | manifestPlaceholders = [
9 | "jPushAppkey" : "ea6c961e572ad972df4ef456",//极光推送的AppKey
10 | "huaweiPushAppId" : "100698925",//华为推送的AppId
11 | "xiaomiPushAppkey": "55617974 54571",//"57417800 14675",//小米推送的AppKey****请务必在数值中间添加一个空格,否则会发生数值变化****
12 | "xiaomiPushAppId" : "28823037 61517974571",//"28823037 61517800675",//小米推送的AppID****请务必在数值中间添加一个空格,否则会发生数值变化****
13 | "oppoAppKey" : "9d24177594c741be86465ec9fe490a44",//OPPO推送的appKey
14 | "oppoAppSecret" : "c60bec1f803e49e88037562ec2109286",//OPPO推送的appSecret
15 | "meizuAppId" : "1200 55",//魅族推送AppId ****请务必在数值中间添加一个空格,否则会发生数值变化****
16 | "meizuAppKey" : "3aca7449444347c4a1d2a70826ae1e9b",//魅族推送AppKey
17 | "vivoAppId" : "11937",//vivo推送AppId
18 | "vivoAppKey" : "acfdb480-e178-4098-80ae-76284df7d588",//vivo推送AppKey
19 | "marketChannel" : "develops"//渠道
20 | ]
21 |
22 | minSdkVersion 15
23 | targetSdkVersion 26
24 | versionCode 1
25 | versionName "1.0"
26 |
27 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
28 | }
29 | buildTypes {
30 | release {
31 | minifyEnabled false
32 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
33 | }
34 | }
35 |
36 | sourceSets {
37 | main {
38 | jniLibs.srcDirs = ['libs']
39 | }
40 | }
41 | repositories {
42 | flatDir {
43 | dirs 'libs'
44 | }
45 | }
46 | }
47 |
48 | dependencies {
49 | compile fileTree(include: ['*.jar'], dir: 'libs')
50 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
51 | exclude group: 'com.android.support', module: 'support-annotations'
52 | })
53 | compile 'com.android.support:appcompat-v7:26.+'
54 | testCompile 'junit:junit:4.12'
55 | compile files('libs/jcore-android-1.2.1.jar')
56 | compile files('libs/jpush-android-3.1.3.jar')
57 | compile files('libs/MiPush_SDK_Client_3_6_2.jar')
58 | compile files('libs/HMS_SDK_2.6.0.301.jar')
59 | compile 'com.google.code.gson:gson:2.2.4'
60 | compile(name: 'push-internal-3.8.1', ext: 'aar')
61 |
62 | }
63 |
--------------------------------------------------------------------------------
/push/libs/HMS_SDK_2.6.0.301.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Luomingbear/Push/49c3e097f97f403eec6ed903a4a81ca3044ec844/push/libs/HMS_SDK_2.6.0.301.jar
--------------------------------------------------------------------------------
/push/libs/MiPush_SDK_Client_3_6_2.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Luomingbear/Push/49c3e097f97f403eec6ed903a4a81ca3044ec844/push/libs/MiPush_SDK_Client_3_6_2.jar
--------------------------------------------------------------------------------
/push/libs/arm64-v8a/libjcore121.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Luomingbear/Push/49c3e097f97f403eec6ed903a4a81ca3044ec844/push/libs/arm64-v8a/libjcore121.so
--------------------------------------------------------------------------------
/push/libs/armeabi-v7a/libjcore121.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Luomingbear/Push/49c3e097f97f403eec6ed903a4a81ca3044ec844/push/libs/armeabi-v7a/libjcore121.so
--------------------------------------------------------------------------------
/push/libs/armeabi/libjcore121.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Luomingbear/Push/49c3e097f97f403eec6ed903a4a81ca3044ec844/push/libs/armeabi/libjcore121.so
--------------------------------------------------------------------------------
/push/libs/com.coloros.mcssdk.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Luomingbear/Push/49c3e097f97f403eec6ed903a4a81ca3044ec844/push/libs/com.coloros.mcssdk.jar
--------------------------------------------------------------------------------
/push/libs/jcore-android-1.2.1.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Luomingbear/Push/49c3e097f97f403eec6ed903a4a81ca3044ec844/push/libs/jcore-android-1.2.1.jar
--------------------------------------------------------------------------------
/push/libs/jpush-android-3.1.3.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Luomingbear/Push/49c3e097f97f403eec6ed903a4a81ca3044ec844/push/libs/jpush-android-3.1.3.jar
--------------------------------------------------------------------------------
/push/libs/mips/libjcore121.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Luomingbear/Push/49c3e097f97f403eec6ed903a4a81ca3044ec844/push/libs/mips/libjcore121.so
--------------------------------------------------------------------------------
/push/libs/mips64/libjcore121.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Luomingbear/Push/49c3e097f97f403eec6ed903a4a81ca3044ec844/push/libs/mips64/libjcore121.so
--------------------------------------------------------------------------------
/push/libs/push-internal-3.8.1.aar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Luomingbear/Push/49c3e097f97f403eec6ed903a4a81ca3044ec844/push/libs/push-internal-3.8.1.aar
--------------------------------------------------------------------------------
/push/libs/pushsdk_v2.3.4.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Luomingbear/Push/49c3e097f97f403eec6ed903a4a81ca3044ec844/push/libs/pushsdk_v2.3.4.jar
--------------------------------------------------------------------------------
/push/libs/x86/libjcore121.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Luomingbear/Push/49c3e097f97f403eec6ed903a4a81ca3044ec844/push/libs/x86/libjcore121.so
--------------------------------------------------------------------------------
/push/libs/x86_64/libjcore121.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Luomingbear/Push/49c3e097f97f403eec6ed903a4a81ca3044ec844/push/libs/x86_64/libjcore121.so
--------------------------------------------------------------------------------
/push/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in D:\sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
19 | # Uncomment this to preserve the line number information for
20 | # debugging stack traces.
21 | #-keepattributes SourceFile,LineNumberTable
22 |
23 | # If you keep the line number information, uncomment this to
24 | # hide the original source file name.
25 | #-renamesourcefileattribute SourceFile
26 |
27 | #极光推送start
28 | -dontoptimize
29 | -dontpreverify
30 |
31 | -dontwarn cn.jpush.**
32 | -keep class cn.jpush.** { *; }
33 | -keep class * extends cn.jpush.android.helpers.JPushMessageReceiver { *; }
34 |
35 | -dontwarn cn.jiguang.**
36 | -keep class cn.jiguang.** { *; }
37 | #极光推送end
38 |
39 | #小米推送start
40 | -keep class com.bearever.push.target.xiaomi.XiaomiBroadcastReceiver {*;}
41 | -dontwarn com.xiaomi.push.**
42 | #小米推送end
43 |
44 | #华为推送start
45 | -ignorewarning
46 | -keepattributes *Annotation*
47 | -keepattributes Exceptions
48 | -keepattributes InnerClasses
49 | -keepattributes Signature
50 | -keepattributes SourceFile,LineNumberTable
51 | -keep class com.hianalytics.android.**{*;}
52 | -keep class com.huawei.updatesdk.**{*;}
53 | -keep class com.huawei.hms.**{*;}
54 |
55 | -keep class com.huawei.gamebox.plugin.gameservice.**{*;}
56 |
57 | -keep public class com.huawei.android.hms.agent.** extends android.app.Activity { public *; protected *; }
58 | -keep interface com.huawei.android.hms.agent.common.INoProguard {*;}
59 | -keep class * extends com.huawei.android.hms.agent.common.INoProguard {*;}
60 | #华为推送end
61 |
62 | #OPPO推送 start
63 | -keep public class * extends android.app.Service
64 | #OPPO推送 end
65 |
66 | #VIVO推送 start
67 | -dontwarn com.vivo.push.**-keep class com.vivo.push.**{*; }
68 | -keep class com.vivo.vms.**{*; }
69 | -keep class xxx.xxx.xxx.PushMessageReceiverImpl{*;}
70 | #VIVO推送 end
71 |
--------------------------------------------------------------------------------
/push/readme.md:
--------------------------------------------------------------------------------
1 |
2 | # Push
3 |
4 | 一个推送的模块,集成了华为、小米、魅族、OPPO和极光推送,根据设备厂商判断使用具体哪个SDK如:小米手机使用小米推送,华为手机使用华为推送,其他的设备使用极光推送。
5 |
6 | ## 更新时间
7 |
8 | 2019/04/18
9 |
10 | 添加统一接收消息的`BasePushBroadcastReceiver`和vivo推送平台
11 |
12 | ## 使用
13 |
14 | ### 1.配置AppKey
15 |
16 | 在您的app 的gradle配置文件里面添加如下代码:
17 |
18 | ```groovy
19 | defaultConfig {
20 | manifestPlaceholders = [
21 | "jPushAppkey" : "ea6c961e572ad972df4ef456",//极光推送的AppKey
22 | "huaweiPushAppId" : "100698925",//华为推送的AppId
23 | "xiaomiPushAppkey": "55617974 54571",//"57417800 14675",//小米推送的AppKey****请务必在数值中间添加一个空格,否则会发生数值变化****
24 | "xiaomiPushAppId" : "28823037 61517974571",//"28823037 61517800675",//小米推送的AppID****请务必在数值中间添加一个空格,否则会发生数值变化****
25 | "oppoAppKey" : "9d24177594c741be86465ec9fe490a44",//OPPO推送的appKey
26 | "oppoAppSecret" : "c60bec1f803e49e88037562ec2109286",//OPPO推送的appSecret
27 | "meizuAppId" : "1200 55",//魅族推送AppId ****请务必在数值中间添加一个空格,否则会发生数值变化****
28 | "meizuAppKey" : "3aca7449444347c4a1d2a70826ae1e9b",//魅族推送AppKey
29 | "vivoAppId" : "11937",//vivo推送AppId
30 | "vivoAppKey" : "acfdb480-e178-4098-80ae-76284df7d588",//vivo推送AppKey
31 | "marketChannel" : "develops"//渠道
32 | ]
33 | }
34 | ```
35 |
36 | 在push模块下面的`buid.gradle`文件里面替换对应的AppKey,**需要注意的地方**:
37 |
38 | > 小米的AppKey和魅族的AppId是使用的数字的格式,不能直接复制粘粘到文件里面,需要在中间增加一个空格,例如:AppKey为`201584151343514321321`需要替换为`20158415134 3514321321`
39 |
40 | ### 2.配置华为推送
41 |
42 | 华为推送的SDK是通过工具生成的,所以需要手动配置生成代码,先[下载华为HMS Agent套件](https://obs.cn-north-2.myhwclouds.com/hms-ds-wf/sdk/HMSAgent_2.6.1.302.zip),解压出来之后根据自己的电脑系统需要相应的脚本文件,例如:Window点击双击`GetHMSAgent_cn.bat`在弹出的窗口里面根据提示操作就好了,最后生存的代码会保存在`copysrc`文件夹里面。将生成的代码复制到Push的java目录下面,res资源文件根据需要添加到资源目录下。
43 |
44 | ### 3.初始化
45 |
46 | 在Application的onCreate里面调用`PushTargetManager`的`init`方法。
47 |
48 | ### 4.处理推送消息
49 |
50 | 推送的信息分为`Message`和`Notification`,Notification会主动在通知栏显示通知,而Message不会。
51 |
52 | 要处理接收到的信息,只需要实现`BasePushBroadcastReceiver`或者`PushTargetManager.getInstance().addPushReceiverListener(String, OnPushReceiverListener)`方法即可。
53 |
54 | #### 4.1自定义BasePushBroadcastReceiver
55 |
56 | ```java
57 | PushBroadcastReceiverIml extends BasePushBroadcastReceiver{
58 |
59 | public PushBroadcastReceiverIml() {
60 | }
61 |
62 | @Override
63 | public void onRegister(Context context, ReceiverInfo info) {
64 | Log.d(TAG, "推送注册成功\n" + info.toString());
65 | }
66 |
67 | @Override
68 | public void onAlias(Context context, ReceiverInfo info) {
69 | Log.d(TAG, "设置了别名\n" + info.toString());
70 | }
71 |
72 | @Override
73 | public void onMessage(Context context, ReceiverInfo info) {
74 | Log.d(TAG, "收到自定义消息\n" + info.toString());
75 | }
76 |
77 | @Override
78 | public void onNotification(Context context, ReceiverInfo info) {
79 | Log.d(TAG, "收到通知\n" + info.toString());
80 | }
81 |
82 | @Override
83 | public void onOpened(Context context, ReceiverInfo info) {
84 | Log.d(TAG, "点击了通知\n" + info.toString());
85 | }
86 | }
87 | ```
88 |
89 | 在`manifest`里面注册广播接收器
90 |
91 | ```xml
92 |
93 |
96 |
97 |
98 |
99 |
102 |
103 |
104 |
105 |
106 |
107 |
108 | ```
109 |
110 | #### 4.2addPushReceiverListener()
111 |
112 | ```java
113 | PushTargetManager.getInstance().addPushReceiverListener("ml",
114 | new PushTargetManager.OnPushReceiverListener() {
115 | @Override
116 | public void onRegister(ReceiverInfo info) {
117 | Log.d(TAG, "注册成功\n" + info.toString());
118 | }
119 |
120 | @Override
121 | public void onAlias(ReceiverInfo info) {
122 | Log.d(TAG, "设置了别名\n" + info.toString());
123 | }
124 |
125 | @Override
126 | public void onMessage(ReceiverInfo info) {
127 | Log.d(TAG, "收到了自定义消息\n" + info.toString());
128 | }
129 |
130 | @Override
131 | public void onNotification(ReceiverInfo info) {
132 | Log.d(TAG, "收到了通知\n" + info.toString());
133 | }
134 |
135 | @Override
136 | public void onOpened(ReceiverInfo info) {
137 | Log.d(TAG, "点击通知\n" + info.toString());
138 | }
139 | });
140 | ```
141 |
142 | **注意**:*使用这种方式有一个局限,就是只会在应用运行期间有回调,应用杀死之后就不会有反应了,所以推荐使用第一种方式。*
143 |
144 | ### 5.处理用户点击通知栏
145 |
146 | 针对用户点击通知栏的行为,我们可能需要对通知进行处理跳转到指定的页面。当有用户点击通知栏的时候`BasePushBroadcastReceiver`或者`OnPushReceiverListener`的`onOpened(Context context, ReceiverInfo info)`会执行,我们只需要在这里处理就可以了。**需要注意的是,华为和OPPO的事件处理使用的是一个虚拟的Activity进行中转。 **因为无法监听到用户点击的事件,但是可以在点击之后打开的页面里面获取到传递的数据,间接的进行处理。所以使用的时候需要和后端协商好推送类型为自定义参数的格式。
147 |
148 | > OPPO和华为的处理Activity分别为`OppoLoadActivity`、`HuaweiLoadActivity`具体的intent设置请按照自己的需求修改。
149 |
150 | 
151 |
152 | ### 6.设置别名
153 |
154 | 为了区别不同的设备与账号的对应关系,需要将设备别名设置到推送服务器和自己应用的服务器。* 当然,如果你不需要知道具体用户对于的设备,也可以不处理 *。 **别名的设置需要执行`PushTargetManager`的`setAlias`, **建议在注册成功之后再执行设置别名的操作,即在`HandleReceiverRegistration`的`handle`里面执行。 **需要注意的是华为推送不支持设置别名,只能获取华为服务器返回的`token` **。对于将别名上传到服务器的操作,用户只需要在`HandleReceiverAlias`类实现`handle`方法就可以了。
155 |
156 | 
157 |
158 | ### 7.获取注册id
159 |
160 | 在`BasePushBroadcastReceiver`或者`OnPushReceiverListener`的`onRegister(Context context, ReceiverInfo info)`会在推送sdk注册成功之后回调,所以,可以在这里获取注册id,此时的`ReceiverInfo`数据结构如下:
161 |
162 | | pushTarget | PushTargetEnum的枚举,表示了当前的推送平台 |
163 | | ---------- | ------------------------------------------ |
164 | | title | 提示文本,例如“小米推送注册成功” |
165 | | content | 注册id |
166 | | rawData | 推送平台注册成功之后的原始返回值 |
167 |
168 | ## 模块设计思路
169 |
170 | 通过对推送服务的分析,我将推送分为了三个步骤,分别是:初始化、接收和处理,不同的推送平台的接收方式并不一样,但是推送服务只是一个工具,接收推送之后的处理才是关键,而这个是不需要根据不同的平台来变化的,所以我使用了一个统一的处理入口。
171 |
172 | 
173 |
174 | 根据这个思路,我设计的代码结构如下:
175 |
176 | 
177 |
178 | | 目录 | 说明 |
179 | | ------ | ---------------------------------- |
180 | | Handle | 统一处理接收到的推送信息 |
181 | | Target | 将不同的推送平台的初始化和接收存放在这个目录里面,按照推送平台分类。 |
182 |
183 | 关于消息的处理,通常会有:SDK注册成功、接收到消息、用户点击通知栏等,所以我将不同的动作分配到具体的类里面,减少一个大类处理多个方法的问题,通过一个入口类管理具体的行为。
--------------------------------------------------------------------------------
/push/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
8 |
9 |
10 |
11 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
26 |
27 |
28 |
29 |
30 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
65 |
66 |
67 |
68 |
69 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
87 |
88 |
89 |
90 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
105 |
106 |
107 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
197 |
198 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
210 |
211 |
216 |
220 |
223 |
224 |
225 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
238 |
239 |
240 |
241 |
242 |
243 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
260 |
261 |
264 |
265 |
266 |
267 |
268 |
271 |
272 |
273 |
274 |
278 |
279 |
280 |
283 |
284 |
286 |
291 |
292 |
294 |
299 |
300 |
301 |
302 |
303 |
310 |
313 |
314 |
315 |
316 |
323 |
326 |
327 |
328 |
329 |
334 |
337 |
338 |
339 |
340 |
345 |
348 |
349 |
350 |
357 |
358 |
359 |
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
381 |
382 |
383 |
384 |
385 |
388 |
389 |
390 |
391 |
392 |
393 |
394 |
397 |
398 |
399 |
400 |
401 |
402 |
405 |
406 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
433 |
434 |
437 |
438 |
439 |
440 |
443 |
444 |
449 |
450 |
451 |
452 |
453 |
454 |
455 |
456 |
457 |
460 |
463 |
464 |
465 |
466 |
467 |
468 |
469 |
--------------------------------------------------------------------------------
/push/src/main/java/com/bearever/push/OnTokenGetListener.java:
--------------------------------------------------------------------------------
1 | package com.bearever.push;
2 |
3 | /**
4 | *
5 | */
6 | public interface OnTokenGetListener {
7 |
8 | void onGetTokenSuccess(String bussid, String token);
9 |
10 | }
11 |
--------------------------------------------------------------------------------
/push/src/main/java/com/bearever/push/PushTargetManager.java:
--------------------------------------------------------------------------------
1 | package com.bearever.push;
2 |
3 | import android.app.Application;
4 |
5 | import com.bearever.push.model.PushTargetEnum;
6 | import com.bearever.push.model.ReceiverInfo;
7 | import com.bearever.push.receiver.PushReceiverHandleManager;
8 | import com.bearever.push.target.BasePushTargetInit;
9 | import com.bearever.push.target.huawei.HuaweiInit;
10 | import com.bearever.push.target.jiguang.JPushInit;
11 | import com.bearever.push.target.meizu.MeizuInit;
12 | import com.bearever.push.target.oppo.OppoInit;
13 | import com.bearever.push.target.vivo.VivoInit;
14 | import com.bearever.push.target.xiaomi.XiaomiInit;
15 |
16 | /**
17 | * 初始化推送服务的管家,根据设备判断初始化哪个平台的推送服务;
18 | * *********
19 | * 注册广播接收消息
20 | * 实现 {@link com.bearever.push.receiver.BasePushBroadcastReceiver} 类,在manifest里面添加如下代码实现广播的接收
21 | *
24 | *
25 | *
26 | *
29 | *
30 | *
31 | *
32 | *
33 | *
34 | * --------------------
35 | * 另外一种是添加回调接口监听,执行{@link #addPushReceiverListener(String, OnPushReceiverListener)}添加推送回调接口
36 | * *********
37 | * Created by luoming on 2018/5/28.
38 | */
39 | public class PushTargetManager {
40 | private static final String TAG = "PushTargetManager";
41 | private static PushTargetManager instance;
42 | /**
43 | * 当前的推送平台
44 | */
45 | private PushTargetEnum mTarget = PushTargetEnum.XIAOMI;
46 | /**
47 | * 当前选择的推送方式
48 | */
49 | private BasePushTargetInit mPushTarget;
50 |
51 | /**
52 | * 广播的action
53 | */
54 | public static final String ACTION = "com.bearever.push.IPushBroadcast";
55 | /**
56 | * 广播的permission
57 | */
58 | public static final String PERMISSION = ".push.RECEIVER";
59 |
60 | public static PushTargetManager getInstance() {
61 | if (instance == null) {
62 | synchronized (PushTargetManager.class) {
63 | if (instance == null) {
64 | instance = new PushTargetManager();
65 | }
66 | }
67 | }
68 | return instance;
69 | }
70 |
71 | /**
72 | * 初始化
73 | *
74 | * @param context
75 | */
76 | public PushTargetManager init(Application context) {
77 | String mobile_brand = android.os.Build.MANUFACTURER;
78 | mobile_brand = mobile_brand.toUpperCase();
79 | //根据设备厂商选择推送平台
80 | //小米的使用小米推送,华为使用华为推送...其他的使用极光推送
81 | if (PushTargetEnum.XIAOMI.brand.equals(mobile_brand)) {
82 | this.mTarget = PushTargetEnum.XIAOMI;
83 | this.mPushTarget = new XiaomiInit(context);
84 | } else if (PushTargetEnum.HUAWEI.brand.equals(mobile_brand)) {
85 | this.mTarget = PushTargetEnum.HUAWEI;
86 | this.mPushTarget = new HuaweiInit(context);
87 | } else if (PushTargetEnum.OPPO.brand.equals(mobile_brand)) {
88 | this.mTarget = PushTargetEnum.OPPO;
89 | this.mPushTarget = new OppoInit(context);
90 | } else if (PushTargetEnum.VIVO.brand.equals(mobile_brand)) {
91 | this.mTarget = PushTargetEnum.VIVO;
92 | this.mPushTarget = new VivoInit(context);
93 | } else if (PushTargetEnum.MEIZU.brand.equals(mobile_brand)) {
94 | this.mTarget = PushTargetEnum.MEIZU;
95 | this.mPushTarget = new MeizuInit(context);
96 | } else {
97 | this.mTarget = PushTargetEnum.JPUSH;
98 | this.mPushTarget = new JPushInit(context);
99 | }
100 | PushReceiverHandleManager.getInstance().setPushTargetInit(mPushTarget);
101 | return this;
102 | }
103 |
104 | /**
105 | * 设置别名,华为不可用,需要通过@link 接口OnPushReceiverListener.onRegistration 方法回调取得
106 | *
107 | * @param alias 别名
108 | */
109 | public PushTargetManager setAliasExceptHuawei(String alias) {
110 | if (mPushTarget == null) {
111 | throw new NullPointerException("请先执行init(),然后在设置别名");
112 | }
113 | PushReceiverHandleManager.getInstance().setAlias(alias);
114 | return this;
115 | }
116 |
117 | /**
118 | * 添加推送监听
119 | *
120 | * @param key
121 | * @param listener
122 | */
123 | public void addPushReceiverListener(String key, OnPushReceiverListener listener) {
124 | PushReceiverHandleManager.getInstance().addPushReceiverListener(key, listener);
125 | }
126 |
127 | /**
128 | * 移除一个推送监听
129 | *
130 | * @param key
131 | */
132 | public void removePushReceiverListener(String key) {
133 | PushReceiverHandleManager.getInstance().removePushReceiverListener(key);
134 | }
135 |
136 | /**
137 | * 清空推送监听
138 | */
139 | public void clearPushReceiverListener() {
140 | PushReceiverHandleManager.getInstance().clearPushReceiverListener();
141 |
142 | }
143 |
144 | /**
145 | * 获取当前选择的推送平台
146 | *
147 | * @return
148 | */
149 | public PushTargetEnum getPushTarget() {
150 | return this.mTarget;
151 | }
152 |
153 | public interface OnPushReceiverListener {
154 | /**
155 | * 注册成功回调
156 | *
157 | * @param info info.getContent() 对应的就是具体的推送平台的注册id ,例如小米的regid和华为的TMID
158 | */
159 | void onRegister(ReceiverInfo info);
160 |
161 | /**
162 | * 别名设置完成回调
163 | *
164 | * @param info info.getContent() 对应的就是设置的别名
165 | */
166 | void onAlias(ReceiverInfo info);
167 |
168 | /**
169 | * 收到穿透消息的回调
170 | *
171 | * @param info info.getContent对应的是消息文本
172 | */
173 | void onMessage(ReceiverInfo info);
174 |
175 | /**
176 | * 收到通知的回调
177 | *
178 | * @param info info.getContent对应的是消息文本
179 | */
180 | void onNotification(ReceiverInfo info);
181 |
182 | /**
183 | * 点击通知的回调
184 | *
185 | * @param info info.getContent对应的是消息文本
186 | */
187 | void onOpened(ReceiverInfo info);
188 | }
189 | }
190 |
--------------------------------------------------------------------------------
/push/src/main/java/com/bearever/push/model/PushTarget.java:
--------------------------------------------------------------------------------
1 | package com.bearever.push.model;
2 |
3 | /**
4 | * 推送平台
5 | * Created by luoming on 2018/5/31.
6 | */
7 |
8 | public enum PushTarget {
9 | JPUSH, //极光
10 |
11 | XIAOMI, //小米
12 |
13 | HUAWEI,//华为
14 |
15 | OPPO,//oppo
16 |
17 | MEIZU; //魅族
18 | }
19 |
--------------------------------------------------------------------------------
/push/src/main/java/com/bearever/push/model/PushTargetEnum.java:
--------------------------------------------------------------------------------
1 | package com.bearever.push.model;
2 |
3 | /**
4 | * 推送平台
5 | * Created by luoming on 2018/5/31.
6 | */
7 |
8 | public enum PushTargetEnum {
9 | /**
10 | * 极光
11 | */
12 | JPUSH("JPUSH"),
13 |
14 | /**
15 | * 小米
16 | */
17 | XIAOMI("XIAOMI"),
18 |
19 | /**
20 | * 华为
21 | */
22 | HUAWEI("HUAWEI"),
23 |
24 | /**
25 | * OPPO
26 | */
27 | OPPO("OPPO"),
28 |
29 | /**
30 | * 魅族
31 | */
32 | MEIZU("MEIZU"),
33 |
34 | /**
35 | * VIVO
36 | */
37 | VIVO("VIVO");
38 |
39 | public String brand;
40 |
41 | PushTargetEnum(String brand) {
42 | this.brand = brand;
43 | }
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/push/src/main/java/com/bearever/push/model/ReceiverInfo.java:
--------------------------------------------------------------------------------
1 | package com.bearever.push.model;
2 |
3 | import java.io.Serializable;
4 |
5 | /**
6 | * 接收到的推送的消息
7 | * Created by luoming on 2018/5/28.
8 | */
9 | public class ReceiverInfo implements Serializable {
10 | private PushTargetEnum pushTarget = PushTargetEnum.JPUSH; //推送平台
11 | private String title = ""; //标题
12 | private String content = ""; //内容
13 | private String extra = ""; //额外数据
14 | private Object rawData; //原始数据
15 |
16 | public ReceiverInfo() {
17 | }
18 |
19 | public ReceiverInfo(PushTargetEnum pushTarget, String title, String content, String extra,
20 | Object rawData) {
21 | this.pushTarget = pushTarget;
22 | this.title = title;
23 | this.content = content;
24 | this.extra = extra;
25 | this.rawData = rawData;
26 | }
27 |
28 | public String getTitle() {
29 | return title;
30 | }
31 |
32 | public void setTitle(String title) {
33 | this.title = title;
34 | }
35 |
36 | public PushTargetEnum getPushTarget() {
37 | return pushTarget;
38 | }
39 |
40 | public void setPushTarget(PushTargetEnum pushTarget) {
41 | this.pushTarget = pushTarget;
42 | }
43 |
44 | public String getContent() {
45 | return content;
46 | }
47 |
48 | public void setContent(String content) {
49 | this.content = content;
50 | }
51 |
52 | public String getExtra() {
53 | return extra;
54 | }
55 |
56 | public void setExtra(String extra) {
57 | this.extra = extra;
58 | }
59 |
60 | public Object getRawData() {
61 | return rawData;
62 | }
63 |
64 | public void setRawData(Object rawData) {
65 | this.rawData = rawData;
66 | }
67 |
68 | @Override
69 | public String toString() {
70 | return "推送平台:" + getPushTarget().brand + "\ntitle:" + getTitle() + "\ncontent:" + getContent();
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/push/src/main/java/com/bearever/push/receiver/BasePushBroadcastReceiver.java:
--------------------------------------------------------------------------------
1 | package com.bearever.push.receiver;
2 |
3 | import android.content.BroadcastReceiver;
4 | import android.content.Context;
5 | import android.content.Intent;
6 |
7 | import com.bearever.push.model.ReceiverInfo;
8 | import com.google.gson.Gson;
9 |
10 | /**
11 | * 推送集成聚合广播接收器
12 | *
13 | * @author : malong luomingbear@163.com
14 | * @date : 2019/4/18
15 | **/
16 | public abstract class BasePushBroadcastReceiver extends BroadcastReceiver {
17 | public BasePushBroadcastReceiver() {
18 | }
19 |
20 | @Override
21 | public void onReceive(Context context, Intent intent) {
22 | if (intent == null) {
23 | return;
24 | }
25 |
26 | String json = intent.getStringExtra("receiverinfo");
27 | ReceiverInfo info = new Gson().fromJson(json, ReceiverInfo.class);
28 | // 根据推送平台确定原始数据的类型
29 | // PushTargetEnum pushTargetEnum = (PushTargetEnum) intent.getSerializableExtra("pushTarget");
30 | // switch (pushTargetEnum) {
31 | // case MEIZU:
32 | //
33 | // break;
34 | // case HUAWEI:
35 | // break;
36 | // case JPUSH:
37 | // break;
38 | // case OPPO:
39 | // break;
40 | // case VIVO:
41 | // break;
42 | // case XIAOMI:
43 | // break;
44 | // }
45 | int type = intent.getIntExtra("type", 0);
46 | switch (type) {
47 | case PushReceiverHandleManager.TYPE_REGISTRATION:
48 | onRegister(context, info);
49 | break;
50 | case PushReceiverHandleManager.TYPE_ALIAS:
51 | onAlias(context, info);
52 | break;
53 | case PushReceiverHandleManager.TYPE_NOTIFICATION:
54 | onNotification(context, info);
55 | break;
56 | case PushReceiverHandleManager.TYPE_MESSAGE:
57 | onMessage(context, info);
58 | break;
59 | case PushReceiverHandleManager.TYPE_OPEN:
60 | onOpened(context, info);
61 | break;
62 | default:
63 | break;
64 | }
65 | }
66 |
67 | /**
68 | * 注册成功回调
69 | *
70 | * @param info info.getContent() 对应的就是具体的推送平台的注册id ,例如小米的regid和华为的TMID
71 | */
72 | public abstract void onRegister(Context context, ReceiverInfo info);
73 |
74 | /**
75 | * 别名设置完成回调
76 | *
77 | * @param info info.getContent() 对应的就是设置的别名
78 | */
79 | public abstract void onAlias(Context context, ReceiverInfo info);
80 |
81 | /**
82 | * 收到穿透消息的回调
83 | *
84 | * @param info info.getContent对应的是消息文本
85 | */
86 | public abstract void onMessage(Context context, ReceiverInfo info);
87 |
88 | /**
89 | * 收到通知的回调
90 | *
91 | * @param info info.getContent对应的是消息文本
92 | */
93 | public abstract void onNotification(Context context, ReceiverInfo info);
94 |
95 | /**
96 | * 点击通知的回调
97 | *
98 | * @param info info.getContent对应的是消息文本
99 | */
100 | public abstract void onOpened(Context context, ReceiverInfo info);
101 | }
102 |
--------------------------------------------------------------------------------
/push/src/main/java/com/bearever/push/receiver/PushReceiverHandleManager.java:
--------------------------------------------------------------------------------
1 | package com.bearever.push.receiver;
2 |
3 | import android.content.ComponentName;
4 | import android.content.Context;
5 | import android.content.Intent;
6 | import android.content.pm.PackageManager;
7 | import android.content.pm.ResolveInfo;
8 | import android.os.Build;
9 | import android.text.TextUtils;
10 | import android.util.Log;
11 |
12 | import com.bearever.push.PushTargetManager;
13 | import com.bearever.push.model.ReceiverInfo;
14 | import com.bearever.push.target.BasePushTargetInit;
15 | import com.google.gson.Gson;
16 |
17 | import java.util.HashMap;
18 | import java.util.List;
19 | import java.util.Map;
20 |
21 | /**
22 | * 统一处理收到的推送
23 | * Created by luoming on 2018/5/28.
24 | */
25 | public class PushReceiverHandleManager {
26 | private static final String TAG = "PushReceiverHandleManag";
27 | private static PushReceiverHandleManager instance;
28 |
29 | private String mAlias = "";
30 | private BasePushTargetInit mPushTargetInit;
31 |
32 | /**
33 | * 待处理的消息列表
34 | */
35 | private HashMap mReceiverMap = new HashMap<>();
36 |
37 | /**
38 | * 注册行为
39 | */
40 | public static final int TYPE_REGISTRATION = 0;
41 | /**
42 | * 设置别名行为
43 | */
44 | public static final int TYPE_ALIAS = TYPE_REGISTRATION + 1;
45 | /**
46 | * 收到自定义消息行为
47 | */
48 | public static final int TYPE_MESSAGE = TYPE_ALIAS + 1;
49 | /**
50 | * 收到通知行为
51 | */
52 | public static final int TYPE_NOTIFICATION = TYPE_MESSAGE + 1;
53 | /**
54 | * 点击通知行为
55 | */
56 | public static final int TYPE_OPEN = TYPE_NOTIFICATION + 1;
57 |
58 | public static PushReceiverHandleManager getInstance() {
59 | if (instance == null) {
60 | synchronized (PushReceiverHandleManager.class) {
61 | if (instance == null) {
62 | instance = new PushReceiverHandleManager();
63 | }
64 | }
65 | }
66 | return instance;
67 | }
68 |
69 | private PushReceiverHandleManager() {
70 |
71 | }
72 |
73 | public void setPushTargetInit(BasePushTargetInit pushTargetInit) {
74 | this.mPushTargetInit = pushTargetInit;
75 | }
76 |
77 | /**
78 | * 发送广播
79 | *
80 | * @param context
81 | * @param type 行为类型
82 | * @param info
83 | */
84 | private void sendBroadcast(Context context, int type, ReceiverInfo info) {
85 | Log.d(TAG, "发送广播\nPackageName:" + context.getPackageName() + "\n" + info.toString());
86 | Intent intent = new Intent();
87 | intent.putExtra("receiverinfo", new Gson().toJson(info));
88 | intent.putExtra("type", type);
89 | intent.putExtra("pushTarget", info.getPushTarget());
90 | intent.setAction(PushTargetManager.ACTION);
91 |
92 | //Android O 之后限制了隐式广播的接收,需要主动注册接收器
93 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
94 | context.sendBroadcast(intent, context.getPackageName() + PushTargetManager.PERMISSION);
95 | } else {
96 | sendImplicitBroadcast(context, intent);
97 | }
98 | }
99 |
100 | /**
101 | * 发送隐式广播
102 | *
103 | * @param ctxt
104 | * @param i
105 | */
106 | private static void sendImplicitBroadcast(Context ctxt, Intent i) {
107 | PackageManager pm = ctxt.getPackageManager();
108 | List matches = pm.queryBroadcastReceivers(i, 0);
109 |
110 | for (ResolveInfo resolveInfo : matches) {
111 | Intent explicit = new Intent(i);
112 | ComponentName cn =
113 | new ComponentName(resolveInfo.activityInfo.applicationInfo.packageName,
114 | resolveInfo.activityInfo.name);
115 | explicit.setPackage(resolveInfo.activityInfo.applicationInfo.packageName);
116 | explicit.setComponent(cn);
117 | ctxt.sendBroadcast(explicit, ctxt.getPackageName() + PushTargetManager.PERMISSION);
118 | }
119 | }
120 |
121 | /***
122 | * 用户注册sdk之后的通知
123 | * 注册成功之后设置别名
124 | * @param context
125 | */
126 | public void onRegistration(Context context, ReceiverInfo info) {
127 | for (Map.Entry item : mReceiverMap.entrySet()) {
128 | PushTargetManager.OnPushReceiverListener listener = item.getValue();
129 | if (listener != null) {
130 | listener.onRegister(info);
131 | }
132 | }
133 |
134 | //执行设置别名操作
135 | doSetAlias(context, info);
136 |
137 | //发送广播
138 | sendBroadcast(context, TYPE_REGISTRATION, info);
139 | }
140 |
141 | /**
142 | * 执行别名设置
143 | */
144 | private void doSetAlias(Context context, ReceiverInfo registerInfo) {
145 | if (TextUtils.isEmpty(mAlias) || mPushTargetInit == null) {
146 | return;
147 | }
148 | mPushTargetInit.setAlias(context, mAlias, registerInfo);
149 | }
150 |
151 | /**
152 | * 设置了别名之后
153 | *
154 | * @param context
155 | * @param info
156 | */
157 | public void onAliasSet(Context context, ReceiverInfo info) {
158 | for (Map.Entry item : mReceiverMap.entrySet()) {
159 | PushTargetManager.OnPushReceiverListener listener = item.getValue();
160 | if (listener != null) {
161 | listener.onAlias(info);
162 | }
163 | }
164 |
165 | //发送广播
166 | sendBroadcast(context, TYPE_ALIAS, info);
167 | }
168 |
169 | /**
170 | * 接收到消息推送,不会主动显示在通知栏
171 | *
172 | * @param context
173 | * @param info
174 | */
175 | public void onMessageReceived(Context context, ReceiverInfo info) {
176 | for (Map.Entry item : mReceiverMap.entrySet()) {
177 | PushTargetManager.OnPushReceiverListener listener = item.getValue();
178 | if (listener != null) {
179 | listener.onMessage(info);
180 | }
181 | }
182 |
183 | //发送广播
184 | sendBroadcast(context, TYPE_MESSAGE, info);
185 | }
186 |
187 | /**
188 | * 接收到通知,会主动显示在通知栏的
189 | *
190 | * @param context
191 | * @param info
192 | */
193 | public void onNotificationReceived(Context context, ReceiverInfo info) {
194 | for (Map.Entry item : mReceiverMap.entrySet()) {
195 | PushTargetManager.OnPushReceiverListener listener = item.getValue();
196 | if (listener != null) {
197 | listener.onNotification(info);
198 | }
199 | }
200 |
201 | //发送广播
202 | sendBroadcast(context, TYPE_NOTIFICATION, info);
203 | }
204 |
205 | /**
206 | * 用户点击了通知
207 | *
208 | * @param context
209 | * @param info
210 | */
211 | public void onNotificationOpened(Context context, ReceiverInfo info) {
212 | for (Map.Entry item : mReceiverMap.entrySet()) {
213 | PushTargetManager.OnPushReceiverListener listener = item.getValue();
214 | if (listener != null) {
215 | listener.onOpened(info);
216 | }
217 | }
218 |
219 | //发送广播
220 | sendBroadcast(context, TYPE_OPEN, info);
221 | }
222 |
223 | /**
224 | * 添加推送监听
225 | *
226 | * @param key
227 | * @param listener
228 | */
229 | public void addPushReceiverListener(String key, PushTargetManager.OnPushReceiverListener listener) {
230 | mReceiverMap.put(key, listener);
231 | }
232 |
233 | /**
234 | * 移除一个推送监听
235 | *
236 | * @param key
237 | */
238 | public void removePushReceiverListener(String key) {
239 | if (mReceiverMap.containsKey(key)) {
240 | mReceiverMap.remove(key);
241 | }
242 | }
243 |
244 | /**
245 | * 清空推送监听
246 | */
247 | public void clearPushReceiverListener() {
248 | mReceiverMap.clear();
249 | }
250 |
251 | public String getAlias() {
252 | return mAlias;
253 | }
254 |
255 | /**
256 | * 设置别名
257 | * 对于华为手机无效,华为手机只能通过返回的token识别用户
258 | *
259 | * @param mAlias
260 | */
261 | public void setAlias(String mAlias) {
262 | this.mAlias = mAlias;
263 | }
264 |
265 | }
266 |
--------------------------------------------------------------------------------
/push/src/main/java/com/bearever/push/target/BasePushTargetInit.java:
--------------------------------------------------------------------------------
1 | package com.bearever.push.target;
2 |
3 | import android.app.Application;
4 | import android.content.Context;
5 |
6 | import com.bearever.push.model.ReceiverInfo;
7 |
8 | /**
9 | * 初始化推送平台的基类
10 | * Created by luoming on 2018/5/28.
11 | */
12 |
13 | public abstract class BasePushTargetInit {
14 | protected static int MAX_RETRY_COUNT = 3;
15 | protected Application mApplication;
16 | protected String mAlias;
17 |
18 | /**
19 | * 推送初始化
20 | *
21 | * @param application
22 | */
23 | public BasePushTargetInit(Application application) {
24 | this.mApplication = application;
25 | }
26 |
27 | /**
28 | * 设置别名
29 | *
30 | * @param context
31 | * @param alias
32 | */
33 | public void setAlias(Context context, String alias, ReceiverInfo registerInfo) {
34 | this.mAlias = alias;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/push/src/main/java/com/bearever/push/target/huawei/HuaweiInit.java:
--------------------------------------------------------------------------------
1 | package com.bearever.push.target.huawei;
2 |
3 | import android.app.Application;
4 | import android.content.Context;
5 | import android.os.Handler;
6 | import android.util.Log;
7 |
8 | import com.bearever.push.model.ReceiverInfo;
9 | import com.bearever.push.target.BasePushTargetInit;
10 | import com.huawei.android.hms.agent.HMSAgent;
11 |
12 | /**
13 | * 华为推送初始化
14 | * Created by luoming on 2018/5/28.
15 | */
16 |
17 | public class HuaweiInit extends BasePushTargetInit {
18 | private static final String TAG = "HuaweiInit";
19 | private int mCount = 0;
20 | private Runnable mRunnable = new Runnable() {
21 | @Override
22 | public void run() {
23 | if (mCount < MAX_RETRY_COUNT) {
24 | init();
25 | }
26 | mCount++;
27 | }
28 | };
29 |
30 | private Handler mHandler;
31 |
32 | public HuaweiInit(Application application) {
33 | super(application);
34 | init();
35 | Log.d(TAG, "初始化华为推送");
36 |
37 | }
38 |
39 | private void init() {
40 | if (!HMSAgent.init(mApplication)) {
41 | if (mHandler == null) {
42 | mHandler = new Handler();
43 | }
44 | mHandler.postDelayed(mRunnable, 1000);
45 | }
46 | }
47 |
48 | @Override
49 | public void setAlias(Context context, String alias, ReceiverInfo registerInfo) {
50 | //华为没有设置alias的功能
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/push/src/main/java/com/bearever/push/target/huawei/HuaweiLoadActivity.java:
--------------------------------------------------------------------------------
1 | package com.bearever.push.target.huawei;
2 |
3 | import android.net.Uri;
4 | import android.os.Bundle;
5 | import android.support.annotation.Nullable;
6 | import android.support.v7.app.AppCompatActivity;
7 |
8 | import com.bearever.push.receiver.PushReceiverHandleManager;
9 | import com.bearever.push.model.PushTargetEnum;
10 | import com.bearever.push.model.ReceiverInfo;
11 |
12 | /**
13 | * 处理华为推送点击事件
14 | * 需要与后端协商好数据结构
15 | * scheme :ipush://router/huawei
16 | * 作者:luoming on 2018/10/13.
17 | * 邮箱:luomingbear@163.com
18 | * 版本:v1.0
19 | */
20 | public class HuaweiLoadActivity extends AppCompatActivity {
21 | private static final String TAG = "HuaweiLoadActivity";
22 |
23 | @Override
24 | protected void onCreate(@Nullable Bundle savedInstanceState) {
25 | super.onCreate(savedInstanceState);
26 | Uri uri = getIntent().getData();
27 | String data = "";
28 | // TODO: 2018/10/15 与后端协商好数据结构,这里的“data”是与后端协商的key
29 | if (uri != null) {
30 | data = uri.getQueryParameter("data");
31 | }
32 | ReceiverInfo openInfo = new ReceiverInfo();
33 | openInfo.setPushTarget(PushTargetEnum.HUAWEI);
34 | openInfo.setExtra(data);
35 | PushReceiverHandleManager.getInstance().onNotificationOpened(this, openInfo);
36 | finish();
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/push/src/main/java/com/bearever/push/target/huawei/HuaweiPushBroadcastReceiver.java:
--------------------------------------------------------------------------------
1 | package com.bearever.push.target.huawei;
2 |
3 | import android.content.Context;
4 | import android.os.Bundle;
5 | import android.util.Log;
6 |
7 | import com.bearever.push.PushTargetManager;
8 | import com.bearever.push.receiver.PushReceiverHandleManager;
9 | import com.bearever.push.model.PushTargetEnum;
10 | import com.bearever.push.model.ReceiverInfo;
11 | import com.huawei.hms.support.api.push.PushReceiver;
12 |
13 | /**
14 | * 自定义的华为推送服务的接收器
15 | * Created by luoming on 2018/5/29.
16 | */
17 |
18 | public class HuaweiPushBroadcastReceiver extends PushReceiver {
19 |
20 | /**
21 | * token获取完成;token用于标识设备
22 | *
23 | * @param context
24 | * @param token
25 | * @param extras
26 | */
27 | @Override
28 | public void onToken(Context context, String token, Bundle extras) {
29 | //获取token成功,token用于标识设备的唯一性
30 | ReceiverInfo alias = createReceiverInfo();
31 | alias.setContent(token);
32 | alias.setRawData(extras);
33 | PushReceiverHandleManager.getInstance().onRegistration(context, alias);
34 | PushReceiverHandleManager.getInstance().onAliasSet(context, alias);
35 | Log.e("华为token", token + " -----------------------");
36 | }
37 |
38 | /**
39 | * 接收到了穿透消息
40 | *
41 | * @param context
42 | * @param msg
43 | * @param bundle
44 | * @return
45 | */
46 | @Override
47 | public boolean onPushMsg(Context context, byte[] msg, Bundle bundle) {
48 | try {
49 | //CP可以自己解析消息内容,然后做相应的处理
50 | String content = new String(msg, "UTF-8");
51 | ReceiverInfo info = createReceiverInfo();
52 | info.setContent(content);
53 | info.setRawData(bundle);
54 | PushReceiverHandleManager.getInstance().onMessageReceived(context, info);
55 | } catch (Exception e) {
56 | e.printStackTrace();
57 | }
58 | return false;
59 | }
60 |
61 | /**
62 | * 点击通知栏事件处理
63 | *
64 | * @param context
65 | * @param event
66 | * @param extras
67 | */
68 | @Override
69 | public void onEvent(Context context, Event event, Bundle extras) {
70 | //点击通知事件
71 | if (Event.NOTIFICATION_OPENED.equals(event)) {
72 | ReceiverInfo info = createReceiverInfo();
73 | String message = extras.getString(BOUND_KEY.pushMsgKey);
74 | info.setContent(message);
75 | info.setRawData(extras);
76 | PushReceiverHandleManager.getInstance().onNotificationOpened(context, info);
77 | }
78 | }
79 |
80 | /**
81 | * SDK状态
82 | *
83 | * @param context
84 | * @param pushState
85 | */
86 | @Override
87 | public void onPushState(Context context, boolean pushState) {
88 | // if (pushState) {
89 | // ReceiverInfo info = createReceiverInfo();
90 | // info.setTitle("华为推送注册成功");
91 | // PushReceiverHandleManager.getInstance().onRegistration(context, info);
92 | // }
93 | }
94 |
95 | private ReceiverInfo createReceiverInfo() {
96 | ReceiverInfo info = new ReceiverInfo();
97 | info.setPushTarget(PushTargetEnum.HUAWEI);
98 | return info;
99 | }
100 |
101 | }
102 |
--------------------------------------------------------------------------------
/push/src/main/java/com/bearever/push/target/jiguang/IJPushEventReceiver.java:
--------------------------------------------------------------------------------
1 | package com.bearever.push.target.jiguang;
2 |
3 | import android.content.Context;
4 |
5 | import com.bearever.push.model.PushTargetEnum;
6 | import com.bearever.push.model.ReceiverInfo;
7 | import com.bearever.push.receiver.PushReceiverHandleManager;
8 |
9 | import cn.jpush.android.api.JPushMessage;
10 | import cn.jpush.android.service.JPushMessageReceiver;
11 |
12 | /**
13 | * 自定义的alin/tag设置接口回调
14 | * Created by luoming on 2018/5/28.
15 | */
16 |
17 | public class IJPushEventReceiver extends JPushMessageReceiver {
18 | private static final String TAG = "IJPushEventReceiver";
19 |
20 | @Override
21 | public void onTagOperatorResult(Context var1, JPushMessage var2) {
22 | }
23 |
24 | @Override
25 | public void onCheckTagOperatorResult(Context var1, JPushMessage var2) {
26 |
27 | }
28 |
29 | @Override
30 | public void onAliasOperatorResult(Context var1, JPushMessage var2) {
31 | ReceiverInfo aliasInfo = new ReceiverInfo();
32 | aliasInfo.setContent(var2.getAlias());
33 | aliasInfo.setPushTarget(PushTargetEnum.JPUSH);
34 | aliasInfo.setRawData(var2);
35 | PushReceiverHandleManager.getInstance().onAliasSet(var1, aliasInfo);
36 | }
37 |
38 | @Override
39 | public void onMobileNumberOperatorResult(Context var1, JPushMessage var2) {
40 |
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/push/src/main/java/com/bearever/push/target/jiguang/JPushBroadcastReceiver.java:
--------------------------------------------------------------------------------
1 | package com.bearever.push.target.jiguang;
2 |
3 | import android.content.BroadcastReceiver;
4 | import android.content.Context;
5 | import android.content.Intent;
6 | import android.os.Bundle;
7 | import android.text.TextUtils;
8 |
9 | import com.bearever.push.receiver.PushReceiverHandleManager;
10 | import com.bearever.push.model.PushTargetEnum;
11 | import com.bearever.push.model.ReceiverInfo;
12 |
13 | import cn.jpush.android.api.JPushInterface;
14 |
15 | /**
16 | * 自定义的极光推送接收
17 | * Created by luoming on 2018/5/28.
18 | */
19 |
20 | public class JPushBroadcastReceiver extends BroadcastReceiver {
21 |
22 | @Override
23 | public void onReceive(Context context, Intent intent) {
24 | if (intent == null) {
25 | return;
26 | }
27 |
28 | String action = intent.getAction();
29 | if (TextUtils.isEmpty(action)) {
30 | return;
31 | }
32 |
33 | if (JPushInterface.ACTION_REGISTRATION_ID.equals(action)) {
34 | //用户注册SDK的intent
35 | ReceiverInfo info = new ReceiverInfo();
36 | info.setPushTarget(PushTargetEnum.JPUSH);
37 | info.setRawData(intent);
38 | Bundle bundle = intent.getExtras();
39 | if (bundle != null) {
40 | String code = bundle.getString(JPushInterface.EXTRA_REGISTRATION_ID, "");
41 | info.setContent(code);
42 | }
43 | info.setTitle("极光推送注册成功");
44 | PushReceiverHandleManager.getInstance().onRegistration(context, info);
45 | } else if (JPushInterface.ACTION_MESSAGE_RECEIVED.equals(action)) {
46 | //用户接收SDK消息的intent
47 | PushReceiverHandleManager.getInstance().onMessageReceived(context, convert2MessageReceiverInfo(intent));
48 | } else if (JPushInterface.ACTION_NOTIFICATION_RECEIVED.equals(action)) {
49 | //用户接收SDK通知栏信息的intent
50 | PushReceiverHandleManager.getInstance().onNotificationReceived(context, convert2NotificationReceiverInfo(intent));
51 | } else if (JPushInterface.ACTION_NOTIFICATION_OPENED.equals(action)) {
52 | //用户打开自定义通知栏的intent
53 | PushReceiverHandleManager.getInstance().onNotificationOpened(context, convert2NotificationReceiverInfo(intent));
54 | }
55 | }
56 |
57 | /**
58 | * 将intent的数据转化为ReceiverInfo用于处理
59 | *
60 | * @param intent
61 | * @return
62 | */
63 | private ReceiverInfo convert2NotificationReceiverInfo(Intent intent) {
64 | ReceiverInfo info = new ReceiverInfo();
65 | Bundle bundle = intent.getExtras();
66 | String title = bundle.getString(JPushInterface.EXTRA_NOTIFICATION_TITLE);
67 | String message = bundle.getString(JPushInterface.EXTRA_ALERT);
68 | String extras = bundle.getString(JPushInterface.EXTRA_EXTRA);
69 |
70 | info.setTitle(title);
71 | info.setContent(message);
72 | info.setExtra(extras);
73 | info.setPushTarget(PushTargetEnum.JPUSH);
74 | info.setRawData(intent);
75 | return info;
76 | }
77 |
78 | /**
79 | * 将intent的数据转化为ReceiverInfo用于处理
80 | *
81 | * @param intent
82 | * @return
83 | */
84 | private ReceiverInfo convert2MessageReceiverInfo(Intent intent) {
85 | ReceiverInfo info = new ReceiverInfo();
86 | Bundle bundle = intent.getExtras();
87 | String title = bundle.getString(JPushInterface.EXTRA_TITLE);
88 | String message = bundle.getString(JPushInterface.EXTRA_MESSAGE);
89 | String extras = bundle.getString(JPushInterface.EXTRA_EXTRA);
90 |
91 | info.setTitle(title);
92 | info.setContent(message);
93 | info.setExtra(extras);
94 | info.setPushTarget(PushTargetEnum.JPUSH);
95 | info.setRawData(intent);
96 | return info;
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/push/src/main/java/com/bearever/push/target/jiguang/JPushInit.java:
--------------------------------------------------------------------------------
1 | package com.bearever.push.target.jiguang;
2 |
3 | import android.app.Application;
4 | import android.content.Context;
5 | import android.util.Log;
6 |
7 | import com.bearever.push.model.ReceiverInfo;
8 | import com.bearever.push.target.BasePushTargetInit;
9 |
10 | import cn.jpush.android.api.JPushInterface;
11 |
12 | /**
13 | * 极光推送的初始化服务
14 | * Created by luoming on 2018/5/28.
15 | */
16 |
17 | public class JPushInit extends BasePushTargetInit {
18 | private static final String TAG = "JPushInit";
19 |
20 | public JPushInit(Application application) {
21 | super(application);
22 | JPushInterface.init(application);
23 | Log.d(TAG, "初始化极光推送");
24 | }
25 |
26 | @Override
27 | public void setAlias(Context context, String alias, ReceiverInfo registerInfo) {
28 | JPushInterface.setAlias(context, 0, alias);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/push/src/main/java/com/bearever/push/target/meizu/MeizuInit.java:
--------------------------------------------------------------------------------
1 | package com.bearever.push.target.meizu;
2 |
3 | import android.app.Application;
4 | import android.content.Context;
5 | import android.text.TextUtils;
6 | import android.util.Log;
7 |
8 | import com.bearever.push.model.ReceiverInfo;
9 | import com.bearever.push.target.BasePushTargetInit;
10 | import com.bearever.push.util.ApplicationUtil;
11 | import com.meizu.cloud.pushsdk.PushManager;
12 |
13 | /**
14 | * 魅族推送的初始化
15 | * 作者:luoming on 2018/9/30.
16 | * 邮箱:luomingbear@163.com
17 | * 版本:v1.0
18 | */
19 | public class MeizuInit extends BasePushTargetInit {
20 | private static final String TAG = "MeizuInit";
21 |
22 | public MeizuInit(Application application) {
23 | super(application);
24 |
25 | String appid = ApplicationUtil.getMetaData(application, "MEIZU_APP_ID");
26 | appid = appid.replace(" ", "");
27 | String appkey = ApplicationUtil.getMetaData(application, "MEIZU_APP_KEY");
28 | if (TextUtils.isEmpty(appid) || TextUtils.isEmpty(appkey)) {
29 | return;
30 | }
31 |
32 | PushManager.register(application, appid, appkey);
33 | Log.d(TAG, "初始化魅族推送");
34 | }
35 |
36 | /**
37 | * 魅族设置别名需要pushId,所以不能直接设置,需要在注册成功之后执行设置别名
38 | * 这里的设置功能不可用
39 | *
40 | * @param context
41 | * @param alias
42 | */
43 | @Override
44 | public void setAlias(Context context, String alias, ReceiverInfo registerInfo) {
45 | super.setAlias(context, alias, registerInfo);
46 | String appid = ApplicationUtil.getMetaData(context, "MEIZU_APP_ID");
47 | appid = appid.replace(" ", "");
48 | String appkey = ApplicationUtil.getMetaData(context, "MEIZU_APP_KEY");
49 | PushManager.subScribeAlias(context, appid, appkey, registerInfo.getContent(), alias);
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/push/src/main/java/com/bearever/push/target/meizu/MeizuMessageReceiver.java:
--------------------------------------------------------------------------------
1 | package com.bearever.push.target.meizu;
2 |
3 | import android.content.Context;
4 |
5 | import com.bearever.push.receiver.PushReceiverHandleManager;
6 | import com.bearever.push.model.PushTargetEnum;
7 | import com.bearever.push.model.ReceiverInfo;
8 | import com.meizu.cloud.pushsdk.MzPushMessageReceiver;
9 | import com.meizu.cloud.pushsdk.handler.MzPushMessage;
10 | import com.meizu.cloud.pushsdk.platform.message.PushSwitchStatus;
11 | import com.meizu.cloud.pushsdk.platform.message.RegisterStatus;
12 | import com.meizu.cloud.pushsdk.platform.message.SubAliasStatus;
13 | import com.meizu.cloud.pushsdk.platform.message.SubTagsStatus;
14 | import com.meizu.cloud.pushsdk.platform.message.UnRegisterStatus;
15 |
16 | /**
17 | * 魅族消息的接收
18 | * 作者:luoming on 2018/10/8.
19 | * 邮箱:luomingbear@163.com
20 | * 版本:v1.0
21 | */
22 | public class MeizuMessageReceiver extends MzPushMessageReceiver {
23 | @Override
24 | @Deprecated
25 | public void onRegister(Context context, String pushid) {
26 | //调用 PushManager.register(context)方法后,会在此回调注册状态
27 | //应用在接受返回的 pushid
28 | }
29 |
30 | @Override
31 | public void onMessage(Context context, String s) {
32 | //接收服务器推送的透传消息
33 | ReceiverInfo info = new ReceiverInfo();
34 | info.setPushTarget(PushTargetEnum.MEIZU);
35 | info.setContent(s);
36 | PushReceiverHandleManager.getInstance().onMessageReceived(context, info);
37 | }
38 |
39 | @Override
40 | @Deprecated
41 | public void onUnRegister(Context context, boolean b) {
42 | //调用 PushManager.unRegister(context)方法后,会在此回调反注册状态
43 | }
44 |
45 | @Override
46 | public void onPushStatus(Context context, PushSwitchStatus
47 | pushSwitchStatus) {
48 | //检查通知栏和透传消息开关状态回调
49 | }
50 |
51 | @Override
52 | public void onRegisterStatus(Context context, RegisterStatus registerStatus) {
53 | //调用新版订阅 PushManager.register(context,appId,appKey)回调
54 | if (registerStatus.code.equals(RegisterStatus.SUCCESS_CODE)) {
55 | ReceiverInfo info = new ReceiverInfo();
56 | info.setPushTarget(PushTargetEnum.MEIZU);
57 | info.setTitle("魅族推送注册成功");
58 | info.setContent(registerStatus.getPushId());
59 | info.setRawData(registerStatus);
60 | PushReceiverHandleManager.getInstance().onRegistration(context, info);
61 | }
62 | }
63 |
64 | @Override
65 | public void onUnRegisterStatus(Context context, UnRegisterStatus unRegisterStatus) {
66 | //新版反订阅回调
67 | }
68 |
69 | @Override
70 | public void onSubTagsStatus(Context context, SubTagsStatus subTagsStatus) {
71 | //标签回调
72 | }
73 |
74 | @Override
75 | public void onSubAliasStatus(Context context, SubAliasStatus subAliasStatus) {
76 | //别名回调
77 | ReceiverInfo info = new ReceiverInfo();
78 | info.setPushTarget(PushTargetEnum.MEIZU);
79 | info.setContent(subAliasStatus.getAlias());
80 | info.setRawData(subAliasStatus);
81 | PushReceiverHandleManager.getInstance().onAliasSet(context, info);
82 | }
83 |
84 | @Override
85 | public void onNotificationArrived(Context context, MzPushMessage mzPushMessage) {
86 | //通知栏消息到达回调,flyme6 基于 android6.0 以上不再回调
87 | PushReceiverHandleManager.getInstance().onNotificationReceived(context, createReceiverInfo(mzPushMessage));
88 | }
89 |
90 | @Override
91 | public void onNotificationClicked(Context context, MzPushMessage mzPushMessage) {
92 | //通知栏消息点击回调
93 | PushReceiverHandleManager.getInstance().onNotificationOpened(context, createReceiverInfo(mzPushMessage));
94 | }
95 |
96 | @Override
97 | public void onNotificationDeleted(Context context, MzPushMessage mzPushMessage) {
98 | //通知栏消息删除回调;flyme6 基于 android6.0 以上不再回调
99 | }
100 |
101 | private ReceiverInfo createReceiverInfo(MzPushMessage mzPushMessage) {
102 | ReceiverInfo info = new ReceiverInfo();
103 | info.setPushTarget(PushTargetEnum.MEIZU);
104 | info.setContent(mzPushMessage.getContent());
105 | info.setTitle(mzPushMessage.getTitle());
106 | info.setExtra(mzPushMessage.getSelfDefineContentString());
107 | info.setRawData(mzPushMessage);
108 | return info;
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/push/src/main/java/com/bearever/push/target/oppo/OppoInit.java:
--------------------------------------------------------------------------------
1 | package com.bearever.push.target.oppo;
2 |
3 | import android.app.Application;
4 | import android.content.Context;
5 | import android.os.Handler;
6 | import android.util.Log;
7 |
8 | import com.bearever.push.model.PushTargetEnum;
9 | import com.bearever.push.model.ReceiverInfo;
10 | import com.bearever.push.receiver.PushReceiverHandleManager;
11 | import com.bearever.push.target.BasePushTargetInit;
12 | import com.bearever.push.util.ApplicationUtil;
13 | import com.coloros.mcssdk.PushManager;
14 | import com.coloros.mcssdk.callback.PushCallback;
15 | import com.coloros.mcssdk.mode.ErrorCode;
16 | import com.coloros.mcssdk.mode.SubscribeResult;
17 |
18 | import java.util.List;
19 |
20 | /**
21 | * oppo的推送服务初始化
22 | * 作者:luoming on 2018/9/30.
23 | * 邮箱:luomingbear@163.com
24 | * 版本:v1.0
25 | */
26 | public class OppoInit extends BasePushTargetInit {
27 | private static final String TAG = "OppoInit";
28 | private int mInitCount = 0;
29 | private int mAliasCount = 0;
30 | private Handler mHandler;
31 |
32 | private Runnable mInitRunnable = new Runnable() {
33 | @Override
34 | public void run() {
35 | if (mInitCount < MAX_RETRY_COUNT) {
36 | init();
37 | mInitCount++;
38 | }
39 | }
40 | };
41 |
42 | private Runnable mAliasRunnable = new Runnable() {
43 | @Override
44 | public void run() {
45 | if (mAliasCount < MAX_RETRY_COUNT) {
46 | setAlias(mApplication, mAlias, null);
47 | mAliasCount++;
48 | }
49 | }
50 | };
51 |
52 | public OppoInit(Application application) {
53 | super(application);
54 | if (!PushManager.isSupportPush(application)) {
55 | return;
56 | }
57 | init();
58 | Log.d(TAG, "初始化OPPO推送");
59 | }
60 |
61 | private void init() {
62 | String appKey = ApplicationUtil.getMetaData(mApplication, "OPPO_APP_KEY");
63 | String appSecret = ApplicationUtil.getMetaData(mApplication, "OPPO_APP_SECRET");
64 | PushManager.getInstance().register(mApplication, appKey, appSecret, pushCallback);
65 | }
66 |
67 | private PushCallback pushCallback = new PushCallback() {
68 | @Override
69 | public void onRegister(int i, String s) {
70 | //s 注册id,用来唯一标识设备的
71 | if (i == ErrorCode.SUCCESS) {
72 | //注册成功
73 | ReceiverInfo info = new ReceiverInfo();
74 | info.setContent(s);
75 | info.setTitle("OPPO注册成功");
76 | info.setRawData(s);
77 | info.setPushTarget(PushTargetEnum.OPPO);
78 | PushReceiverHandleManager.getInstance().onRegistration(mApplication, info);
79 | } else {
80 | if (mHandler == null) {
81 | mHandler = new Handler();
82 | }
83 | mHandler.postDelayed(mInitRunnable, 1000);
84 | }
85 | }
86 |
87 | @Override
88 | public void onUnRegister(int i) {
89 |
90 | }
91 |
92 | @Override
93 | public void onGetAliases(int i, List list) {
94 |
95 | }
96 |
97 | @Override
98 | public void onSetAliases(int i, List list) {
99 | if (i == ErrorCode.SUCCESS) {
100 | //成功
101 | ReceiverInfo aliasInfo = new ReceiverInfo();
102 | if (list != null && list.size() > 0) {
103 | aliasInfo.setContent(list.get(0).getContent());
104 | }
105 | aliasInfo.setRawData(list);
106 | aliasInfo.setPushTarget(PushTargetEnum.OPPO);
107 | PushReceiverHandleManager.getInstance().onAliasSet(mApplication, aliasInfo);
108 | } else {
109 | if (mHandler == null) {
110 | mHandler = new Handler();
111 | }
112 | mHandler.postDelayed(mAliasRunnable, 1000);
113 | }
114 | }
115 |
116 | @Override
117 | public void onUnsetAliases(int i, List list) {
118 |
119 | }
120 |
121 | @Override
122 | public void onSetUserAccounts(int i, List list) {
123 |
124 | }
125 |
126 | @Override
127 | public void onUnsetUserAccounts(int i, List list) {
128 |
129 | }
130 |
131 | @Override
132 | public void onGetUserAccounts(int i, List list) {
133 |
134 | }
135 |
136 | @Override
137 | public void onSetTags(int i, List list) {
138 |
139 | }
140 |
141 | @Override
142 | public void onUnsetTags(int i, List list) {
143 |
144 | }
145 |
146 | @Override
147 | public void onGetTags(int i, List list) {
148 |
149 | }
150 |
151 | @Override
152 | public void onGetPushStatus(int i, int i1) {
153 |
154 | }
155 |
156 | @Override
157 | public void onSetPushTime(int i, String s) {
158 |
159 | }
160 |
161 | @Override
162 | public void onGetNotificationStatus(int i, int i1) {
163 |
164 | }
165 | };
166 |
167 | @Override
168 | public void setAlias(Context context, String alias, ReceiverInfo registerInfo) {
169 | super.setAlias(context, alias, registerInfo);
170 | // 别名设置总是失败,索性取消,使用注册id识别用户
171 | // List list = new ArrayList<>();
172 | // list.add(alias);
173 | // PushManager.getInstance().setAliases(list);
174 | PushReceiverHandleManager.getInstance().onAliasSet(context, registerInfo);
175 | }
176 | }
177 |
--------------------------------------------------------------------------------
/push/src/main/java/com/bearever/push/target/oppo/OppoLoadActivity.java:
--------------------------------------------------------------------------------
1 | package com.bearever.push.target.oppo;
2 |
3 | import android.os.Bundle;
4 | import android.support.annotation.Nullable;
5 | import android.support.v7.app.AppCompatActivity;
6 |
7 | import com.bearever.push.receiver.PushReceiverHandleManager;
8 | import com.bearever.push.model.PushTargetEnum;
9 | import com.bearever.push.model.ReceiverInfo;
10 |
11 | import java.util.Set;
12 |
13 | /**
14 | * 处理OPPO的通知栏点击事件
15 | * action:ipush.router.oppo
16 | * 作者:luoming on 2018/10/12.
17 | * 邮箱:luomingbear@163.com
18 | * 版本:v1.0
19 | */
20 | public class OppoLoadActivity extends AppCompatActivity {
21 | private static final String TAG = "OppoLoadActivity";
22 |
23 | @Override
24 | protected void onCreate(@Nullable Bundle savedInstanceState) {
25 | super.onCreate(savedInstanceState);
26 | //取出bundle里面的参数数据改为json格式
27 | Bundle bundle = getIntent().getExtras();
28 | Set set = bundle.keySet();
29 | StringBuffer sb = new StringBuffer();
30 | if (set != null) {
31 | sb.append("{");
32 | for (String key : set) {
33 | String vaues = bundle.getString(key);
34 | sb.append("\"");
35 | sb.append(key);
36 | sb.append("\"");
37 | sb.append(":");
38 | sb.append("\"");
39 | sb.append(vaues);
40 | sb.append("\"");
41 | sb.append(",");
42 | }
43 | sb.append("}");
44 | }
45 | //发送到处理中心
46 | ReceiverInfo openInfo = new ReceiverInfo();
47 | openInfo.setPushTarget(PushTargetEnum.OPPO);
48 | openInfo.setExtra(sb.replace(sb.length() - 2, sb.length(), "}").toString());
49 | PushReceiverHandleManager.getInstance().onNotificationOpened(this, openInfo);
50 | finish();
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/push/src/main/java/com/bearever/push/target/oppo/OppoMessageService.java:
--------------------------------------------------------------------------------
1 | package com.bearever.push.target.oppo;
2 |
3 | import android.content.Context;
4 | import android.util.Log;
5 |
6 | import com.bearever.push.receiver.PushReceiverHandleManager;
7 | import com.bearever.push.model.PushTargetEnum;
8 | import com.bearever.push.model.ReceiverInfo;
9 | import com.coloros.mcssdk.PushService;
10 | import com.coloros.mcssdk.mode.AppMessage;
11 | import com.coloros.mcssdk.mode.CommandMessage;
12 | import com.coloros.mcssdk.mode.SptDataMessage;
13 |
14 | /**
15 | * OPPO消息接收处理器
16 | * 作者:luoming on 2018/9/30.
17 | * 邮箱:luomingbear@163.com
18 | * 版本:v1.0
19 | */
20 | public class OppoMessageService extends PushService {
21 | private static final String TAG = "OppoMessageService";
22 |
23 | /**
24 | * 普通应用消息
25 | *
26 | * @param context
27 | * @param appMessage
28 | */
29 | @Override
30 | public void processMessage(Context context, AppMessage appMessage) {
31 | super.processMessage(context, appMessage);
32 | Log.d(TAG, "app processMessage: handle:" + appMessage);
33 | ReceiverInfo info = new ReceiverInfo();
34 | info.setTitle(appMessage.getTitle());
35 | info.setContent(appMessage.getContent());
36 | info.setPushTarget(PushTargetEnum.OPPO);
37 | info.setRawData(appMessage);
38 | PushReceiverHandleManager.getInstance().onNotificationReceived(context, info);
39 | }
40 |
41 | /**
42 | * 透传消息处理,应用可以打开页面或者执行命令,如果应用不需要处理透传消息,则不需要重写此方法
43 | *
44 | * @param context
45 | * @param sptDataMessage
46 | */
47 | @Override
48 | public void processMessage(Context context, SptDataMessage sptDataMessage) {
49 | super.processMessage(context, sptDataMessage);
50 | Log.d(TAG, "spt processMessage: handle:" + sptDataMessage);
51 | ReceiverInfo info = new ReceiverInfo();
52 | info.setContent(sptDataMessage.getContent());
53 | info.setExtra(sptDataMessage.getDescription());
54 | info.setPushTarget(PushTargetEnum.OPPO);
55 | info.setRawData(sptDataMessage);
56 | PushReceiverHandleManager.getInstance().onMessageReceived(context, info);
57 | }
58 |
59 | /**
60 | * 命令消息,主要是服务端对客户端调用的反馈,一般应用不需要重写此方法
61 | *
62 | * @param context
63 | * @param commandMessage
64 | */
65 | @Override
66 | public void processMessage(Context context, CommandMessage commandMessage) {
67 | super.processMessage(context, commandMessage);
68 | Log.d(TAG, "command processMessage: " + commandMessage);
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/push/src/main/java/com/bearever/push/target/vivo/VivoBroadcastReceiver.java:
--------------------------------------------------------------------------------
1 | package com.bearever.push.target.vivo;
2 |
3 | import android.content.Context;
4 |
5 | import com.bearever.push.receiver.PushReceiverHandleManager;
6 | import com.bearever.push.model.PushTargetEnum;
7 | import com.bearever.push.model.ReceiverInfo;
8 | import com.vivo.push.model.UPSNotificationMessage;
9 | import com.vivo.push.sdk.OpenClientPushMessageReceiver;
10 |
11 | /**
12 | * desc: vivo的消息接收
13 | * auth: malong
14 | * email: luomingbear@163.com
15 | * time: 2019/4/18
16 | **/
17 | public class VivoBroadcastReceiver extends OpenClientPushMessageReceiver {
18 | @Override
19 | public void onNotificationMessageClicked(Context context, UPSNotificationMessage upsNotificationMessage) {
20 | /**
21 | * UPSNotificationMessage 数据结构
22 | * msgid:通知 id
23 | * title:通知标题
24 | * content:通知内容
25 | * skipContent:通知自定义内容
26 | * params:自定义键值对
27 | */
28 |
29 | ReceiverInfo info = new ReceiverInfo();
30 | info.setTitle(upsNotificationMessage.getTitle());
31 | info.setContent(upsNotificationMessage.getContent());
32 | info.setPushTarget(PushTargetEnum.VIVO);
33 | info.setRawData(upsNotificationMessage);
34 | PushReceiverHandleManager.getInstance().onNotificationOpened(context, info);
35 | }
36 |
37 | @Override
38 | public void onReceiveRegId(Context context, String s) {
39 | ReceiverInfo info = new ReceiverInfo();
40 | info.setTitle("VIVO推送初始化成功");
41 | info.setContent(s);
42 | info.setPushTarget(PushTargetEnum.VIVO);
43 | info.setRawData(s);
44 | PushReceiverHandleManager.getInstance().onRegistration(context, info);
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/push/src/main/java/com/bearever/push/target/vivo/VivoInit.java:
--------------------------------------------------------------------------------
1 | package com.bearever.push.target.vivo;
2 |
3 | import android.app.Application;
4 | import android.content.Context;
5 | import android.os.Handler;
6 | import android.util.Log;
7 |
8 | import com.bearever.push.model.PushTargetEnum;
9 | import com.bearever.push.model.ReceiverInfo;
10 | import com.bearever.push.receiver.PushReceiverHandleManager;
11 | import com.bearever.push.target.BasePushTargetInit;
12 | import com.vivo.push.IPushActionListener;
13 | import com.vivo.push.PushClient;
14 |
15 | /**
16 | * desc: vivo推送初始化类
17 | * auth: malong
18 | * email: luomingbear@163.com
19 | * time: 2019/4/18
20 | **/
21 | public class VivoInit extends BasePushTargetInit {
22 | private static final String TAG = "VivoInit";
23 | private int mInitCount = 0;
24 | private int mAliasCount = 0;
25 | private Handler mHandler;
26 |
27 | public VivoInit(final Application application) {
28 | super(application);
29 | if (!PushClient.getInstance(application).isSupport()) {
30 | return;
31 | }
32 |
33 | //初始化
34 | PushClient.getInstance(application).initialize();
35 | if (mHandler == null) {
36 | mHandler = new Handler();
37 | }
38 | mHandler.post(initRunnable);
39 | Log.d(TAG, "初始化魅族推送");
40 | }
41 |
42 | private Runnable initRunnable = new Runnable() {
43 | @Override
44 | public void run() {
45 | //打开推送
46 | PushClient.getInstance(mApplication).turnOnPush(new IPushActionListener() {
47 | @Override
48 | public void onStateChanged(int i) {
49 | if (i != 0 && i != 1) {
50 | //失败重试
51 | if (mInitCount < MAX_RETRY_COUNT) {
52 | if (mHandler == null) {
53 | mHandler = new Handler();
54 | }
55 | mHandler.postDelayed(initRunnable, 1000);
56 | mInitCount++;
57 | }
58 | }
59 | }
60 | });
61 | }
62 | };
63 |
64 | @Override
65 | public void setAlias(Context context, String alias, ReceiverInfo registerInfo) {
66 | super.setAlias(context, alias, registerInfo);
67 | if (mHandler == null) {
68 | mHandler = new Handler();
69 | }
70 | mHandler.post(aliasRunnable);
71 | }
72 |
73 | private Runnable aliasRunnable = new Runnable() {
74 | @Override
75 | public void run() {
76 | //设置别名
77 | PushClient.getInstance(mApplication).bindAlias(mAlias, new IPushActionListener() {
78 | @Override
79 | public void onStateChanged(int i) {
80 | if (i != 0 && i != 1) {
81 | //失败重试
82 | if (mAliasCount < MAX_RETRY_COUNT) {
83 | if (mHandler == null) {
84 | mHandler = new Handler();
85 | }
86 | mHandler.postDelayed(aliasRunnable, 1000);
87 | mAliasCount++;
88 | }
89 | } else {
90 | //成功
91 | ReceiverInfo info = new ReceiverInfo();
92 | info.setContent(mAlias);
93 | info.setPushTarget(PushTargetEnum.VIVO);
94 | PushReceiverHandleManager.getInstance().onAliasSet(mApplication, info);
95 | }
96 | }
97 | });
98 | }
99 | };
100 |
101 | }
102 |
--------------------------------------------------------------------------------
/push/src/main/java/com/bearever/push/target/xiaomi/XiaomiBroadcastReceiver.java:
--------------------------------------------------------------------------------
1 | package com.bearever.push.target.xiaomi;
2 |
3 | import android.content.Context;
4 | import android.util.Log;
5 |
6 | import com.bearever.push.model.PushTargetEnum;
7 | import com.bearever.push.model.ReceiverInfo;
8 | import com.bearever.push.receiver.PushReceiverHandleManager;
9 | import com.google.gson.Gson;
10 | import com.xiaomi.mipush.sdk.MiPushClient;
11 | import com.xiaomi.mipush.sdk.MiPushCommandMessage;
12 | import com.xiaomi.mipush.sdk.MiPushMessage;
13 | import com.xiaomi.mipush.sdk.PushMessageReceiver;
14 |
15 | /**
16 | * 自定义的小米推送接收
17 | * Created by luoming on 2018/5/28.
18 | */
19 |
20 | public class XiaomiBroadcastReceiver extends PushMessageReceiver {
21 | @Override
22 | public void onReceivePassThroughMessage(Context var1, MiPushMessage var2) {
23 | PushReceiverHandleManager.getInstance().onMessageReceived(var1, convert2ReceiverInfo(var2));
24 | }
25 |
26 | @Override
27 | public void onNotificationMessageClicked(Context var1, MiPushMessage var2) {
28 | PushReceiverHandleManager.getInstance().onNotificationOpened(var1, convert2ReceiverInfo(var2));
29 | }
30 |
31 | @Override
32 | public void onNotificationMessageArrived(Context var1, MiPushMessage var2) {
33 | Log.e("接收消息成功", "------------------------");
34 | PushReceiverHandleManager.getInstance().onNotificationReceived(var1, convert2ReceiverInfo(var2));
35 | }
36 |
37 | @Override
38 | public void onReceiveRegisterResult(Context var1, MiPushCommandMessage command) {
39 | if (MiPushClient.COMMAND_REGISTER.equals(command.getCommand())) {
40 | ReceiverInfo info = convert2ReceiverInfo(command);
41 | info.setTitle("小米推送注册成功");
42 | //注册id
43 | String id = command.getCommandArguments().get(0);
44 | info.setContent(id);
45 | Log.e("command id", id);
46 | PushReceiverHandleManager.getInstance().onRegistration(var1, info);
47 | }
48 | }
49 |
50 | /**
51 | * 将intent的数据转化为ReceiverInfo用于处理
52 | *
53 | * @param miPushMessage
54 | * @return
55 | */
56 | private ReceiverInfo convert2ReceiverInfo(MiPushMessage miPushMessage) {
57 | ReceiverInfo info = new ReceiverInfo();
58 | info.setContent(miPushMessage.getContent());
59 | info.setPushTarget(PushTargetEnum.XIAOMI);
60 | info.setTitle(miPushMessage.getTitle());
61 | info.setRawData(miPushMessage);
62 | if (miPushMessage.getExtra() != null) {
63 | info.setExtra(new Gson().toJson(miPushMessage.getExtra()));
64 | }
65 | return info;
66 | }
67 |
68 | /**
69 | * 将intent的数据转化为ReceiverInfo用于处理
70 | *
71 | * @param miPushCommandMessage
72 | * @return
73 | */
74 | private ReceiverInfo convert2ReceiverInfo(MiPushCommandMessage miPushCommandMessage) {
75 | ReceiverInfo info = new ReceiverInfo();
76 | info.setContent(miPushCommandMessage.getCommand());
77 | info.setRawData(miPushCommandMessage);
78 | info.setPushTarget(PushTargetEnum.XIAOMI);
79 | return info;
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/push/src/main/java/com/bearever/push/target/xiaomi/XiaomiInit.java:
--------------------------------------------------------------------------------
1 | package com.bearever.push.target.xiaomi;
2 |
3 | import android.app.ActivityManager;
4 | import android.app.Application;
5 | import android.content.Context;
6 | import android.os.Process;
7 | import android.util.Log;
8 |
9 | import com.bearever.push.model.PushTargetEnum;
10 | import com.bearever.push.model.ReceiverInfo;
11 | import com.bearever.push.receiver.PushReceiverHandleManager;
12 | import com.bearever.push.target.BasePushTargetInit;
13 | import com.bearever.push.util.ApplicationUtil;
14 | import com.xiaomi.mipush.sdk.MiPushClient;
15 |
16 | import java.util.List;
17 |
18 | /**
19 | * 小米推送的初始化
20 | * Created by luoming on 2018/5/28.
21 | */
22 |
23 | public class XiaomiInit extends BasePushTargetInit {
24 | private static final String TAG = "XiaomiInit";
25 |
26 | public XiaomiInit(Application context) {
27 | super(context);
28 |
29 | if (shouldInit()) {
30 | //注册SDK
31 | String appId = ApplicationUtil.getMetaData(context, "XMPUSH_APPID");
32 | String appKey = ApplicationUtil.getMetaData(context, "XMPUSH_APPKEY");
33 |
34 | MiPushClient.registerPush(context, appId.replaceAll(" ", ""),
35 | appKey.replaceAll(" ", ""));
36 |
37 | Log.d(TAG, "初始化小米推送");
38 | }
39 | }
40 |
41 | private boolean shouldInit() {
42 | ActivityManager am = (ActivityManager) mApplication.getSystemService(Context.ACTIVITY_SERVICE);
43 | List processInfos = am.getRunningAppProcesses();
44 | String mainProcessName = mApplication.getPackageName();
45 | int myPid = Process.myPid();
46 | for (ActivityManager.RunningAppProcessInfo info : processInfos) {
47 | if (info.pid == myPid && mainProcessName.equals(info.processName)) {
48 | return true;
49 | }
50 | }
51 | return false;
52 | }
53 |
54 | @Override
55 | public void setAlias(Context context, String alias, ReceiverInfo registerInfo) {
56 | MiPushClient.setAlias(context, alias, null);
57 | ReceiverInfo aliasInfo = new ReceiverInfo();
58 | aliasInfo.setContent(alias);
59 | aliasInfo.setPushTarget(PushTargetEnum.XIAOMI);
60 | PushReceiverHandleManager.getInstance().onAliasSet(context, aliasInfo);
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/push/src/main/java/com/bearever/push/util/ApplicationUtil.java:
--------------------------------------------------------------------------------
1 | package com.bearever.push.util;
2 |
3 | import android.content.Context;
4 | import android.content.pm.ApplicationInfo;
5 | import android.content.pm.PackageManager;
6 | import android.os.Build;
7 | import android.os.Bundle;
8 | import android.provider.Settings;
9 |
10 | /**
11 | * 系统工具类
12 | * Created by luoming on 2018/5/28.
13 | */
14 |
15 | public class ApplicationUtil {
16 | /**
17 | * 获取Manifest 里面的meta-data
18 | *
19 | * @param context
20 | * @param key
21 | * @return
22 | */
23 | public static String getMetaData(Context context, String key) {
24 | ApplicationInfo ai = null;
25 | try {
26 | ai = context.getPackageManager().getApplicationInfo(context.getPackageName(),
27 | PackageManager.GET_META_DATA);
28 | } catch (PackageManager.NameNotFoundException e) {
29 | e.printStackTrace();
30 | return "";
31 | }
32 | Bundle bundle = ai.metaData;
33 | String value = bundle.getString(key);
34 | return value;
35 | }
36 |
37 | /**
38 | * 获取设备id
39 | *
40 | * @param context
41 | * @return
42 | */
43 | public static String getDeviceId(Context context) {
44 | String androidID = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
45 | String id = androidID + Build.SERIAL;
46 | return id;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/push/src/main/java/com/huawei/android/hms/agent/HMSAgent.java:
--------------------------------------------------------------------------------
1 | package com.huawei.android.hms.agent;
2 |
3 |
4 | import android.app.Activity;
5 | import android.app.Application;
6 | import android.content.Context;
7 | import android.os.Handler;
8 | import android.os.Looper;
9 | import android.widget.Toast;
10 |
11 | import com.bearever.push.PushTargetManager;
12 | import com.huawei.android.hms.agent.common.ActivityMgr;
13 | import com.huawei.android.hms.agent.common.ApiClientMgr;
14 | import com.huawei.android.hms.agent.common.HMSAgentLog;
15 | import com.huawei.android.hms.agent.common.IClientConnectCallback;
16 | import com.huawei.android.hms.agent.common.INoProguard;
17 | import com.huawei.android.hms.agent.common.handler.ConnectHandler;
18 | import com.huawei.android.hms.agent.push.DeleteTokenApi;
19 | import com.huawei.android.hms.agent.push.EnableReceiveNormalMsgApi;
20 | import com.huawei.android.hms.agent.push.EnableReceiveNotifyMsgApi;
21 | import com.huawei.android.hms.agent.push.GetPushStateApi;
22 | import com.huawei.android.hms.agent.push.GetTokenApi;
23 | import com.huawei.android.hms.agent.push.QueryAgreementApi;
24 | import com.huawei.android.hms.agent.push.handler.DeleteTokenHandler;
25 | import com.huawei.android.hms.agent.push.handler.EnableReceiveNormalMsgHandler;
26 | import com.huawei.android.hms.agent.push.handler.EnableReceiveNotifyMsgHandler;
27 | import com.huawei.android.hms.agent.push.handler.GetPushStateHandler;
28 | import com.huawei.android.hms.agent.push.handler.GetTokenHandler;
29 | import com.huawei.android.hms.agent.push.handler.QueryAgreementHandler;
30 | import com.huawei.hms.api.HuaweiApiAvailability;
31 | import com.huawei.hms.api.HuaweiApiClient;
32 |
33 | /**
34 | * HMSAgent 封装入口类。 提供了HMS SDK 功能的封装,使开发者更聚焦业务的处理。
35 | * HMSAgent encapsulates the entry class. Provides a encapsulation of the HMS SDK functionality that enables developers to focus more on business processing.
36 | */
37 | public final class HMSAgent implements INoProguard {
38 |
39 | /**
40 | * 基础版本 | Base version
41 | */
42 | private static final String VER_020503001 = "020503001";
43 |
44 | /**
45 | * 2.6.0 版本1 | 2.6.0 version 1
46 | * 对外:接口不变 | External: interface unchanged
47 | * 对内:HMSSDK connect 接口增加activity参数 | Internal: HMSSDK connect interface to increase activity parameters
48 | * HMSSDK sign 接口增加activity参数 | HMSSDK sign interface to increase activity parameters
49 | * 自身优化: | Self optimization:
50 | * 1、增加了升级时被其他界面覆盖的处理 | Increased handling of other interface coverage issues when upgrading
51 | * 2、game模块savePlayerInfo接口,去掉activity的判断 | Game Module Saveplayerinfo method to remove activity judgments
52 | * 3、解决错误回调成功,增加重试次数3次 | Resolve error callback succeeded, increase retry count 3 times
53 | * 4、提供了多种HMSAgent初始化方法 | Provides a variety of hmsagent initialization methods
54 | * 5、初始化时增加了版本号校验 | Increased version number checksum during initialization
55 | */
56 | private static final String VER_020600001 = "020600001";
57 |
58 | /**
59 | * 2.6.0.200 | 2.6.0.200
60 | * 自身优化: | Self optimization:
61 | * 1、增加shell脚本用来抽取代码和编译成jar | Add shell script to extract code and compile into jar
62 | * 2、示例中manifest里面升级配置错误修复 | Example manifest upgrade configuration error Repair
63 | * 3、抽取代码中去掉manifest文件,只留纯代码 | Remove manifest files in the extraction code, leaving only pure code
64 | */
65 | private static final String VER_020600200 = "020600200";
66 |
67 | /**
68 | * 2.6.0.302 | 2.6.0.302
69 | * 修改manifest,删除hms版本号配置;增加直接传入请求和私钥的签名方法封装
70 | */
71 | private static final String VER_020600302 = "020600302";
72 |
73 | /**
74 | * 当前版本号 | Current version number
75 | */
76 | public static final String CURVER = VER_020600302;
77 |
78 |
79 |
80 | public static final class AgentResultCode {
81 |
82 | /**
83 | * HMSAgent 成功 | success
84 | */
85 | public static final int HMSAGENT_SUCCESS = 0;
86 |
87 | /**
88 | * HMSAgent 没有初始化 | Hmsagent not initialized
89 | */
90 | public static final int HMSAGENT_NO_INIT = -1000;
91 |
92 | /**
93 | * 请求需要activity,但当前没有可用的activity | Request requires activity, but no active activity is currently available
94 | */
95 | public static final int NO_ACTIVITY_FOR_USE = -1001;
96 |
97 | /**
98 | * 结果为空 | Result is empty
99 | */
100 | public static final int RESULT_IS_NULL = -1002;
101 |
102 | /**
103 | * 状态为空 | Status is empty
104 | */
105 | public static final int STATUS_IS_NULL = -1003;
106 |
107 | /**
108 | * 拉起activity异常,需要检查activity有没有在manifest中配置 | Pull up an activity exception and need to check if the activity is configured in manifest
109 | */
110 | public static final int START_ACTIVITY_ERROR = -1004;
111 |
112 | /**
113 | * onActivityResult 回调结果错误 | Onactivityresult Callback Result Error
114 | */
115 | public static final int ON_ACTIVITY_RESULT_ERROR = -1005;
116 |
117 | /**
118 | * 重复请求 | Duplicate Request
119 | */
120 | public static final int REQUEST_REPEATED = -1006;
121 |
122 | /**
123 | * 连接client 超时 | Connect Client Timeout
124 | */
125 | public static final int APICLIENT_TIMEOUT = -1007;
126 |
127 | /**
128 | * 调用接口异常 | Calling an interface exception
129 | */
130 | public static final int CALL_EXCEPTION = -1008;
131 |
132 | /**
133 | * 接口参数为空 | Interface parameter is empty
134 | */
135 | public static final int EMPTY_PARAM = -1009;
136 | }
137 |
138 | private HMSAgent(){}
139 |
140 | private static boolean checkSDKVersion(Context context){
141 | long sdkMainVerL = HuaweiApiAvailability.HMS_SDK_VERSION_CODE/1000;
142 | long agentMainVerL = Long.parseLong(CURVER)/1000;
143 | if (sdkMainVerL != agentMainVerL) {
144 | String errMsg = "error: HMSAgent major version code ("+agentMainVerL+") does not match HMSSDK major version code ("+sdkMainVerL+")";
145 | HMSAgentLog.e(errMsg);
146 | Toast.makeText(context, errMsg, Toast.LENGTH_LONG).show();
147 | return false;
148 | }
149 | return true;
150 | }
151 |
152 | /**
153 | * 初始化方法,传入第一个界面的activity | Initialization method, passing in the first interface activity
154 | * @param activity 当前界面 | Current interface
155 | * @return true:成功 false:失败 | True: Success false: Failed
156 | */
157 | public static boolean init(Activity activity) {
158 | return init(null, activity);
159 | }
160 |
161 | /**
162 | * 初始化方法,建议在Application onCreate里面调用 | Initialization method, it is recommended to call in creator OnCreate
163 | * @param app 应用程序 | Application
164 | * @return true:成功 false:失败 | True: Success false: Failed
165 | */
166 | public static boolean init(Application app) {
167 | return init(app, null);
168 | }
169 |
170 | /**
171 | * 初始化方法,建议在Application onCreate里面调用 | Initialization method, it is recommended to call in creator OnCreate
172 | * @param app 应用程序 | Application
173 | * @param activity 当前界面 | Current activity
174 | * @return true:成功 false:失败 | True: Success false: Failed
175 | */
176 | public static boolean init(Application app, Activity activity) {
177 |
178 | Application appTmp = app;
179 | Activity activityTmp = activity;
180 |
181 | // 两个参数都为null,直接抛异常 | Two parameters are null, throwing exceptions directly
182 | if (appTmp == null && activityTmp == null) {
183 | HMSAgentLog.e("the param of method HMSAgent.init can not be null !!!");
184 | return false;
185 | }
186 |
187 | // 如果application实例为null,则从activity里面取 | If the creator instance is null, it is taken from the activity
188 | if (appTmp == null) {
189 | appTmp = activityTmp.getApplication();
190 | }
191 |
192 | // 如果application实例仍然为null,抛异常 | Throws an exception if the creator instance is still null
193 | if (appTmp == null) {
194 | HMSAgentLog.e("the param of method HMSAgent.init app can not be null !!!");
195 | return false;
196 | }
197 |
198 | // activity 已经失效,则赋值null | Assignment NULL if activity has been invalidated
199 | if (activityTmp != null && activityTmp.isFinishing()) {
200 | activityTmp = null;
201 | }
202 |
203 | // 检查HMSAgent 和 HMSSDK 版本匹配关系 | Check hmsagent and HMSSDK version matching relationships
204 | if (!checkSDKVersion(appTmp)) {
205 | return false;
206 | }
207 |
208 | HMSAgentLog.i("init HMSAgent " + CURVER + " with hmssdkver " + HuaweiApiAvailability.HMS_SDK_VERSION_CODE);
209 |
210 | // 初始化activity管理类 | Initializing Activity Management Classes
211 | ActivityMgr.INST.init(appTmp, activityTmp);
212 |
213 | // 初始化HuaweiApiClient管理类 | Initialize Huaweiapiclient Management class
214 | ApiClientMgr.INST.init(appTmp);
215 |
216 | HMSAgent.connect(new ConnectHandler() {
217 | @Override
218 | public void onConnect(int rst) {
219 | if (rst == HMSAgent.AgentResultCode.HMSAGENT_SUCCESS) {
220 | //连接成功就获取token和设置打开推送等
221 | HMSAgent.Push.getPushState(null);
222 | HMSAgent.Push.getToken(null);
223 | }
224 | }
225 | });
226 |
227 | return true;
228 | }
229 |
230 | /**
231 | * 释放资源,这里一般不需要调用 | Frees resources, which are generally not required to call
232 | */
233 | public static void destroy() {
234 | HMSAgentLog.i("destroy HMSAgent");
235 | ActivityMgr.INST.release();
236 | ApiClientMgr.INST.release();
237 | }
238 |
239 | /**
240 | * 连接HMS SDK, 可能拉起界面(包括升级引导等),建议在第一个界面进行连接。 | Connecting to the HMS SDK may pull up the activity (including upgrade guard, etc.), and it is recommended that you connect in the first activity.
241 | * 此方法可以重复调用,没必要为了只调用一次做复杂处理 | This method can be called repeatedly, and there is no need to do complex processing for only one call at a time
242 | * 方法为异步调用,调用结果在主线程回调 | Method is called asynchronously, and the result is invoked in the main thread callback
243 | * @param activity 当前界面的activity, 不能传空 | Activity of the current activity, cannot be empty
244 | * @param callback 连接结果回调 | Connection Result Callback
245 | */
246 | public static void connect(final ConnectHandler callback) {
247 | HMSAgentLog.i("start connect");
248 | ApiClientMgr.INST.connect(new IClientConnectCallback() {
249 | @Override
250 | public void onConnect(final int rst, HuaweiApiClient client) {
251 | if (callback != null) {
252 | new Handler(Looper.getMainLooper()).post(new Runnable() {
253 | @Override
254 | public void run() {
255 | callback.onConnect(rst);
256 | }
257 | });
258 | }
259 | }
260 | }, true);
261 | }
262 |
263 | /**
264 | * 检查本应用的升级 | Check for upgrades to this application
265 | * @param activity 上下文 | context
266 | */
267 | public static void checkUpdate (final Activity activity) {
268 | HMSAgentLog.i("start checkUpdate");
269 | ApiClientMgr.INST.connect(new IClientConnectCallback() {
270 | @Override
271 | public void onConnect(int rst, HuaweiApiClient client) {
272 | Activity activityCur = ActivityMgr.INST.getLastActivity();
273 |
274 | if (activityCur != null && client != null) {
275 | client.checkUpdate(activityCur);
276 | } else if (activity != null && client != null){
277 | client.checkUpdate(activity);
278 | } else {
279 | // 跟SE确认:activity 为 null , 不处理 | Activity is null and does not need to be processed
280 | HMSAgentLog.e("no activity to checkUpdate");
281 | }
282 | }
283 | }, true);
284 | }
285 |
286 |
287 |
288 |
289 |
290 | /**
291 | * push接口封装 | Push interface Encapsulation
292 | */
293 | public static final class Push {
294 | /**
295 | * 获取pushtoken接口 | Get Pushtoken method
296 | * pushtoken通过广播下发,要监听的广播,请参见HMS-SDK开发准备中PushReceiver的注册 | Pushtoken Broadcast issued, to listen to the broadcast, see HMS-SDK Development Preparation Pushreceiver Registration
297 | * @param handler pushtoken接口调用回调(结果会在主线程回调) | getToken method Call callback (result will be callback in main thread)
298 | */
299 | public static void getToken(GetTokenHandler handler){
300 | new GetTokenApi().getToken(handler);
301 | }
302 |
303 | /**
304 | * 删除指定的pushtoken | Deletes the specified Pushtoken
305 | * 该接口只在EMUI5.1以及更高版本的华为手机上调用该接口后才不会收到PUSH消息。 | The method will not receive a push message until it is invoked on EMUI5.1 and later Huawei handsets.
306 | * @param token 要删除的token | Token to delete
307 | * @param handler 方法调用结果回调(结果会在主线程回调) | Method call result Callback (result will be callback on main thread)
308 | */
309 | public static void deleteToken(String token, DeleteTokenHandler handler){
310 | new DeleteTokenApi().deleteToken(token, handler);
311 | }
312 |
313 | /**
314 | * 获取push状态,push状态的回调通过广播发送。 | Gets the push state, and the push state callback is sent by broadcast.
315 | * 要监听的广播,请参见HMS-SDK开发准备中PushReceiver的注册 | To listen for broadcasts, see Pushreceiver Registration in HMS-SDK development preparation
316 | * @param handler 方法调用结果回调(结果会在主线程回调) | Method call result Callback (result will be callback on main thread)
317 | */
318 | public static void getPushState(GetPushStateHandler handler){
319 | new GetPushStateApi().getPushState(handler);
320 | }
321 |
322 | /**
323 | * 打开/关闭通知栏消息 | Turn on/off notification bar messages
324 | * @param enable 打开/关闭 | Turn ON/off
325 | * @param handler 方法调用结果回调(结果会在主线程回调) | Method call result Callback (result will be callback on main thread)
326 | */
327 | public static void enableReceiveNotifyMsg(boolean enable, EnableReceiveNotifyMsgHandler handler){
328 | new EnableReceiveNotifyMsgApi().enableReceiveNotifyMsg(enable, handler);
329 | }
330 |
331 | /**
332 | * 打开/关闭透传消息 | Turn on/off the pass message
333 | * @param enable 打开/关闭 | Turn ON/off
334 | * @param handler 方法调用结果回调(结果会在主线程回调) | Method call result Callback (result will be callback on main thread)
335 | */
336 | public static void enableReceiveNormalMsg(boolean enable, EnableReceiveNormalMsgHandler handler){
337 | new EnableReceiveNormalMsgApi().enableReceiveNormalMsg(enable, handler);
338 | }
339 |
340 | /**
341 | * 请求push协议展示 | Request Push Protocol Display
342 | * @param handler 方法调用结果回调(结果会在主线程回调)| Method call result Callback (result will be callback on main thread)
343 | */
344 | public static void queryAgreement(QueryAgreementHandler handler){
345 | new QueryAgreementApi().queryAgreement(handler);
346 | }
347 | }
348 | }
349 |
--------------------------------------------------------------------------------
/push/src/main/java/com/huawei/android/hms/agent/common/ActivityMgr.java:
--------------------------------------------------------------------------------
1 | package com.huawei.android.hms.agent.common;
2 |
3 | import android.app.Activity;
4 | import android.app.Application;
5 | import android.os.Bundle;
6 |
7 | import java.util.ArrayList;
8 | import java.util.List;
9 |
10 | /**
11 | * Activity Management Class
12 | * 此类注册了activity的生命周期监听,用来获取最新的activity给后续逻辑处理使用 | This class registers the life cycle monitoring of the activity to obtain the latest activity for subsequent logical processing using
13 | */
14 | public final class ActivityMgr implements Application.ActivityLifecycleCallbacks {
15 |
16 | /**
17 | * 单实例 | Single Instance
18 | */
19 | public static final ActivityMgr INST = new ActivityMgr();
20 |
21 | private static final Object LOCK_LASTACTIVITIES = new Object();
22 |
23 | /**
24 | * 应用程序 | application
25 | */
26 | private Application application;
27 |
28 | /**
29 | * 最新的activity列表,如果没有则为空列表 | Latest list of activity, if no, empty list
30 | */
31 | private List curActivities = new ArrayList();
32 |
33 | /**
34 | * activity onResume Event Monitoring
35 | */
36 | private List resumeCallbacks = new ArrayList();
37 |
38 | /**
39 | * activity onPause Event Monitoring
40 | */
41 | private List pauseCallbacks = new ArrayList();
42 |
43 | /**
44 | * activity onDestroyed Event Monitoring
45 | */
46 | private List destroyedCallbacks = new ArrayList();
47 |
48 | /**
49 | * 私有构造方法 | Private construction methods
50 | * 防止外面直接创建实例 | Prevent external instances from being created directly
51 | */
52 | private ActivityMgr(){}
53 |
54 | /**
55 | * 初始化方法 | Initialization method
56 | * @param app 应用程序 | application
57 | */
58 | public void init(Application app, Activity initActivity) {
59 | HMSAgentLog.d("init");
60 |
61 | if (application != null) {
62 | application.unregisterActivityLifecycleCallbacks(this);
63 | }
64 |
65 | application = app;
66 | setCurActivity(initActivity);
67 | app.registerActivityLifecycleCallbacks(this);
68 | }
69 |
70 | /**
71 | * 释放资源,一般不需要调用 | Frees resources, and generally does not need to call
72 | */
73 | public void release() {
74 | HMSAgentLog.d("release");
75 | if (application != null) {
76 | application.unregisterActivityLifecycleCallbacks(this);
77 | }
78 |
79 | clearCurActivities();
80 | clearActivitResumeCallbacks();
81 | clearActivitPauseCallbacks();
82 | application = null;
83 | }
84 |
85 | /**
86 | * 注册activity onResume事件回调 | Registering an Activity Onresume event Callback
87 | * @param callback activity onResume事件回调 | Activity Onresume Event Callback
88 | */
89 | public void registerActivitResumeEvent(IActivityResumeCallback callback) {
90 | HMSAgentLog.d("registerOnResume:" + StrUtils.objDesc(callback));
91 | resumeCallbacks.add(callback);
92 | }
93 |
94 | /**
95 | * 反注册activity onResume事件回调 | unregistration Activity Onresume Event Callback
96 | * @param callback 已经注册的 activity onResume事件回调 | Registered Activity Onresume Event callback
97 | */
98 | public void unRegisterActivitResumeEvent(IActivityResumeCallback callback) {
99 | HMSAgentLog.d("unRegisterOnResume:" + StrUtils.objDesc(callback));
100 | resumeCallbacks.remove(callback);
101 | }
102 |
103 | /**
104 | * 注册activity onPause 事件回调 | Registering an Activity OnPause event Callback
105 | * @param callback activity onPause 事件回调 | Activity OnPause Event Callback
106 | */
107 | public void registerActivitPauseEvent(IActivityPauseCallback callback) {
108 | HMSAgentLog.d("registerOnPause:" + StrUtils.objDesc(callback));
109 | pauseCallbacks.add(callback);
110 | }
111 |
112 | /**
113 | * 反注册activity onPause事件回调 | unregistration activity OnPause Event Callback
114 | * @param callback 已经注册的 activity onPause事件回调 | Registered Activity OnPause Event callback
115 | */
116 | public void unRegisterActivitPauseEvent(IActivityPauseCallback callback) {
117 | HMSAgentLog.d("unRegisterOnPause:" + StrUtils.objDesc(callback));
118 | pauseCallbacks.remove(callback);
119 | }
120 |
121 | /**
122 | * 注册activity onDestroyed 事件回调 | Registering an Activity ondestroyed event Callback
123 | * @param callback activity onDestroyed 事件回调 | Activity Ondestroyed Event Callback
124 | */
125 | public void registerActivitDestroyedEvent(IActivityDestroyedCallback callback) {
126 | HMSAgentLog.d("registerOnDestroyed:" + StrUtils.objDesc(callback));
127 | destroyedCallbacks.add(callback);
128 | }
129 |
130 | /**
131 | * 反注册activity onDestroyed 事件回调 | unregistration Activity ondestroyed Event Callback
132 | * @param callback 已经注册的 activity onDestroyed事件回调 | Registered Activity ondestroyed Event callback
133 | */
134 | public void unRegisterActivitDestroyedEvent(IActivityDestroyedCallback callback) {
135 | HMSAgentLog.d("unRegisterOnDestroyed:" + StrUtils.objDesc(callback));
136 | destroyedCallbacks.remove(callback);
137 | }
138 |
139 | /**
140 | * 清空 activity onResume事件回调 | Clear Activity Onresume Event callback
141 | */
142 | public void clearActivitResumeCallbacks() {
143 | HMSAgentLog.d("clearOnResumeCallback");
144 | resumeCallbacks.clear();
145 | }
146 |
147 | /**
148 | * 清空 activity onPause 事件回调 | Clear Activity OnPause Event callback
149 | */
150 | public void clearActivitPauseCallbacks() {
151 | HMSAgentLog.d("clearOnPauseCallback");
152 | pauseCallbacks.clear();
153 | }
154 |
155 | /**
156 | * 获取最新的activity | Get the latest activity
157 | * @return 最新的activity | Latest activity
158 | */
159 | public Activity getLastActivity() {
160 | return getLastActivityInner();
161 | }
162 |
163 | /**
164 | * activity onCreate 监听回调 | Activity OnCreate Listener Callback
165 | * @param activity 发生onCreate事件的activity | Activity that occurs OnCreate events
166 | * @param savedInstanceState 缓存状态数据 | Cached state data
167 | */
168 | @Override
169 | public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
170 | HMSAgentLog.d("onCreated:" + StrUtils.objDesc(activity));
171 | setCurActivity(activity);
172 | }
173 |
174 | /**
175 | * activity onStart 监听回调 | Activity OnStart Listener Callback
176 | * @param activity 发生onStart事件的activity | Activity that occurs OnStart events
177 | */
178 | @Override
179 | public void onActivityStarted(Activity activity) {
180 | HMSAgentLog.d("onStarted:" + StrUtils.objDesc(activity));
181 | setCurActivity(activity);
182 | }
183 |
184 | /**
185 | * activity onResume 监听回调 | Activity Onresume Listener Callback
186 | * @param activity 发生onResume事件的activity | Activity that occurs Onresume events
187 | */
188 | @Override
189 | public void onActivityResumed(Activity activity) {
190 | HMSAgentLog.d("onResumed:" + StrUtils.objDesc(activity));
191 | setCurActivity(activity);
192 |
193 | List tmdCallbacks = new ArrayList(resumeCallbacks);
194 | for (IActivityResumeCallback callback : tmdCallbacks) {
195 | callback.onActivityResume(activity);
196 | }
197 | }
198 |
199 | /**
200 | * activity onPause 监听回调 | Activity OnPause Listener Callback
201 | * @param activity 发生onPause事件的activity | Activity that occurs OnPause events
202 | */
203 | @Override
204 | public void onActivityPaused(Activity activity) {
205 | HMSAgentLog.d("onPaused:" + StrUtils.objDesc(activity));
206 | List tmdCallbacks = new ArrayList(pauseCallbacks);
207 | for (IActivityPauseCallback callback : tmdCallbacks) {
208 | callback.onActivityPause(activity);
209 | }
210 | }
211 |
212 | /**
213 | * activity onStop 监听回调 | Activity OnStop Listener Callback
214 | * @param activity 发生onStop事件的activity | Activity that occurs OnStop events
215 | */
216 | @Override
217 | public void onActivityStopped(Activity activity) {
218 | HMSAgentLog.d("onStopped:" + StrUtils.objDesc(activity));
219 | }
220 |
221 | /**
222 | * activity onSaveInstanceState 监听回调 | Activity Onsaveinstancestate Listener Callback
223 | * @param activity 发生 onSaveInstanceState 事件的activity | Activity that occurs onsaveinstancestate events
224 | */
225 | @Override
226 | public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
227 | }
228 |
229 | /**
230 | * activity onDestroyed 监听回调 | Activity Ondestroyed Listener Callback
231 | * @param activity 发生 onDestroyed 事件的activity | Activity that occurs ondestroyed events
232 | */
233 | @Override
234 | public void onActivityDestroyed(Activity activity) {
235 | HMSAgentLog.d("onDestroyed:" + StrUtils.objDesc(activity));
236 | removeActivity(activity);
237 |
238 | // activity onDestroyed 事件回调 | Activity Ondestroyed Event Callback
239 | List tmdCallbacks = new ArrayList(destroyedCallbacks);
240 | for (IActivityDestroyedCallback callback : tmdCallbacks) {
241 | callback.onActivityDestroyed(activity, getLastActivityInner());
242 | }
243 | }
244 |
245 | /**
246 | * 移除当前activity | Remove Current Activity
247 | * @param curActivity 要移除的activity | Activity to remove
248 | */
249 | private void removeActivity(Activity curActivity) {
250 | synchronized (LOCK_LASTACTIVITIES) {
251 | curActivities.remove(curActivity);
252 | }
253 | }
254 |
255 | /**
256 | * 设置最新的activity | Set up the latest activity
257 | * @param curActivity 最新的activity | Latest activity
258 | */
259 | private void setCurActivity(Activity curActivity) {
260 | synchronized (LOCK_LASTACTIVITIES) {
261 | int idxCurActivity = curActivities.indexOf(curActivity);
262 | if (idxCurActivity == -1) {
263 | curActivities.add(curActivity);
264 | } else if (idxCurActivity < curActivities.size()-1){
265 | curActivities.remove(curActivity);
266 | curActivities.add(curActivity);
267 | }
268 | }
269 | }
270 |
271 | /**
272 | * 获取最新的activity,如果没有则返回null | Gets the latest activity and returns null if not
273 | * @return 最新的activity | Latest activity
274 | */
275 | private Activity getLastActivityInner(){
276 | synchronized (LOCK_LASTACTIVITIES) {
277 | if (curActivities.size() > 0) {
278 | return curActivities.get(curActivities.size()-1);
279 | } else {
280 | return null;
281 | }
282 | }
283 | }
284 |
285 | /**
286 | * 清理activities | Clean activities
287 | */
288 | private void clearCurActivities(){
289 | synchronized (LOCK_LASTACTIVITIES) {
290 | curActivities.clear();
291 | }
292 | }
293 | }
--------------------------------------------------------------------------------
/push/src/main/java/com/huawei/android/hms/agent/common/ApiClientMgr.java:
--------------------------------------------------------------------------------
1 | package com.huawei.android.hms.agent.common;
2 |
3 | import android.app.Activity;
4 | import android.app.Application;
5 | import android.content.Context;
6 | import android.content.Intent;
7 | import android.os.Handler;
8 | import android.os.Message;
9 |
10 | import com.huawei.android.hms.agent.HMSAgent;
11 | import com.huawei.hms.activity.BridgeActivity;
12 | import com.huawei.hms.api.ConnectionResult;
13 | import com.huawei.hms.api.HuaweiApiAvailability;
14 | import com.huawei.hms.api.HuaweiApiClient;
15 | import com.huawei.hms.support.api.push.HuaweiPush;
16 |
17 | import java.util.ArrayList;
18 | import java.util.List;
19 |
20 |
21 | /**
22 | * Huawei Api Client 管理类 | Huawei API Client Management class
23 | * 负责HuaweiApiClient的连接,异常处理等 | Responsible for huaweiapiclient connection, exception handling, etc.
24 | */
25 | public final class ApiClientMgr implements HuaweiApiClient.ConnectionCallbacks, HuaweiApiClient.OnConnectionFailedListener, IActivityResumeCallback, IActivityPauseCallback, IActivityDestroyedCallback {
26 |
27 | /**
28 | * 单实例
29 | */
30 | public static final ApiClientMgr INST = new ApiClientMgr();
31 |
32 | /**
33 | * 应用市场包名
34 | */
35 | private static final String PACKAGE_NAME_HIAPP = "com.huawei.appmarket";
36 |
37 | /**
38 | * 回调锁,避免连接回调紊乱
39 | */
40 | private static final Object CALLBACK_LOCK = new Object();
41 |
42 | /**
43 | * 静态注册回调锁,避免注册和回调紊乱
44 | */
45 | private static final Object STATIC_CALLBACK_LOCK = new Object();
46 |
47 | /**
48 | * client操作锁,避免连接使用紊乱
49 | */
50 | private static final Object APICLIENT_LOCK = new Object();
51 |
52 | /**
53 | * api client 连接超时
54 | */
55 | private static final int APICLIENT_CONNECT_TIMEOUT = 30000;
56 |
57 | /**
58 | * 解决升级错误时activity onResume 稳定在3秒时间判断BridgeActivity上面有没有其他activity
59 | */
60 | private static final int UPDATE_OVER_ACTIVITY_CHECK_TIMEOUT = 3000;
61 |
62 | /**
63 | * api client 解决错误拉起界面超时
64 | */
65 | private static final int APICLIENT_STARTACTIVITY_TIMEOUT = 3000;
66 |
67 | /**
68 | * client 连接超时消息
69 | */
70 | private static final int APICLIENT_TIMEOUT_HANDLE_MSG = 3;
71 |
72 | /**
73 | * client 拉起activity超时消息
74 | */
75 | private static final int APICLIENT_STARTACTIVITY_TIMEOUT_HANDLE_MSG = 4;
76 |
77 | /**
78 | * 解决升级错误时activity onResume 稳定在3秒时间判断BridgeActivity上面有没有其他activity
79 | */
80 | private static final int UPDATE_OVER_ACTIVITY_CHECK_TIMEOUT_HANDLE_MSG = 5;
81 |
82 | /**
83 | * 最大尝试连接次数
84 | */
85 | private static final int MAX_RESOLVE_TIMES = 3;
86 |
87 | /**
88 | * 上下文,用来处理连接失败
89 | */
90 | private Context context;
91 |
92 | /**
93 | * 当前应用包名
94 | */
95 | private String curAppPackageName;
96 |
97 | /**
98 | * HuaweiApiClient 实例
99 | */
100 | private HuaweiApiClient apiClient;
101 |
102 | /**
103 | * 是否允许解决connect错误(解决connect错误需要拉起activity)
104 | */
105 | private boolean allowResolveConnectError = false;
106 |
107 | /**
108 | * 是否正在解决连接错误
109 | */
110 | private boolean isResolving;
111 |
112 | /**
113 | * HMSSDK 解决错误的activity
114 | */
115 | private BridgeActivity resolveActivity;
116 |
117 | /**
118 | * 是否存在其他activity覆盖在升级activity之上
119 | */
120 | private boolean hasOverActivity = false;
121 |
122 | /**
123 | * 当前剩余尝试次数
124 | */
125 | private int curLeftResolveTimes = MAX_RESOLVE_TIMES;
126 |
127 | /**
128 | * 连接回调
129 | */
130 | private List connCallbacks = new ArrayList();
131 |
132 | /**
133 | * 注册的静态回调
134 | */
135 | private List staticCallbacks = new ArrayList();
136 |
137 | /**
138 | * 超时handler用来处理client connect 超时
139 | */
140 | private Handler timeoutHandler = new Handler(new Handler.Callback() {
141 | @Override
142 | public boolean handleMessage(Message msg) {
143 |
144 | boolean hasConnCallbacks;
145 | synchronized (CALLBACK_LOCK) {
146 | hasConnCallbacks = !connCallbacks.isEmpty();
147 | }
148 |
149 | if (msg != null && msg.what == APICLIENT_TIMEOUT_HANDLE_MSG && hasConnCallbacks) {
150 | HMSAgentLog.d("connect time out");
151 | resetApiClient();
152 | onConnectEnd(HMSAgent.AgentResultCode.APICLIENT_TIMEOUT);
153 | return true;
154 | } else if (msg != null && msg.what == APICLIENT_STARTACTIVITY_TIMEOUT_HANDLE_MSG && hasConnCallbacks) {
155 | HMSAgentLog.d("start activity time out");
156 | onConnectEnd(HMSAgent.AgentResultCode.APICLIENT_TIMEOUT);
157 | return true;
158 | } else if (msg != null && msg.what == UPDATE_OVER_ACTIVITY_CHECK_TIMEOUT_HANDLE_MSG && hasConnCallbacks) {
159 | HMSAgentLog.d("Discarded update dispose:hasOverActivity=" +hasOverActivity + " resolveActivity=" + StrUtils.objDesc(resolveActivity));
160 | if (hasOverActivity && resolveActivity != null && !resolveActivity.isFinishing()) {
161 | onResolveErrorRst(ConnectionResult.CANCELED);
162 | }
163 | return true;
164 | }
165 | return false;
166 | }
167 | });
168 |
169 | /**
170 | * 私有构造方法
171 | */
172 | private ApiClientMgr () {
173 | }
174 |
175 | /**
176 | * 初始化
177 | * @param app 应用程序
178 | */
179 | public void init(Application app) {
180 |
181 | HMSAgentLog.d("init");
182 |
183 | // 保存应用程序context
184 | context = app.getApplicationContext();
185 |
186 | // 取得应用程序包名
187 | curAppPackageName = app.getPackageName();
188 |
189 | // 注册activity onResume回调
190 | ActivityMgr.INST.unRegisterActivitResumeEvent(this);
191 | ActivityMgr.INST.registerActivitResumeEvent(this);
192 |
193 | // 注册activity onPause回调
194 | ActivityMgr.INST.unRegisterActivitPauseEvent(this);
195 | ActivityMgr.INST.registerActivitPauseEvent(this);
196 |
197 | // 注册activity onDestroyed 回调
198 | ActivityMgr.INST.unRegisterActivitDestroyedEvent(this);
199 | ActivityMgr.INST.registerActivitDestroyedEvent(this);
200 | }
201 |
202 | /**
203 | * 断开apiclient,一般不需要调用
204 | */
205 | public void release() {
206 | HMSAgentLog.d("release");
207 |
208 | isResolving = false;
209 | resolveActivity = null;
210 | hasOverActivity = false;
211 |
212 | HuaweiApiClient client = getApiClient();
213 | if (client != null) {
214 | client.disconnect();
215 | synchronized (APICLIENT_LOCK) {
216 | apiClient = null;
217 | }
218 | }
219 |
220 | synchronized (STATIC_CALLBACK_LOCK) {
221 | staticCallbacks.clear();
222 | }
223 |
224 | synchronized (CALLBACK_LOCK) {
225 | connCallbacks.clear();
226 | }
227 | }
228 |
229 | /**
230 | * 获取当前的 HuaweiApiClient
231 | * @return HuaweiApiClient 实例
232 | */
233 | public HuaweiApiClient getApiClient() {
234 | synchronized (APICLIENT_LOCK) {
235 | return apiClient;
236 | }
237 | }
238 |
239 | /**
240 | * 判断client是否已经连接
241 | * @param client 要检测的client
242 | * @return 是否已经连接
243 | */
244 | public boolean isConnect(HuaweiApiClient client) {
245 | return client != null && client.isConnected();
246 | }
247 |
248 | /**
249 | * 注册apiclient连接事件
250 | * @param staticCallback 连接回调
251 | */
252 | public void registerClientConnect(IClientConnectCallback staticCallback){
253 | synchronized (STATIC_CALLBACK_LOCK) {
254 | staticCallbacks.add(staticCallback);
255 | }
256 | }
257 |
258 | /**
259 | * 反注册apiclient连接事件
260 | * @param staticCallback 连接回调
261 | */
262 | public void removeClientConnectCallback(IClientConnectCallback staticCallback) {
263 | synchronized (STATIC_CALLBACK_LOCK) {
264 | staticCallbacks.remove(staticCallback);
265 | }
266 | }
267 |
268 | /**
269 | * 重新创建apiclient
270 | * 2种情况需要重新创建:1、首次 2、client的状态已经紊乱
271 | * @return 新创建的client
272 | */
273 | private HuaweiApiClient resetApiClient(){
274 | synchronized (APICLIENT_LOCK) {
275 | if (apiClient != null) {
276 | // 对于老的apiClient,1分钟后才丢弃,防止外面正在使用过程中这边disConnect了
277 | disConnectClientDelay(apiClient, 60000);
278 | }
279 |
280 | HMSAgentLog.d("reset client");
281 |
282 | // 这种重置client,极端情况可能会出现2个client都回调结果的情况。此时可能出现rstCode=0,但是client无效。
283 | // 因为业务调用封装中都进行了一次重试。所以不会有问题
284 | apiClient = new HuaweiApiClient.Builder(context)
285 | .addApi(HuaweiPush.PUSH_API)
286 | .addConnectionCallbacks(INST)
287 | .addOnConnectionFailedListener(INST)
288 | .build();
289 | return apiClient;
290 | }
291 | }
292 |
293 | /**
294 | * 连接 HuaweiApiClient,
295 | * @param callback 连接结果回调,一定不能为null,在子线程进行回调
296 | * @param allowResolve 是否允许解决错误,解决错误时可能会拉起界面
297 | */
298 | public void connect(IClientConnectCallback callback, boolean allowResolve) {
299 |
300 | if (context == null) {
301 | aSysnCallback(HMSAgent.AgentResultCode.HMSAGENT_NO_INIT, callback);
302 | return;
303 | }
304 |
305 | HuaweiApiClient client = getApiClient();
306 | // client 有效,则直接回调
307 | if (client != null && client.isConnected()) {
308 | HMSAgentLog.d("client is valid");
309 | aSysnCallback(HMSAgent.AgentResultCode.HMSAGENT_SUCCESS, callback);
310 | return;
311 | } else {
312 | // client无效,将callback加入队列,并启动连接
313 | synchronized (CALLBACK_LOCK) {
314 | HMSAgentLog.d("client is invalid:size=" + connCallbacks.size());
315 | allowResolveConnectError = allowResolveConnectError || allowResolve;
316 | if (connCallbacks.isEmpty()) {
317 | connCallbacks.add(callback);
318 |
319 | // 连接尝试最大次数
320 | curLeftResolveTimes = MAX_RESOLVE_TIMES;
321 |
322 | startConnect();
323 | } else {
324 | connCallbacks.add(callback);
325 | }
326 | }
327 | }
328 | }
329 |
330 | /**
331 | * 线程中进行Huawei Api Client 的连接
332 | */
333 | private void startConnect() {
334 |
335 | // 触发一次连接将重试次数减1
336 | curLeftResolveTimes--;
337 |
338 | HMSAgentLog.d("start thread to connect");
339 | ThreadUtil.INST.excute(new Runnable() {
340 | @Override
341 | public void run() {
342 | HuaweiApiClient client = getApiClient();
343 | if (client == null) {
344 | HMSAgentLog.d("create client");
345 | client = resetApiClient();
346 | }
347 |
348 | HMSAgentLog.d("connect");
349 | Activity curActivity = ActivityMgr.INST.getLastActivity();
350 |
351 | // 考虑到有cp后台需要调用接口,HMSSDK去掉了activity不能为空的判断。这里只是取当前activity,可能为空
352 | timeoutHandler.sendEmptyMessageDelayed(APICLIENT_TIMEOUT_HANDLE_MSG, APICLIENT_CONNECT_TIMEOUT);
353 | client.connect(curActivity);
354 | }
355 | });
356 | }
357 |
358 | /**
359 | * Huawei Api Client 连接结束方法
360 | * @param rstCode client 连接结果码
361 | */
362 | private void onConnectEnd(final int rstCode) {
363 | HMSAgentLog.d("connect end:" + rstCode);
364 |
365 | synchronized (CALLBACK_LOCK) {
366 | // 回调各个回调接口连接结束
367 | for (IClientConnectCallback callback : connCallbacks) {
368 | aSysnCallback(rstCode, callback);
369 | }
370 | connCallbacks.clear();
371 |
372 | // 恢复默认不显示
373 | allowResolveConnectError = false;
374 | }
375 |
376 | synchronized (STATIC_CALLBACK_LOCK) {
377 | // 回调各个回调接口连接结束
378 | for (IClientConnectCallback callback : staticCallbacks) {
379 | aSysnCallback(rstCode, callback);
380 | }
381 | staticCallbacks.clear();
382 | }
383 | }
384 |
385 | /**
386 | * 起线程回调各个接口,避免其中一个回调者耗时长影响其他调用者
387 | * @param rstCode 结果码
388 | * @param callback 回调
389 | */
390 | private void aSysnCallback(final int rstCode, final IClientConnectCallback callback) {
391 | ThreadUtil.INST.excute(new Runnable() {
392 | @Override
393 | public void run() {
394 | HuaweiApiClient client = getApiClient();
395 | HMSAgentLog.d("callback connect: rst=" + rstCode + " apiClient=" + client);
396 | callback.onConnect(rstCode, client);
397 | }
398 | });
399 | }
400 |
401 | /**
402 | * Activity onResume回调
403 | *
404 | * @param activity 发生 onResume 事件的activity
405 | */
406 | @Override
407 | public void onActivityResume(Activity activity) {
408 | // 通知hmssdk activity onResume了
409 | if (apiClient != null) {
410 | HMSAgentLog.d("tell hmssdk: onResume");
411 | apiClient.onResume(activity);
412 | }
413 |
414 | // 如果正在解决错误,则处理被覆盖的场景
415 | HMSAgentLog.d("is resolving:" + isResolving);
416 | if (isResolving && !PACKAGE_NAME_HIAPP.equals(curAppPackageName)) {
417 | if (activity instanceof BridgeActivity) {
418 | resolveActivity = (BridgeActivity)activity;
419 | hasOverActivity = false;
420 | HMSAgentLog.d("received bridgeActivity:" + StrUtils.objDesc(resolveActivity));
421 | } else if (resolveActivity != null && !resolveActivity.isFinishing()){
422 | hasOverActivity = true;
423 | HMSAgentLog.d("received other Activity:" + StrUtils.objDesc(resolveActivity));
424 | }
425 | timeoutHandler.removeMessages(UPDATE_OVER_ACTIVITY_CHECK_TIMEOUT_HANDLE_MSG);
426 | timeoutHandler.sendEmptyMessageDelayed(UPDATE_OVER_ACTIVITY_CHECK_TIMEOUT_HANDLE_MSG, UPDATE_OVER_ACTIVITY_CHECK_TIMEOUT);
427 | }
428 | }
429 |
430 | /**
431 | * Activity onPause回调
432 | *
433 | * @param activity 发生 onPause 事件的activity
434 | */
435 | @Override
436 | public void onActivityPause(Activity activity) {
437 | // 通知hmssdk,activity onPause了
438 | if (apiClient != null) {
439 | apiClient.onPause(activity);
440 | }
441 | }
442 |
443 | /**
444 | * Activity onPause回调
445 | *
446 | * @param activityDestroyed 发生 onDestroyed 事件的activity
447 | * @param activityNxt 下个要显示的activity
448 | */
449 | @Override
450 | public void onActivityDestroyed(Activity activityDestroyed, Activity activityNxt) {
451 | if (activityNxt == null) {
452 | // 所有activity销毁后,重置client,否则公告的标志位还在,下次弹不出来
453 | resetApiClient();
454 | }
455 | }
456 |
457 | /**
458 | * connect fail 解决结果回调, 由 HMSAgentActivity 在 onActivityResult 中调用
459 | * @param result 解决结果
460 | */
461 | void onResolveErrorRst(int result) {
462 | HMSAgentLog.d("result="+result);
463 | isResolving = false;
464 | resolveActivity = null;
465 | hasOverActivity = false;
466 |
467 | if(result == ConnectionResult.SUCCESS) {
468 | HuaweiApiClient client = getApiClient();
469 | if (!client.isConnecting() && !client.isConnected() && curLeftResolveTimes > 0) {
470 | startConnect();
471 | return;
472 | }
473 | }
474 |
475 | onConnectEnd(result);
476 | }
477 |
478 | /**
479 | * HMSAgentActivity 拉起拉了(走了onCreate)
480 | */
481 | void onActivityLunched(){
482 | HMSAgentLog.d("resolve onActivityLunched");
483 | // 拉起界面回调,移除拉起界面超时
484 | timeoutHandler.removeMessages(APICLIENT_STARTACTIVITY_TIMEOUT_HANDLE_MSG);
485 | isResolving = true;
486 | }
487 |
488 | /**
489 | * Huawe Api Client 连接成功回到
490 | */
491 | @Override
492 | public void onConnected() {
493 | HMSAgentLog.d("connect success");
494 | timeoutHandler.removeMessages(APICLIENT_TIMEOUT_HANDLE_MSG);
495 | onConnectEnd(ConnectionResult.SUCCESS);
496 | }
497 |
498 | /**
499 | * 当client变成断开状态时会被调用。这有可能发生在远程服务出现问题时(例如:出现crash或资源问题导致服务被系统杀掉)。
500 | * 当被调用时,所有的请求都会被取消,任何listeners都不会被执行。需要 CP 开发代码尝试恢复连接(connect)。
501 | * 应用程序应该禁用需要服务的相关UI组件,等待{@link #onConnected()} 回调后重新启用他们。
502 | *
503 | * @param cause 断开的原因. 常量定义: CAUSE_*.
504 | */
505 | @Override
506 | public void onConnectionSuspended(int cause) {
507 | HMSAgentLog.d("connect suspended");
508 | connect(new EmptyConnectCallback("onConnectionSuspended try end:"), true);
509 | }
510 |
511 | /**
512 | * 建立client到service的连接失败时调用
513 | *
514 | * @param result 连接结果,用于解决错误和知道什么类型的错误
515 | */
516 | @Override
517 | public void onConnectionFailed(ConnectionResult result) {
518 | timeoutHandler.removeMessages(APICLIENT_TIMEOUT_HANDLE_MSG);
519 |
520 | if (result == null) {
521 | HMSAgentLog.e("result is null");
522 | onConnectEnd(HMSAgent.AgentResultCode.RESULT_IS_NULL);
523 | return;
524 | }
525 |
526 | int errCode = result.getErrorCode();
527 | HMSAgentLog.d("errCode=" + errCode + " allowResolve=" + allowResolveConnectError);
528 |
529 | if(HuaweiApiAvailability.getInstance().isUserResolvableError(errCode) && allowResolveConnectError) {
530 | Activity activity = ActivityMgr.INST.getLastActivity();
531 | if (activity != null) {
532 | try {
533 | timeoutHandler.sendEmptyMessageDelayed(APICLIENT_STARTACTIVITY_TIMEOUT_HANDLE_MSG, APICLIENT_STARTACTIVITY_TIMEOUT);
534 | Intent intent = new Intent(activity, HMSAgentActivity.class);
535 | intent.putExtra(HMSAgentActivity.CONN_ERR_CODE_TAG, errCode);
536 | activity.startActivity(intent);
537 | return;
538 | } catch (Exception e) {
539 | HMSAgentLog.e("start HMSAgentActivity exception:" + e.getMessage());
540 | timeoutHandler.removeMessages(APICLIENT_STARTACTIVITY_TIMEOUT_HANDLE_MSG);
541 | onConnectEnd(HMSAgent.AgentResultCode.START_ACTIVITY_ERROR);
542 | return;
543 | }
544 | } else {
545 | // 当前没有界面处理不了错误
546 | HMSAgentLog.d("no activity");
547 | onConnectEnd(HMSAgent.AgentResultCode.NO_ACTIVITY_FOR_USE);
548 | return;
549 | }
550 | } else {
551 | //其他错误码直接透传
552 | }
553 |
554 | onConnectEnd(errCode);
555 | }
556 |
557 | private static void disConnectClientDelay(final HuaweiApiClient clientTmp, int delay) {
558 | new Handler().postDelayed(new Runnable() {
559 | @Override
560 | public void run() {
561 | clientTmp.disconnect();
562 | }
563 | }, delay);
564 | }
565 | }
566 |
--------------------------------------------------------------------------------
/push/src/main/java/com/huawei/android/hms/agent/common/BaseAgentActivity.java:
--------------------------------------------------------------------------------
1 | package com.huawei.android.hms.agent.common;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 | import android.view.Window;
6 |
7 | /**
8 | * 基础activity,用来处理公共的透明参数
9 | */
10 | public class BaseAgentActivity extends Activity {
11 |
12 | @Override
13 | protected void onCreate(Bundle savedInstanceState) {
14 | super.onCreate(savedInstanceState);
15 | requestActivityTransparent();
16 | }
17 |
18 | /**
19 | * 启用透明的跳板Activity
20 | */
21 | private void requestActivityTransparent() {
22 | requestWindowFeature(Window.FEATURE_NO_TITLE);
23 | Window window = getWindow();
24 | if (window != null) {
25 | window.addFlags(0x04000000);
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/push/src/main/java/com/huawei/android/hms/agent/common/BaseApiAgent.java:
--------------------------------------------------------------------------------
1 | package com.huawei.android.hms.agent.common;
2 |
3 | /**
4 | * API 实现类基类,用于处理公共操作
5 | * 目前实现的是client的连接及回调
6 | */
7 | public abstract class BaseApiAgent implements IClientConnectCallback {
8 | protected void connect() {
9 | HMSAgentLog.d("connect");
10 | ApiClientMgr.INST.connect(this, true);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/push/src/main/java/com/huawei/android/hms/agent/common/CallbackCodeRunnable.java:
--------------------------------------------------------------------------------
1 | package com.huawei.android.hms.agent.common;
2 |
3 | /**
4 | * 回调线程
5 | */
6 | public class CallbackCodeRunnable implements Runnable {
7 |
8 | private ICallbackCode handlerInner;
9 | private int rtnCodeInner;
10 |
11 | public CallbackCodeRunnable(ICallbackCode handler, int rtnCode) {
12 | handlerInner = handler;
13 | rtnCodeInner = rtnCode;
14 | }
15 |
16 | @Override
17 | public void run() {
18 | if (handlerInner != null) {
19 | handlerInner.onResult(rtnCodeInner);
20 | }
21 | }
22 | }
--------------------------------------------------------------------------------
/push/src/main/java/com/huawei/android/hms/agent/common/CallbackResultRunnable.java:
--------------------------------------------------------------------------------
1 | package com.huawei.android.hms.agent.common;
2 |
3 | /**
4 | * 回调线程
5 | */
6 | public class CallbackResultRunnable implements Runnable {
7 |
8 | private ICallbackResult handlerInner;
9 | private int rtnCodeInner;
10 | private R resultInner;
11 |
12 | public CallbackResultRunnable(ICallbackResult handler, int rtnCode, R payInfo) {
13 | handlerInner = handler;
14 | rtnCodeInner = rtnCode;
15 | resultInner = payInfo;
16 | }
17 |
18 | @Override
19 | public void run() {
20 | if (handlerInner != null) {
21 | handlerInner.onResult(rtnCodeInner, resultInner);
22 | }
23 | }
24 | }
--------------------------------------------------------------------------------
/push/src/main/java/com/huawei/android/hms/agent/common/EmptyConnectCallback.java:
--------------------------------------------------------------------------------
1 | package com.huawei.android.hms.agent.common;
2 |
3 | import com.huawei.hms.api.HuaweiApiClient;
4 |
5 | /**
6 | * 连接client空回调
7 | */
8 | public class EmptyConnectCallback implements IClientConnectCallback {
9 |
10 | private String msgPre;
11 |
12 | public EmptyConnectCallback(String msgPre){
13 | this.msgPre = msgPre;
14 | }
15 |
16 | /**
17 | * HuaweiApiClient 连接结果回调
18 | *
19 | * @param rst 结果码
20 | * @param client HuaweiApiClient 实例
21 | */
22 | @Override
23 | public void onConnect(int rst, HuaweiApiClient client) {
24 | HMSAgentLog.d(msgPre + rst);
25 | }
26 | }
--------------------------------------------------------------------------------
/push/src/main/java/com/huawei/android/hms/agent/common/HMSAgentActivity.java:
--------------------------------------------------------------------------------
1 | package com.huawei.android.hms.agent.common;
2 |
3 | import android.app.Activity;
4 | import android.content.Intent;
5 | import android.os.Bundle;
6 |
7 | import com.huawei.android.hms.agent.HMSAgent;
8 | import com.huawei.hms.api.HuaweiApiAvailability;
9 |
10 | /**
11 | * 代理Activity,用于弹出解决问题的引导
12 | */
13 | public class HMSAgentActivity extends BaseAgentActivity {
14 |
15 | /**
16 | * 参数标签,用于取得要解决的错误码
17 | */
18 | public static final String CONN_ERR_CODE_TAG = "HMSConnectionErrorCode";
19 |
20 | /**
21 | * 解决错误后结果的标签,用来取得解决的结果
22 | */
23 | public static final String EXTRA_RESULT = "intent.extra.RESULT";
24 |
25 | /**
26 | * 解决错误的requestCode
27 | */
28 | private static final int REQUEST_HMS_RESOLVE_ERROR = 1000;
29 |
30 | @Override
31 | protected void onCreate(Bundle savedInstanceState) {
32 | super.onCreate(savedInstanceState);
33 | ApiClientMgr.INST.onActivityLunched();
34 |
35 | Intent intent = getIntent();
36 | if (intent != null) {
37 | int rstCode = intent.getIntExtra(CONN_ERR_CODE_TAG, 0);
38 | HMSAgentLog.d("dispose code:" + rstCode);
39 | HuaweiApiAvailability.getInstance().resolveError(this, rstCode, REQUEST_HMS_RESOLVE_ERROR);
40 | } else {
41 | HMSAgentLog.e("intent is null");
42 | finish();
43 | }
44 | }
45 |
46 | @Override
47 | protected void onActivityResult(int requestCode, int resultCode, Intent data) {
48 | super.onActivityResult(requestCode, resultCode, data);
49 |
50 | if(requestCode == REQUEST_HMS_RESOLVE_ERROR) {
51 | if(resultCode == Activity.RESULT_OK) {
52 |
53 | int result = data.getIntExtra(EXTRA_RESULT, -1);
54 | HMSAgentLog.d("dispose result:" + result);
55 | ApiClientMgr.INST.onResolveErrorRst(result);
56 | } else {
57 | HMSAgentLog.e("dispose error:" + resultCode);
58 | ApiClientMgr.INST.onResolveErrorRst(HMSAgent.AgentResultCode.ON_ACTIVITY_RESULT_ERROR);
59 | }
60 | finish();
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/push/src/main/java/com/huawei/android/hms/agent/common/HMSAgentLog.java:
--------------------------------------------------------------------------------
1 | package com.huawei.android.hms.agent.common;
2 |
3 | import android.util.Log;
4 |
5 | /**
6 | * 日志打印类,对打印日志进行封装,方便根据日志定位问题
7 | */
8 | public final class HMSAgentLog {
9 |
10 | /**
11 | * 日志回调,将要打印的日志回调给开发者,由开发者将日志输出
12 | */
13 | public interface IHMSAgentLogCallback {
14 | void logD(String tag, String log);
15 | void logV(String tag, String log);
16 | void logI(String tag, String log);
17 | void logW(String tag, String log);
18 | void logE(String tag, String log);
19 | }
20 |
21 | private static final int START_STACK_INDEX = 4;
22 | private static final int PRINT_STACK_COUTN = 2;
23 |
24 | private static IHMSAgentLogCallback logCallback = null;
25 |
26 | public static void setHMSAgentLogCallback(IHMSAgentLogCallback callback){
27 | logCallback = callback;
28 | }
29 |
30 | public static void d(String log) {
31 | StringBuilder sb = new StringBuilder();
32 | appendStack(sb);
33 | sb.append(log);
34 |
35 | if (logCallback != null) {
36 | logCallback.logD("HMSAgent", sb.toString());
37 | } else {
38 | Log.d("HMSAgent", sb.toString());
39 | }
40 | }
41 |
42 | public static void v(String log) {
43 | StringBuilder sb = new StringBuilder();
44 | appendStack(sb);
45 | sb.append(log);
46 | if (logCallback != null) {
47 | logCallback.logV("HMSAgent", sb.toString());
48 | } else {
49 | Log.v("HMSAgent", sb.toString());
50 | }
51 | }
52 |
53 | public static void i(String log) {
54 | StringBuilder sb = new StringBuilder();
55 | appendStack(sb);
56 | sb.append(log);
57 | if (logCallback != null) {
58 | logCallback.logI("HMSAgent", sb.toString());
59 | } else {
60 | Log.i("HMSAgent", sb.toString());
61 | }
62 | }
63 |
64 | public static void w(String log) {
65 | StringBuilder sb = new StringBuilder();
66 | appendStack(sb);
67 | sb.append(log);
68 | if (logCallback != null) {
69 | logCallback.logW("HMSAgent", sb.toString());
70 | } else {
71 | Log.w("HMSAgent", sb.toString());
72 | }
73 | }
74 |
75 | public static void e(String log) {
76 | StringBuilder sb = new StringBuilder();
77 | appendStack(sb);
78 | sb.append(log);
79 |
80 | if (logCallback != null) {
81 | logCallback.logE("HMSAgent", sb.toString());
82 | } else {
83 | Log.e("HMSAgent", sb.toString());
84 | }
85 | }
86 |
87 | private static void appendStack(StringBuilder sb) {
88 | StackTraceElement[] stacks = Thread.currentThread().getStackTrace();
89 | if (stacks != null && stacks.length > START_STACK_INDEX) {
90 | int lastIndex = Math.min(stacks.length-1,START_STACK_INDEX+PRINT_STACK_COUTN);
91 | for (int i=lastIndex; i >= START_STACK_INDEX; i--) {
92 | if (stacks[i] == null) {
93 | continue;
94 | }
95 |
96 | String fileName = stacks[i].getFileName();
97 | if (fileName != null) {
98 | int dotIndx = fileName.indexOf('.');
99 | if (dotIndx > 0) {
100 | fileName = fileName.substring(0, dotIndx);
101 | }
102 | }
103 |
104 | sb.append(fileName);
105 | sb.append('(');
106 | sb.append(stacks[i].getLineNumber());
107 | sb.append(")");
108 | sb.append("->");
109 | }
110 | sb.append(stacks[START_STACK_INDEX].getMethodName());
111 | }
112 | sb.append('\n');
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/push/src/main/java/com/huawei/android/hms/agent/common/IActivityDestroyedCallback.java:
--------------------------------------------------------------------------------
1 | package com.huawei.android.hms.agent.common;
2 |
3 | import android.app.Activity;
4 |
5 | /**
6 | * Activity onDestroyed 事件回调接口
7 | */
8 | public interface IActivityDestroyedCallback {
9 |
10 | /**
11 | * Activity onPause回调
12 | * @param activityDestroyed 发生 onDestroyed 事件的activity
13 | * @param activityNxt 下个要显示的activity
14 | */
15 | void onActivityDestroyed(Activity activityDestroyed, Activity activityNxt);
16 | }
17 |
--------------------------------------------------------------------------------
/push/src/main/java/com/huawei/android/hms/agent/common/IActivityPauseCallback.java:
--------------------------------------------------------------------------------
1 | package com.huawei.android.hms.agent.common;
2 |
3 | import android.app.Activity;
4 |
5 | /**
6 | * Activity onPause 事件回调接口
7 | */
8 | public interface IActivityPauseCallback {
9 |
10 | /**
11 | * Activity onPause回调
12 | * @param activity 发生 onPause 事件的activity
13 | */
14 | void onActivityPause(Activity activity);
15 | }
16 |
--------------------------------------------------------------------------------
/push/src/main/java/com/huawei/android/hms/agent/common/IActivityResumeCallback.java:
--------------------------------------------------------------------------------
1 | package com.huawei.android.hms.agent.common;
2 |
3 | import android.app.Activity;
4 |
5 | /**
6 | * Activity onResume 事件回调接口
7 | */
8 | public interface IActivityResumeCallback {
9 |
10 | /**
11 | * Activity onResume回调
12 | * @param activity 发生 onResume 事件的activity
13 | */
14 | void onActivityResume(Activity activity);
15 | }
16 |
--------------------------------------------------------------------------------
/push/src/main/java/com/huawei/android/hms/agent/common/ICallbackCode.java:
--------------------------------------------------------------------------------
1 | package com.huawei.android.hms.agent.common;
2 |
3 | /**
4 | * 回调接口
5 | */
6 | public interface ICallbackCode {
7 | /**
8 | * 回调接口
9 | * @param rst 结果码
10 | */
11 | void onResult(int rst);
12 | }
13 |
--------------------------------------------------------------------------------
/push/src/main/java/com/huawei/android/hms/agent/common/ICallbackResult.java:
--------------------------------------------------------------------------------
1 | package com.huawei.android.hms.agent.common;
2 |
3 | /**
4 | * 回调接口
5 | */
6 | public interface ICallbackResult {
7 | /**
8 | * 回调接口
9 | * @param rst 结果码
10 | * @param result 结果信息
11 | */
12 | void onResult(int rst, R result);
13 | }
14 |
--------------------------------------------------------------------------------
/push/src/main/java/com/huawei/android/hms/agent/common/IClientConnectCallback.java:
--------------------------------------------------------------------------------
1 | package com.huawei.android.hms.agent.common;
2 |
3 | import com.huawei.hms.api.HuaweiApiClient;
4 |
5 | /**
6 | * HuaweiApiClient 连接结果回调
7 | */
8 | public interface IClientConnectCallback {
9 | /**
10 | * HuaweiApiClient 连接结果回调
11 | * @param rst 结果码
12 | * @param client HuaweiApiClient 实例
13 | */
14 | void onConnect(int rst, HuaweiApiClient client);
15 | }
16 |
--------------------------------------------------------------------------------
/push/src/main/java/com/huawei/android/hms/agent/common/INoProguard.java:
--------------------------------------------------------------------------------
1 | package com.huawei.android.hms.agent.common;
2 |
3 | /**
4 | * 不混淆类
5 | */
6 | public interface INoProguard {
7 | }
8 |
--------------------------------------------------------------------------------
/push/src/main/java/com/huawei/android/hms/agent/common/IOUtils.java:
--------------------------------------------------------------------------------
1 | package com.huawei.android.hms.agent.common;
2 |
3 | import java.io.Closeable;
4 | import java.io.IOException;
5 |
6 | /**
7 | * 工具类
8 | */
9 | public final class IOUtils {
10 | public static void close(Closeable object) {
11 | if (object != null) {
12 | try {
13 | object.close();
14 | } catch (IOException e) {
15 | HMSAgentLog.d("close fail");
16 | }
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/push/src/main/java/com/huawei/android/hms/agent/common/StrUtils.java:
--------------------------------------------------------------------------------
1 | package com.huawei.android.hms.agent.common;
2 |
3 | /**
4 | * 工具类
5 | */
6 | public final class StrUtils {
7 | /**
8 | * 返回对象的描述,这里为了避免用户数据隐私的泄露,只是返回对象本身的描述 类名@hashcode
9 | * @param object 对象
10 | * @return 对象的描述
11 | */
12 | public static String objDesc(Object object) {
13 | return object == null ? "null" : (object.getClass().getName()+'@'+Integer.toHexString(object.hashCode()));
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/push/src/main/java/com/huawei/android/hms/agent/common/ThreadUtil.java:
--------------------------------------------------------------------------------
1 | package com.huawei.android.hms.agent.common;
2 |
3 | import android.os.Handler;
4 | import android.os.Looper;
5 |
6 | import java.util.concurrent.ExecutorService;
7 | import java.util.concurrent.Executors;
8 |
9 | /**
10 | * 线程工具,用于执行线程等
11 | */
12 | public final class ThreadUtil {
13 | public static final ThreadUtil INST = new ThreadUtil();
14 |
15 | private ExecutorService executors;
16 |
17 | private ThreadUtil(){
18 | }
19 |
20 | /**
21 | * 在线程中执行
22 | * @param runnable 要执行的runnable
23 | */
24 | public void excute(Runnable runnable) {
25 | ExecutorService executorService = getExecutorService();
26 | if (executorService != null) {
27 | // 优先使用线程池,提高效率
28 | executorService.execute(runnable);
29 | } else {
30 | // 线程池获取失败,则直接使用线程
31 | new Thread(runnable).start();
32 | }
33 | }
34 |
35 | /**
36 | * 在主线程中执行
37 | * @param runnable 要执行的runnable
38 | */
39 | public void excuteInMainThread(Runnable runnable){
40 | new Handler(Looper.getMainLooper()).post(runnable);
41 | }
42 |
43 | /**
44 | * 获取缓存线程池
45 | * @return 缓存线程池服务
46 | */
47 | private ExecutorService getExecutorService(){
48 | if (executors == null) {
49 | try {
50 | executors = Executors.newCachedThreadPool();
51 | } catch (Exception e) {
52 | HMSAgentLog.e("create thread service error:" + e.getMessage());
53 | }
54 | }
55 |
56 | return executors;
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/push/src/main/java/com/huawei/android/hms/agent/common/handler/ConnectHandler.java:
--------------------------------------------------------------------------------
1 | package com.huawei.android.hms.agent.common.handler;
2 |
3 | /**
4 | * HuaweiApiClient 连接结果回调
5 | */
6 | public interface ConnectHandler {
7 | /**
8 | * HuaweiApiClient 连接结果回调
9 | * @param rst 结果码
10 | */
11 | void onConnect(int rst);
12 | }
13 |
--------------------------------------------------------------------------------
/push/src/main/java/com/huawei/android/hms/agent/push/DeleteTokenApi.java:
--------------------------------------------------------------------------------
1 | package com.huawei.android.hms.agent.push;
2 |
3 | import android.os.Handler;
4 | import android.os.Looper;
5 | import android.text.TextUtils;
6 |
7 | import com.huawei.android.hms.agent.HMSAgent;
8 | import com.huawei.android.hms.agent.common.ApiClientMgr;
9 | import com.huawei.android.hms.agent.common.BaseApiAgent;
10 | import com.huawei.android.hms.agent.common.CallbackCodeRunnable;
11 | import com.huawei.android.hms.agent.common.HMSAgentLog;
12 | import com.huawei.android.hms.agent.common.StrUtils;
13 | import com.huawei.android.hms.agent.common.ThreadUtil;
14 | import com.huawei.android.hms.agent.push.handler.DeleteTokenHandler;
15 | import com.huawei.hms.api.HuaweiApiClient;
16 | import com.huawei.hms.support.api.push.HuaweiPush;
17 |
18 | /**
19 | * 删除pushtoken的接口。
20 | */
21 | public class DeleteTokenApi extends BaseApiAgent {
22 |
23 | /**
24 | * 待删除的push token
25 | */
26 | private String token;
27 |
28 | /**
29 | * 调用接口回调
30 | */
31 | private DeleteTokenHandler handler;
32 |
33 | /**
34 | * HuaweiApiClient 连接结果回调
35 | *
36 | * @param rst 结果码
37 | * @param client HuaweiApiClient 实例
38 | */
39 | @Override
40 | public void onConnect(final int rst, final HuaweiApiClient client) {
41 | //需要在子线程中执行删除TOKEN操作
42 | ThreadUtil.INST.excute(new Runnable() {
43 | @Override
44 | public void run() {
45 | //调用删除TOKEN需要传入通过getToken接口获取到TOKEN,并且需要对TOKEN进行非空判断
46 | if (!TextUtils.isEmpty(token)){
47 | if (client == null || !ApiClientMgr.INST.isConnect(client)) {
48 | HMSAgentLog.e("client not connted");
49 | onDeleteTokenResult(rst);
50 | } else {
51 | try {
52 | HuaweiPush.HuaweiPushApi.deleteToken(client, token);
53 | onDeleteTokenResult(HMSAgent.AgentResultCode.HMSAGENT_SUCCESS);
54 | } catch (Exception e) {
55 | HMSAgentLog.e("删除TOKEN失败:" + e.getMessage());
56 | onDeleteTokenResult(HMSAgent.AgentResultCode.CALL_EXCEPTION);
57 | }
58 | }
59 | } else {
60 | HMSAgentLog.e("删除TOKEN失败: 要删除的token为空");
61 | onDeleteTokenResult(HMSAgent.AgentResultCode.EMPTY_PARAM);
62 | }
63 | }
64 | });
65 | }
66 |
67 | void onDeleteTokenResult(int rstCode) {
68 | HMSAgentLog.i("deleteToken:callback=" + StrUtils.objDesc(handler) +" retCode=" + rstCode);
69 | if (handler != null) {
70 | new Handler(Looper.getMainLooper()).post(new CallbackCodeRunnable(handler, rstCode));
71 | handler = null;
72 | }
73 | }
74 |
75 | /**
76 | * 删除指定的pushtoken
77 | * 该接口只在EMUI5.1以及更高版本的华为手机上调用该接口后才不会收到PUSH消息。
78 | * @param token 要删除的token
79 | */
80 | public void deleteToken(String token, DeleteTokenHandler handler) {
81 | HMSAgentLog.i("deleteToken:token:" + StrUtils.objDesc(token) + " handler=" + StrUtils.objDesc(handler));
82 | this.token = token;
83 | this.handler = handler;
84 | connect();
85 | }
86 | }
--------------------------------------------------------------------------------
/push/src/main/java/com/huawei/android/hms/agent/push/EnableReceiveNormalMsgApi.java:
--------------------------------------------------------------------------------
1 | package com.huawei.android.hms.agent.push;
2 |
3 | import android.os.Handler;
4 | import android.os.Looper;
5 |
6 | import com.huawei.android.hms.agent.HMSAgent;
7 | import com.huawei.android.hms.agent.common.ApiClientMgr;
8 | import com.huawei.android.hms.agent.common.BaseApiAgent;
9 | import com.huawei.android.hms.agent.common.CallbackCodeRunnable;
10 | import com.huawei.android.hms.agent.common.HMSAgentLog;
11 | import com.huawei.android.hms.agent.common.StrUtils;
12 | import com.huawei.android.hms.agent.common.ThreadUtil;
13 | import com.huawei.android.hms.agent.push.handler.EnableReceiveNormalMsgHandler;
14 | import com.huawei.hms.api.HuaweiApiClient;
15 | import com.huawei.hms.support.api.push.HuaweiPush;
16 |
17 | /**
18 | * 打开透传消息开关的接口。
19 | */
20 | public class EnableReceiveNormalMsgApi extends BaseApiAgent {
21 |
22 | /**
23 | * 是否打开开关
24 | */
25 | boolean enable;
26 |
27 | /**
28 | * 调用接口回调
29 | */
30 | private EnableReceiveNormalMsgHandler handler;
31 |
32 | /**
33 | * HuaweiApiClient 连接结果回调
34 | *
35 | * @param rst 结果码
36 | * @param client HuaweiApiClient 实例
37 | */
38 | @Override
39 | public void onConnect(final int rst, final HuaweiApiClient client) {
40 | //需要在子线程中执行开关的操作
41 | ThreadUtil.INST.excute(new Runnable() {
42 | @Override
43 | public void run() {
44 | if (client == null || !ApiClientMgr.INST.isConnect(client)) {
45 | HMSAgentLog.e("client not connted");
46 | onEnableReceiveNormalMsgResult(rst);
47 | } else {
48 | // 开启/关闭透传消息
49 | HuaweiPush.HuaweiPushApi.enableReceiveNormalMsg(client, enable);
50 | onEnableReceiveNormalMsgResult(HMSAgent.AgentResultCode.HMSAGENT_SUCCESS);
51 | }
52 | }
53 | });
54 | }
55 |
56 | void onEnableReceiveNormalMsgResult(int rstCode) {
57 | HMSAgentLog.i("enableReceiveNormalMsg:callback=" + StrUtils.objDesc(handler) +" retCode=" + rstCode);
58 | if (handler != null) {
59 | new Handler(Looper.getMainLooper()).post(new CallbackCodeRunnable(handler, rstCode));
60 | handler = null;
61 | }
62 | }
63 |
64 | /**
65 | * 打开/关闭透传消息
66 | * @param enable 打开/关闭
67 | */
68 | public void enableReceiveNormalMsg(boolean enable, EnableReceiveNormalMsgHandler handler) {
69 | HMSAgentLog.i("enableReceiveNormalMsg:enable=" + enable + " handler=" + StrUtils.objDesc(handler));
70 | this.enable = enable;
71 | this.handler = handler;
72 | connect();
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/push/src/main/java/com/huawei/android/hms/agent/push/EnableReceiveNotifyMsgApi.java:
--------------------------------------------------------------------------------
1 | package com.huawei.android.hms.agent.push;
2 |
3 | import android.os.Handler;
4 | import android.os.Looper;
5 |
6 | import com.huawei.android.hms.agent.HMSAgent;
7 | import com.huawei.android.hms.agent.common.ApiClientMgr;
8 | import com.huawei.android.hms.agent.common.BaseApiAgent;
9 | import com.huawei.android.hms.agent.common.CallbackCodeRunnable;
10 | import com.huawei.android.hms.agent.common.HMSAgentLog;
11 | import com.huawei.android.hms.agent.common.StrUtils;
12 | import com.huawei.android.hms.agent.common.ThreadUtil;
13 | import com.huawei.android.hms.agent.push.handler.EnableReceiveNotifyMsgHandler;
14 | import com.huawei.hms.api.HuaweiApiClient;
15 | import com.huawei.hms.support.api.push.HuaweiPush;
16 |
17 | /**
18 | * 打开自呈现消息开关的接口。
19 | */
20 | public class EnableReceiveNotifyMsgApi extends BaseApiAgent {
21 |
22 | /**
23 | * 是否打开开关
24 | */
25 | boolean enable;
26 |
27 | /**
28 | * 调用接口回调
29 | */
30 | private EnableReceiveNotifyMsgHandler handler;
31 |
32 | /**
33 | * HuaweiApiClient 连接结果回调
34 | *
35 | * @param rst 结果码
36 | * @param client HuaweiApiClient 实例
37 | */
38 | @Override
39 | public void onConnect(final int rst, final HuaweiApiClient client) {
40 | //需要在子线程中执行开关的操作
41 | ThreadUtil.INST.excute(new Runnable() {
42 | @Override
43 | public void run() {
44 | if (client == null || !ApiClientMgr.INST.isConnect(client)) {
45 | HMSAgentLog.e("client not connted");
46 | onEnableReceiveNotifyMsgResult(rst);
47 | } else {
48 | // 开启/关闭自呈现消息
49 | HuaweiPush.HuaweiPushApi.enableReceiveNotifyMsg(client, enable);
50 | onEnableReceiveNotifyMsgResult(HMSAgent.AgentResultCode.HMSAGENT_SUCCESS);
51 | }
52 | }
53 | });
54 | }
55 |
56 | void onEnableReceiveNotifyMsgResult(int rstCode) {
57 | HMSAgentLog.i("enableReceiveNotifyMsg:callback=" + StrUtils.objDesc(handler) +" retCode=" + rstCode);
58 | if (handler != null) {
59 | new Handler(Looper.getMainLooper()).post(new CallbackCodeRunnable(handler, rstCode));
60 | handler = null;
61 | }
62 | }
63 |
64 | /**
65 | * 打开/关闭自呈现消息
66 | * @param enable 打开/关闭
67 | */
68 | public void enableReceiveNotifyMsg(boolean enable, EnableReceiveNotifyMsgHandler handler) {
69 | HMSAgentLog.i("enableReceiveNotifyMsg:enable=" + enable + " handler=" + StrUtils.objDesc(handler));
70 | this.enable = enable;
71 | this.handler = handler;
72 | connect();
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/push/src/main/java/com/huawei/android/hms/agent/push/GetPushStateApi.java:
--------------------------------------------------------------------------------
1 | package com.huawei.android.hms.agent.push;
2 |
3 | import android.os.Handler;
4 | import android.os.Looper;
5 |
6 | import com.huawei.android.hms.agent.HMSAgent;
7 | import com.huawei.android.hms.agent.common.ApiClientMgr;
8 | import com.huawei.android.hms.agent.common.BaseApiAgent;
9 | import com.huawei.android.hms.agent.common.CallbackCodeRunnable;
10 | import com.huawei.android.hms.agent.common.HMSAgentLog;
11 | import com.huawei.android.hms.agent.common.StrUtils;
12 | import com.huawei.android.hms.agent.common.ThreadUtil;
13 | import com.huawei.android.hms.agent.push.handler.GetPushStateHandler;
14 | import com.huawei.hms.api.HuaweiApiClient;
15 | import com.huawei.hms.support.api.push.HuaweiPush;
16 |
17 | /**
18 | * 获取push状态的接口。
19 | */
20 | public class GetPushStateApi extends BaseApiAgent {
21 |
22 | /**
23 | * 调用接口回调
24 | */
25 | private GetPushStateHandler handler;
26 |
27 | /**
28 | * HuaweiApiClient 连接结果回调
29 | *
30 | * @param rst 结果码
31 | * @param client HuaweiApiClient 实例
32 | */
33 | @Override
34 | public void onConnect(final int rst, final HuaweiApiClient client) {
35 | //需要在子线程中执行获取push状态的操作
36 | ThreadUtil.INST.excute(new Runnable() {
37 | @Override
38 | public void run() {
39 | if (client == null || !ApiClientMgr.INST.isConnect(client)) {
40 | HMSAgentLog.e("client not connted");
41 | onGetPushStateResult(rst);
42 | } else {
43 | HuaweiPush.HuaweiPushApi.getPushState(client);
44 | onGetPushStateResult(HMSAgent.AgentResultCode.HMSAGENT_SUCCESS);
45 | }
46 | }
47 | });
48 | }
49 |
50 | void onGetPushStateResult(int rstCode) {
51 | HMSAgentLog.i("getPushState:callback=" + StrUtils.objDesc(handler) +" retCode=" + rstCode);
52 | if (handler != null) {
53 | new Handler(Looper.getMainLooper()).post(new CallbackCodeRunnable(handler, rstCode));
54 | handler = null;
55 | }
56 | }
57 |
58 | /**
59 | * 获取push状态,push状态的回调通过广播发送。
60 | * 要监听的广播,请参见HMS-SDK开发准备中PushReceiver的注册
61 | */
62 | public void getPushState(GetPushStateHandler handler) {
63 | HMSAgentLog.i("getPushState:handler=" + StrUtils.objDesc(handler));
64 | this.handler = handler;
65 | connect();
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/push/src/main/java/com/huawei/android/hms/agent/push/GetTokenApi.java:
--------------------------------------------------------------------------------
1 | package com.huawei.android.hms.agent.push;
2 |
3 | import android.os.Handler;
4 | import android.os.Looper;
5 |
6 | import com.huawei.android.hms.agent.HMSAgent;
7 | import com.huawei.android.hms.agent.common.ApiClientMgr;
8 | import com.huawei.android.hms.agent.common.BaseApiAgent;
9 | import com.huawei.android.hms.agent.common.CallbackCodeRunnable;
10 | import com.huawei.android.hms.agent.common.HMSAgentLog;
11 | import com.huawei.android.hms.agent.common.StrUtils;
12 | import com.huawei.android.hms.agent.push.handler.GetTokenHandler;
13 | import com.huawei.hms.api.HuaweiApiClient;
14 | import com.huawei.hms.support.api.client.PendingResult;
15 | import com.huawei.hms.support.api.client.ResultCallback;
16 | import com.huawei.hms.support.api.client.Status;
17 | import com.huawei.hms.support.api.entity.core.CommonCode;
18 | import com.huawei.hms.support.api.push.HuaweiPush;
19 | import com.huawei.hms.support.api.push.TokenResult;
20 |
21 | /**
22 | * 获取token的push接口,token的结果通过广播进行接收。
23 | */
24 | public class GetTokenApi extends BaseApiAgent {
25 |
26 | /**
27 | * client 无效最大尝试次数
28 | */
29 | private static final int MAX_RETRY_TIMES = 1;
30 |
31 | /**
32 | * 结果回调
33 | */
34 | private GetTokenHandler handler;
35 |
36 | /**
37 | * 当前剩余重试次数
38 | */
39 | private int retryTimes = MAX_RETRY_TIMES;
40 |
41 | /**
42 | * HuaweiApiClient 连接结果回调
43 | *
44 | * @param rst 结果码
45 | * @param client HuaweiApiClient 实例
46 | */
47 | @Override
48 | public void onConnect(int rst, HuaweiApiClient client) {
49 | if (client == null || !ApiClientMgr.INST.isConnect(client)) {
50 | HMSAgentLog.e("client not connted");
51 | onPushTokenResult(rst, null);
52 | return;
53 | }
54 |
55 | PendingResult tokenResult = HuaweiPush.HuaweiPushApi.getToken(client);
56 | tokenResult.setResultCallback(new ResultCallback() {
57 | @Override
58 | public void onResult(TokenResult result) {
59 | if (result == null) {
60 | HMSAgentLog.e("result is null");
61 | onPushTokenResult(HMSAgent.AgentResultCode.RESULT_IS_NULL, null);
62 | return;
63 | }
64 |
65 | Status status = result.getStatus();
66 | if (status == null) {
67 | HMSAgentLog.e("status is null");
68 | onPushTokenResult(HMSAgent.AgentResultCode.STATUS_IS_NULL, null);
69 | return;
70 | }
71 |
72 | int rstCode = status.getStatusCode();
73 | HMSAgentLog.d("rstCode=" + rstCode);
74 | // 需要重试的错误码,并且可以重试
75 | if ((rstCode == CommonCode.ErrorCode.SESSION_INVALID
76 | || rstCode == CommonCode.ErrorCode.CLIENT_API_INVALID) && retryTimes > 0) {
77 | retryTimes--;
78 | connect();
79 | } else {
80 | onPushTokenResult(rstCode, result);
81 | }
82 | }
83 | });
84 | }
85 |
86 | /**
87 | * 获取pushtoken接口调用回调
88 | * pushtoken通过广播下发,要监听的广播,请参见HMS-SDK开发准备中PushReceiver的注册
89 | * @param rstCode 结果码
90 | * @param result 调用获取pushtoken接口的结果
91 | */
92 | void onPushTokenResult(int rstCode, TokenResult result) {
93 | HMSAgentLog.i("getToken:callback=" + StrUtils.objDesc(handler) +" retCode=" + rstCode);
94 | if (handler != null) {
95 | new Handler(Looper.getMainLooper()).post(new CallbackCodeRunnable(handler, rstCode));
96 | handler = null;
97 | }
98 | retryTimes = MAX_RETRY_TIMES;
99 | }
100 |
101 | /**
102 | * 获取pushtoken接口
103 | * pushtoken通过广播下发,要监听的广播,请参见HMS-SDK开发准备中PushReceiver的注册
104 | * @param handler pushtoken接口调用回调
105 | */
106 | public void getToken(GetTokenHandler handler) {
107 | HMSAgentLog.i("getToken:handler=" + StrUtils.objDesc(handler));
108 | this.handler = handler;
109 | retryTimes = MAX_RETRY_TIMES;
110 | connect();
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/push/src/main/java/com/huawei/android/hms/agent/push/QueryAgreementApi.java:
--------------------------------------------------------------------------------
1 | package com.huawei.android.hms.agent.push;
2 |
3 | import android.os.Handler;
4 | import android.os.Looper;
5 |
6 | import com.huawei.android.hms.agent.HMSAgent;
7 | import com.huawei.android.hms.agent.common.ApiClientMgr;
8 | import com.huawei.android.hms.agent.common.BaseApiAgent;
9 | import com.huawei.android.hms.agent.common.CallbackCodeRunnable;
10 | import com.huawei.android.hms.agent.common.HMSAgentLog;
11 | import com.huawei.android.hms.agent.common.StrUtils;
12 | import com.huawei.android.hms.agent.common.ThreadUtil;
13 | import com.huawei.android.hms.agent.push.handler.QueryAgreementHandler;
14 | import com.huawei.hms.api.HuaweiApiClient;
15 | import com.huawei.hms.support.api.push.HuaweiPush;
16 |
17 | /**
18 | * 获取push协议展示的接口。
19 | */
20 | public class QueryAgreementApi extends BaseApiAgent {
21 |
22 | /**
23 | * 调用接口回调
24 | */
25 | private QueryAgreementHandler handler;
26 |
27 | /**
28 | * HuaweiApiClient 连接结果回调
29 | *
30 | * @param rst 结果码
31 | * @param client HuaweiApiClient 实例
32 | */
33 | @Override
34 | public void onConnect(final int rst, final HuaweiApiClient client) {
35 | //需要在子线程中执行获取push协议展示的操作
36 | ThreadUtil.INST.excute(new Runnable() {
37 | @Override
38 | public void run() {
39 | if (client == null || !ApiClientMgr.INST.isConnect(client)) {
40 | HMSAgentLog.e("client not connted");
41 | onQueryAgreementResult(rst);
42 | } else {
43 | HuaweiPush.HuaweiPushApi.queryAgreement(client);
44 | onQueryAgreementResult(HMSAgent.AgentResultCode.HMSAGENT_SUCCESS);
45 | }
46 | }
47 | });
48 | }
49 |
50 | void onQueryAgreementResult(int rstCode) {
51 | HMSAgentLog.i("queryAgreement:callback=" + StrUtils.objDesc(handler) +" retCode=" + rstCode);
52 | if (handler != null) {
53 | new Handler(Looper.getMainLooper()).post(new CallbackCodeRunnable(handler, rstCode));
54 | handler = null;
55 | }
56 | }
57 |
58 | /**
59 | * 请求push协议展示
60 | */
61 | public void queryAgreement(QueryAgreementHandler handler) {
62 | HMSAgentLog.i("queryAgreement:handler=" + StrUtils.objDesc(handler));
63 | this.handler = handler;
64 | connect();
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/push/src/main/java/com/huawei/android/hms/agent/push/handler/DeleteTokenHandler.java:
--------------------------------------------------------------------------------
1 | package com.huawei.android.hms.agent.push.handler;
2 |
3 | import com.huawei.android.hms.agent.common.ICallbackCode;
4 |
5 | /**
6 | * deleteToken 回调
7 | */
8 | public interface DeleteTokenHandler extends ICallbackCode {
9 | }
10 |
--------------------------------------------------------------------------------
/push/src/main/java/com/huawei/android/hms/agent/push/handler/EnableReceiveNormalMsgHandler.java:
--------------------------------------------------------------------------------
1 | package com.huawei.android.hms.agent.push.handler;
2 |
3 | import com.huawei.android.hms.agent.common.ICallbackCode;
4 |
5 | /**
6 | * enableReceiveNormalMsg 回调
7 | */
8 | public interface EnableReceiveNormalMsgHandler extends ICallbackCode {
9 | }
10 |
--------------------------------------------------------------------------------
/push/src/main/java/com/huawei/android/hms/agent/push/handler/EnableReceiveNotifyMsgHandler.java:
--------------------------------------------------------------------------------
1 | package com.huawei.android.hms.agent.push.handler;
2 |
3 | import com.huawei.android.hms.agent.common.ICallbackCode;
4 |
5 | /**
6 | * enableReceiveNotifyMsg 回调
7 | */
8 | public interface EnableReceiveNotifyMsgHandler extends ICallbackCode {
9 | }
10 |
--------------------------------------------------------------------------------
/push/src/main/java/com/huawei/android/hms/agent/push/handler/GetPushStateHandler.java:
--------------------------------------------------------------------------------
1 | package com.huawei.android.hms.agent.push.handler;
2 |
3 | import com.huawei.android.hms.agent.common.ICallbackCode;
4 |
5 | /**
6 | * getPushState 回调
7 | */
8 | public interface GetPushStateHandler extends ICallbackCode {
9 | }
10 |
--------------------------------------------------------------------------------
/push/src/main/java/com/huawei/android/hms/agent/push/handler/GetTokenHandler.java:
--------------------------------------------------------------------------------
1 | package com.huawei.android.hms.agent.push.handler;
2 |
3 | import com.huawei.android.hms.agent.common.ICallbackCode;
4 |
5 | /**
6 | * 获取 pushtoken 回调
7 | */
8 | public interface GetTokenHandler extends ICallbackCode {
9 | }
10 |
--------------------------------------------------------------------------------
/push/src/main/java/com/huawei/android/hms/agent/push/handler/QueryAgreementHandler.java:
--------------------------------------------------------------------------------
1 | package com.huawei.android.hms.agent.push.handler;
2 |
3 | import com.huawei.android.hms.agent.common.ICallbackCode;
4 |
5 | /**
6 | * queryAgreement 回调
7 | */
8 | public interface QueryAgreementHandler extends ICallbackCode {
9 | }
10 |
--------------------------------------------------------------------------------
/push/src/main/res/values-zh-rCN/hms_values-zh-rCN.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/push/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/push/src/main/res/values/hms_values.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/push/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | push
3 |
4 |
--------------------------------------------------------------------------------
/push/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
--------------------------------------------------------------------------------
/pushdemo.jks:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Luomingbear/Push/49c3e097f97f403eec6ed903a4a81ca3044ec844/pushdemo.jks
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 |
2 | # Push
3 |
4 | 一个推送的模块,集成了华为、小米、魅族、OPPO和极光推送,根据设备厂商判断使用具体哪个SDK如:小米手机使用小米推送,华为手机使用华为推送,其他的设备使用极光推送。
5 |
6 | ## 更新时间
7 |
8 | 2019/07/4
9 |
10 | 添加统一接收消息的`BasePushBroadcastReceiver`和vivo推送平台
11 |
12 | ## 使用
13 |
14 | ### 1.配置AppKey
15 |
16 | 在您的app 的gradle配置文件里面添加如下代码:
17 |
18 | ```groovy
19 | defaultConfig {
20 | manifestPlaceholders = [
21 | "jPushAppkey" : "ea6c961e572ad972df4ef456",//极光推送的AppKey
22 | "huaweiPushAppId" : "100698925",//华为推送的AppId
23 | "xiaomiPushAppkey": "55617974 54571",//"57417800 14675",//小米推送的AppKey****请务必在数值中间添加一个空格,否则会发生数值变化****
24 | "xiaomiPushAppId" : "28823037 61517974571",//"28823037 61517800675",//小米推送的AppID****请务必在数值中间添加一个空格,否则会发生数值变化****
25 | "oppoAppKey" : "9d24177594c741be86465ec9fe490a44",//OPPO推送的appKey
26 | "oppoAppSecret" : "c60bec1f803e49e88037562ec2109286",//OPPO推送的appSecret
27 | "meizuAppId" : "1200 55",//魅族推送AppId ****请务必在数值中间添加一个空格,否则会发生数值变化****
28 | "meizuAppKey" : "3aca7449444347c4a1d2a70826ae1e9b",//魅族推送AppKey
29 | "vivoAppId" : "11937",//vivo推送AppId
30 | "vivoAppKey" : "acfdb480-e178-4098-80ae-76284df7d588",//vivo推送AppKey
31 | "marketChannel" : "develops"//渠道
32 | ]
33 | }
34 | ```
35 |
36 | 在push模块下面的`buid.gradle`文件里面替换对应的AppKey,**需要注意的地方**:
37 |
38 | > 小米的AppKey和魅族的AppId是使用的数字的格式,不能直接复制粘粘到文件里面,需要在中间增加一个空格,例如:AppKey为`201584151343514321321`需要替换为`20158415134 3514321321`
39 |
40 | ### 2.配置华为推送
41 |
42 | 华为推送的SDK是通过工具生成的,所以需要手动配置生成代码,先[下载华为HMS Agent套件](https://obs.cn-north-2.myhwclouds.com/hms-ds-wf/sdk/HMSAgent_2.6.1.302.zip),解压出来之后根据自己的电脑系统需要相应的脚本文件,例如:Window点击双击`GetHMSAgent_cn.bat`在弹出的窗口里面根据提示操作就好了,最后生存的代码会保存在`copysrc`文件夹里面。将生成的代码复制到Push的java目录下面,res资源文件根据需要添加到资源目录下。
43 |
44 | ### 3.初始化
45 |
46 | 在Application的onCreate里面调用`PushTargetManager`的`init`方法。
47 |
48 | ### 4.处理推送消息
49 |
50 | 推送的信息分为`Message`和`Notification`,Notification会主动在通知栏显示通知,而Message不会。
51 |
52 | 要处理接收到的信息,只需要实现`BasePushBroadcastReceiver`或者`PushTargetManager.getInstance().addPushReceiverListener(String, OnPushReceiverListener)`方法即可。
53 |
54 | #### 4.1自定义BasePushBroadcastReceiver
55 |
56 | ```java
57 | PushBroadcastReceiverIml extends BasePushBroadcastReceiver{
58 |
59 | public PushBroadcastReceiverIml() {
60 | }
61 |
62 | @Override
63 | public void onRegister(Context context, ReceiverInfo info) {
64 | Log.d(TAG, "推送注册成功\n" + info.toString());
65 | }
66 |
67 | @Override
68 | public void onAlias(Context context, ReceiverInfo info) {
69 | Log.d(TAG, "设置了别名\n" + info.toString());
70 | }
71 |
72 | @Override
73 | public void onMessage(Context context, ReceiverInfo info) {
74 | Log.d(TAG, "收到自定义消息\n" + info.toString());
75 | }
76 |
77 | @Override
78 | public void onNotification(Context context, ReceiverInfo info) {
79 | Log.d(TAG, "收到通知\n" + info.toString());
80 | }
81 |
82 | @Override
83 | public void onOpened(Context context, ReceiverInfo info) {
84 | Log.d(TAG, "点击了通知\n" + info.toString());
85 | }
86 | }
87 | ```
88 |
89 | 在`manifest`里面注册广播接收器
90 |
91 | ```xml
92 |
93 |
96 |
97 |
98 |
99 |
102 |
103 |
104 |
105 |
106 |
107 |
108 | ```
109 |
110 | #### 4.2addPushReceiverListener()
111 |
112 | ```java
113 | PushTargetManager.getInstance().addPushReceiverListener("ml",
114 | new PushTargetManager.OnPushReceiverListener() {
115 | @Override
116 | public void onRegister(ReceiverInfo info) {
117 | Log.d(TAG, "注册成功\n" + info.toString());
118 | }
119 |
120 | @Override
121 | public void onAlias(ReceiverInfo info) {
122 | Log.d(TAG, "设置了别名\n" + info.toString());
123 | }
124 |
125 | @Override
126 | public void onMessage(ReceiverInfo info) {
127 | Log.d(TAG, "收到了自定义消息\n" + info.toString());
128 | }
129 |
130 | @Override
131 | public void onNotification(ReceiverInfo info) {
132 | Log.d(TAG, "收到了通知\n" + info.toString());
133 | }
134 |
135 | @Override
136 | public void onOpened(ReceiverInfo info) {
137 | Log.d(TAG, "点击通知\n" + info.toString());
138 | }
139 | });
140 | ```
141 |
142 | **注意**:*使用这种方式有一个局限,就是只会在应用运行期间有回调,应用杀死之后就不会有反应了,所以推荐使用第一种方式。*
143 |
144 | ### 5.处理用户点击通知栏
145 |
146 | 针对用户点击通知栏的行为,我们可能需要对通知进行处理跳转到指定的页面。当有用户点击通知栏的时候`BasePushBroadcastReceiver`或者`OnPushReceiverListener`的`onOpened(Context context, ReceiverInfo info)`会执行,我们只需要在这里处理就可以了。**需要注意的是,华为和OPPO的事件处理使用的是一个虚拟的Activity进行中转。 **因为无法监听到用户点击的事件,但是可以在点击之后打开的页面里面获取到传递的数据,间接的进行处理。所以使用的时候需要和后端协商好推送类型为自定义参数的格式。
147 |
148 | > OPPO和华为的处理Activity分别为`OppoLoadActivity`、`HuaweiLoadActivity`具体的intent设置请按照自己的需求修改。
149 |
150 | 
151 |
152 | ### 6.设置别名
153 |
154 | 为了区别不同的设备与账号的对应关系,需要将设备别名设置到推送服务器和自己应用的服务器。* 当然,如果你不需要知道具体用户对于的设备,也可以不处理 *。 **别名的设置需要执行`PushTargetManager`的`setAlias`, **建议在注册成功之后再执行设置别名的操作,即在`HandleReceiverRegistration`的`handle`里面执行。 **需要注意的是华为推送不支持设置别名,只能获取华为服务器返回的`token` **。对于将别名上传到服务器的操作,用户只需要在`HandleReceiverAlias`类实现`handle`方法就可以了。
155 |
156 | 
157 |
158 | ### 7.获取注册id
159 |
160 | 在`BasePushBroadcastReceiver`或者`OnPushReceiverListener`的`onRegister(Context context, ReceiverInfo info)`会在推送sdk注册成功之后回调,所以,可以在这里获取注册id,此时的`ReceiverInfo`数据结构如下:
161 |
162 | | pushTarget | PushTargetEnum的枚举,表示了当前的推送平台 |
163 | | ---------- | ------------------------------------------ |
164 | | title | 提示文本,例如“小米推送注册成功” |
165 | | content | 注册id |
166 | | rawData | 推送平台注册成功之后的原始返回值 |
167 |
168 | ## 模块设计思路
169 |
170 | 通过对推送服务的分析,我将推送分为了三个步骤,分别是:初始化、接收和处理,不同的推送平台的接收方式并不一样,但是推送服务只是一个工具,接收推送之后的处理才是关键,而这个是不需要根据不同的平台来变化的,所以我使用了一个统一的处理入口。
171 |
172 | 
173 |
174 | 根据这个思路,我设计的代码结构如下:
175 |
176 | 
177 |
178 | | 目录 | 说明 |
179 | | ------ | ---------------------------------- |
180 | | Handle | 统一处理接收到的推送信息 |
181 | | Target | 将不同的推送平台的初始化和接收存放在这个目录里面,按照推送平台分类。 |
182 |
183 | 关于消息的处理,通常会有:SDK注册成功、接收到消息、用户点击通知栏等,所以我将不同的动作分配到具体的类里面,减少一个大类处理多个方法的问题,通过一个入口类管理具体的行为。
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app', ':push'
2 |
--------------------------------------------------------------------------------