Skip to content

Commit 276ac75

Browse files
authored
Implement Huawei push messages (#476)
1 parent dcbb524 commit 276ac75

File tree

17 files changed

+367
-4
lines changed

17 files changed

+367
-4
lines changed

AndroidSDKCore/src/main/java/com/leanplum/Leanplum.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -674,6 +674,8 @@ private static void startHelper(
674674
Constants.Defaults.LEANPLUM_PUSH, Constants.Defaults.PROPERTY_FCM_TOKEN_ID);
675675
String miPushRegistrationId = SharedPreferencesUtil.getString(context,
676676
Constants.Defaults.LEANPLUM_PUSH, Constants.Defaults.PROPERTY_MIPUSH_TOKEN_ID);
677+
String hmsRegistrationId = SharedPreferencesUtil.getString(context,
678+
Constants.Defaults.LEANPLUM_PUSH, Constants.Defaults.PROPERTY_HMS_TOKEN_ID);
677679

678680
HashMap<String, Object> params = new HashMap<>();
679681
params.put(Constants.Params.INCLUDE_DEFAULTS, Boolean.toString(false));
@@ -691,6 +693,9 @@ private static void startHelper(
691693
if (!TextUtils.isEmpty(miPushRegistrationId)) {
692694
params.put(Constants.Params.DEVICE_MIPUSH_TOKEN, miPushRegistrationId);
693695
}
696+
if (!TextUtils.isEmpty(hmsRegistrationId)) {
697+
params.put(Constants.Params.DEVICE_HMS_TOKEN, hmsRegistrationId);
698+
}
694699
params.put(Constants.Keys.TIMEZONE, localTimeZone.getID());
695700
params.put(Constants.Keys.TIMEZONE_OFFSET_SECONDS, Integer.toString(timezoneOffsetSeconds));
696701
params.put(Constants.Keys.LOCALE, Util.getLocale());
@@ -1552,6 +1557,9 @@ static void setRegistrationId(PushProviderType type, final String registrationId
15521557
case MIPUSH:
15531558
attributeName = Constants.Params.DEVICE_MIPUSH_TOKEN;
15541559
break;
1560+
case HMS:
1561+
attributeName = Constants.Params.DEVICE_HMS_TOKEN;
1562+
break;
15551563
default:
15561564
return;
15571565
}

AndroidSDKCore/src/main/java/com/leanplum/PushProviderType.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,6 @@
2323

2424
enum PushProviderType {
2525
FCM,
26-
MIPUSH
26+
MIPUSH,
27+
HMS
2728
}

AndroidSDKCore/src/main/java/com/leanplum/internal/Constants.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ public static class Defaults {
8989
public static final String APP_ID = "__app_id";
9090
public static final String PROPERTY_FCM_TOKEN_ID = "registration_id";
9191
public static final String PROPERTY_MIPUSH_TOKEN_ID = "mipush_registration_id";
92+
public static final String PROPERTY_HMS_TOKEN_ID = "hms_registration_id";
9293
public static final String PROPERTY_SENDER_IDS = "sender_ids";
9394
public static final String NOTIFICATION_CHANNELS_KEY = "__leanplum_notification_channels";
9495
public static final String DEFAULT_NOTIFICATION_CHANNEL_KEY = "__leanplum_default_notification_channels";
@@ -111,6 +112,7 @@ public static class Params {
111112
public static final String DEVICE_NAME = "deviceName";
112113
public static final String DEVICE_FCM_PUSH_TOKEN = "gcmRegistrationId";
113114
public static final String DEVICE_MIPUSH_TOKEN = "miPushRegId";
115+
public static final String DEVICE_HMS_TOKEN = "huaweiPushRegId";
114116
public static final String DEVICE_SYSTEM_NAME = "systemName";
115117
public static final String DEVICE_SYSTEM_VERSION = "systemVersion";
116118
public static final String EMAIL = "email";

AndroidSDKCore/src/main/java/com/leanplum/internal/Util.java

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2013, Leanplum, Inc. All rights reserved.
2+
* Copyright 2021, Leanplum, Inc. All rights reserved.
33
*
44
* Licensed to the Apache Software Foundation (ASF) under one
55
* or more contributor license agreements. See the NOTICE file
@@ -34,6 +34,7 @@
3434
import android.net.wifi.WifiInfo;
3535
import android.net.wifi.WifiManager;
3636
import android.os.Build;
37+
import android.os.Looper;
3738
import android.provider.Settings.Secure;
3839
import android.text.TextUtils;
3940
import android.util.TypedValue;
@@ -665,4 +666,30 @@ public static int generateIdFromResourceName(String resourceName) {
665666
public static boolean isXiaomiDevice() {
666667
return Build.MANUFACTURER != null && Build.MANUFACTURER.toLowerCase().contains("xiaomi");
667668
}
669+
670+
/**
671+
* Checks for Huawei Mobile Services.
672+
*
673+
* @return True if Huawei Mobile Services exist.
674+
*/
675+
public static boolean isHuaweiServicesAvailable(Context context) {
676+
try {
677+
Class<?> clazz = Class.forName("com.huawei.hms.api.HuaweiApiAvailability");
678+
Object instance = clazz.getMethod("getInstance").invoke(null);
679+
Method isAvailable = clazz.getMethod("isHuaweiMobileServicesAvailable", Context.class);
680+
int statusCode = (int) isAvailable.invoke(instance, context);
681+
return statusCode == 0;
682+
} catch (Throwable ignore) {
683+
}
684+
return false;
685+
}
686+
687+
/**
688+
* Checks if current thread is the main (UI) thread.
689+
*
690+
* @return True if the current thread is the main thread.
691+
*/
692+
public static boolean isMainThread() {
693+
return Thread.currentThread() == Looper.getMainLooper().getThread();
694+
}
668695
}

AndroidSDKHms/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/build

AndroidSDKHms/build.gradle

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
plugins {
2+
id 'com.android.library'
3+
id 'kotlin-android'
4+
id 'com.jfrog.artifactory' version '4.13.0'
5+
id 'maven-publish'
6+
id 'signing'
7+
}
8+
apply from: "../common-methods.gradle"
9+
10+
android {
11+
compileSdkVersion COMPILE_SDK_VERSION
12+
defaultConfig {
13+
minSdkVersion 18 // version 18 is needed by agconnect plugin
14+
defaultConfig {
15+
consumerProguardFiles 'consumer-proguard-rules.pro'
16+
}
17+
}
18+
19+
buildTypes {
20+
release {
21+
minifyEnabled true
22+
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
23+
}
24+
}
25+
26+
compileOptions {
27+
sourceCompatibility JAVA_VERSION
28+
targetCompatibility JAVA_VERSION
29+
}
30+
}
31+
32+
dependencies {
33+
api project(':AndroidSDKCore')
34+
api project(':AndroidSDKPush')
35+
36+
implementation 'com.huawei.agconnect:agconnect-core:1.6.0.300'
37+
implementation 'com.huawei.hms:push:6.1.0.300'
38+
}
39+
40+
task generateJavadoc(type: Javadoc) {
41+
source = android.sourceSets.main.java.srcDirs
42+
classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
43+
destinationDir = file("./javadoc/")
44+
failOnError false
45+
}
46+
47+
publishing_task(LEANPLUM_HMS_ARTIFACT_ID)
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Keep default Leanplum classes.
2+
-keepclassmembers class * {
3+
@com.leanplum.annotations.* <fields>;
4+
}
5+
6+
-keep class com.leanplum.** { *; }
7+
-dontwarn com.leanplum.**

AndroidSDKHms/proguard-rules.pro

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
-keep class com.huawei.updatesdk.**{*;}
2+
-keep class com.huawei.hms.**{*;}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<manifest package="com.leanplum.hms"
2+
xmlns:android="http://schemas.android.com/apk/res/android">
3+
4+
<application>
5+
<service
6+
android:name="com.leanplum.LeanplumHmsMessageService"
7+
android:exported="false">
8+
<intent-filter>
9+
<action android:name="com.huawei.push.action.MESSAGING_EVENT" />
10+
</intent-filter>
11+
</service>
12+
</application>
13+
14+
</manifest>
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/*
2+
* Copyright 2021, Leanplum, Inc. All rights reserved.
3+
*
4+
* Licensed to the Apache Software Foundation (ASF) under one
5+
* or more contributor license agreements. See the NOTICE file
6+
* distributed with this work for additional information
7+
* regarding copyright ownership. The ASF licenses this file
8+
* to you under the Apache License, Version 2.0 (the
9+
* "License"); you may not use this file except in compliance
10+
* with the License. You may obtain a copy of the License at
11+
*
12+
* http://www.apache.org/licenses/LICENSE-2.0
13+
*
14+
* Unless required by applicable law or agreed to in writing,
15+
* software distributed under the License is distributed on an
16+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17+
* KIND, either express or implied. See the License for the
18+
* specific language governing permissions and limitations
19+
* under the License.
20+
*/
21+
22+
package com.leanplum;
23+
24+
import android.content.Context;
25+
import android.os.Bundle;
26+
import com.huawei.hms.push.HmsMessageService;
27+
import com.huawei.hms.push.RemoteMessage;
28+
import com.leanplum.internal.Constants;
29+
import com.leanplum.internal.Constants.Keys;
30+
import com.leanplum.internal.Log;
31+
import com.leanplum.internal.OperationQueue;
32+
import com.leanplum.internal.Util;
33+
import java.util.Map;
34+
35+
/**
36+
* This class encapsulates functionality for handling notification messages and registration ID from
37+
* Huawei Push Kit. Needs to be called from your instance of {@link HmsMessageService}.
38+
*/
39+
public class LeanplumHmsHandler {
40+
41+
public void onCreate(Context context) {
42+
Leanplum.setApplicationContext(context);
43+
}
44+
45+
public void onNewToken(String token, Context context) {
46+
if (Util.isMainThread()) {
47+
OperationQueue.sharedInstance().addParallelOperation(() -> onNewTokenImpl(token, context));
48+
} else {
49+
onNewTokenImpl(token, context);
50+
}
51+
}
52+
53+
private void onNewTokenImpl(String token, Context context) {
54+
// Send token to backend
55+
LeanplumPushService.getPushProviders().setRegistrationId(PushProviderType.HMS, token);
56+
}
57+
58+
public void onMessageReceived(RemoteMessage remoteMessage, Context context) {
59+
if (Util.isMainThread()) {
60+
OperationQueue.sharedInstance().addParallelOperation(
61+
() -> onMessageReceivedImpl(remoteMessage, context));
62+
} else {
63+
onMessageReceivedImpl(remoteMessage, context);
64+
}
65+
}
66+
67+
private void onMessageReceivedImpl(RemoteMessage remoteMessage, Context context) {
68+
try {
69+
Map<String, String> messageMap = remoteMessage.getDataOfMap();
70+
String channel = PushTracking.CHANNEL_HMS;
71+
if (messageMap.containsKey(Constants.Keys.PUSH_MESSAGE_TEXT)) {
72+
Bundle notification = getBundle(messageMap);
73+
notification.putString(Keys.CHANNEL_INTERNAL_KEY, channel);
74+
LeanplumPushService.handleNotification(context, notification);
75+
}
76+
Log.i("Received HMS notification message: %s", messageMap.toString());
77+
} catch (Throwable t) {
78+
Log.exception(t);
79+
}
80+
}
81+
82+
private Bundle getBundle(Map<String, String> messageMap) {
83+
Bundle bundle = new Bundle();
84+
if (messageMap != null) {
85+
for (Map.Entry<String, String> entry : messageMap.entrySet()) {
86+
bundle.putString(entry.getKey(), entry.getValue());
87+
}
88+
}
89+
return bundle;
90+
}
91+
}

0 commit comments

Comments
 (0)