Android SDK integration

更新时间:
复制 MD 格式

Introduction

This topic describes how to integrate the Mobile Push Android SDK.

  • We recommend using an Android Studio project that manages dependencies with Gradle.

  • The SDK supports Android 5.0 and later.

  • This document applies only to Mobile Push Android SDK V3.0.0 and later.

Important

The Mobile Push SDK includes two types of push channels: the EMAS persistent connection channel and third-party channels. This topic describes how to integrate the persistent connection channel.

Integrating third-party channels improves the delivery rate of pushes when your app is offline. For more information, see Step 3: Integrate third-party channels.

For the Mobile Push Android SDK demo project, see Mobile Push Android Demo.

The demo project is developed using Kotlin and MVVM. It features an improved interface and richer functionality. You can use the demo to quickly learn how to use the Mobile Push Android SDK.

Preparations

Step 1: Add the SDK to your application

You can add the SDK to your application using one of two methods: Maven dependency or local dependency.

Note

We recommend using the Maven dependency method. It is simple to configure, less prone to errors, and easy to update.

1. Use the Maven dependency method

1.1 Configure the Maven repository

The following sections describe how to configure the repository using the dependencyResolutionManagement method recommended for Gradle 7.0 and later, and the allprojects method recommended for versions earlier than Gradle 7.0.

1.1.1 dependencyResolutionManagement method

In your root-level (project-level) Gradle file (<project>/settings.gradle), add the Maven repository URL to the repositories block within dependencyResolutionManagement.

dependencyResolutionManagement {
  repositories {
    maven {
      url 'https://maven.aliyun.com/nexus/content/repositories/releases/'
    }

    // Configure the Maven repository URL for the HMS Core SDK. This is required for integrating the Huawei channel.
    maven {
      url 'https://developer.huawei.com/repo/'
    }
  }
}
1.1.2 allprojects method

In your root-level (project-level) Gradle file (<project>/build.gradle), add the Maven repository URL to the repositories block within allprojects.

allprojects {
  repositories {
    maven {
      url 'https://maven.aliyun.com/nexus/content/repositories/releases/'
    }

    // Configure the Maven repository URL for the HMS Core SDK. This is required for integrating the Huawei channel.
    maven {
      url 'https://developer.huawei.com/repo/'
    }
  }
}

1.2 Add the SDK dependency

In your module-level (app-level) Gradle file (usually <project>/<app-module>/build.gradle), add the SDK dependency to the dependencies block.

dependencies {
  implementation 'com.aliyun.ams:alicloud-android-push:{pushVersion}'
}
Important
  • To get the value of pushVersion, see Android SDK version guide.

  • Use a fixed version number for the integration. Do not use a dynamic version number. For example, do not use 3.+ or 3.2.+.

2. Use the local dependency method

2.1 Download the SDK

See Quick Start, select Mobile Push to download the SDK, and copy all files from the SDK package to the <project>/<app-module>/libs directory of your module.

2.2 Add the SDK dependency

2.2.1 Configure the local SDK directory

In your module-level (app-level) Gradle file (usually <project>/<app-module>/build.gradle), add the local SDK file directory path.

repositories {
  flatDir {
    dirs 'libs'
  }
}

2.2.2 Add the SDK dependency

In your module-level (app-level) Gradle file (usually <project>/<app-module>/build.gradle), add the SDK dependency to the dependencies block.

dependencies {
  implementation fileTree(include the following: ['*.jar'], dir: 'libs')
  implementation (name:'alicloud-android-push-3.x.x', ext: 'aar')
  implementation (name:'accs_sdk_taobao-4.x.x', ext: 'aar')
  // Add all AAR files.
  ...
}
Important
  • The SDK version number in the sample dependency must match the version number in the filename of the downloaded artifact.

  • If a class conflict occurs during compilation, check whether implementation fileTree(dir: 'libs', include the following: ['*.jar']) already exists in the dependencies.

  • Auxiliary channel SDKs do not support local dependencies. They only support Maven dependencies.

Step 2: Configure the SDK

1. Configure the AppKey and AppSecret

You can configure the AppKey and AppSecret in one of two ways: using the AndroidManifest file or using code configuration. Select one method as needed.

Note
  • To prevent the appkey and appsecret parameters or data generated during app runtime from being leaked in logs, we recommend disabling SDK debug logs for the production version.

  • To prevent information leaks from malicious decompilation of your AppKey and AppSecret, we recommend using the code configuration method. Enable obfuscation and reinforce your app before publishing it.

  • If you are a Baichuan Cloud Push user, you cannot directly use the AppKey and AppSecret from the Baichuan platform. You must log on to the EMAS console with your Baichuan account and use the AppKey and AppSecret from the Alibaba Cloud EMAS platform.

1.1 Use the AndroidManifest file

Configure the AppKey and AppSecret in the AndroidManifest.xml file. Add the corresponding meta-data to the application node as shown below.

Note
  • com.alibaba.app.appkey and com.alibaba.app.appsecret are the corresponding information for your app on the EMAS platform. You can find the AppKey and AppSecret in the Application Management section of the EMAS console or in the downloaded configuration file.

  • Make sure to place the AppKey and AppSecret under the application tag. Otherwise, the SDK reports an error indicating that the AppKey cannot be found.

<application android:name="*****">
    <!-- Enter your AppKey. -->
    <meta-data android:name="com.alibaba.app.appkey" android:value="*****"/> 
    <!-- Enter your AppSecret. -->
    <meta-data android:name="com.alibaba.app.appsecret" android:value="****"/> 
</application>

1.2 Use code configuration

In addition to configuring the AppKey and AppSecret in the AndroidManifest file, you can also configure them in your code.

val pushInitConfig = PushInitConfig.Builder()
    .application(application)
    .appKey(appKey)    //Enter your AppKey.
    .appSecret(appSecret)    //Enter your AppSecret.
    .build()
PushInitConfig pushInitConfig = new PushInitConfig.Builder()
        .application(application)
        .appKey(appKey)    //Enter your AppKey.
        .appSecret(appSecret)    //Enter your AppSecret.
        .build();

For more configuration interfaces, see Basic configuration interfaces and Advanced configuration interfaces.

2. Initialize the SDK

To minimize the impact on your app's startup speed, you can perform the initialization in stages.

2.1 Logic that must be executed in Application onCreate

This stage initializes push parameters without starting the push logic. You must execute it in Application onCreate.

Depending on the method you chose in the previous section to configure the AppKey and AppSecret, there are two ways to initialize the code.

AndroidManifest file configuration

PushServiceFactory.init(context)
PushServiceFactory.init(context);

Use code configuration

PushServiceFactory.init(pushInitConfig)
PushServiceFactory.init(pushInitConfig);
Note

If you have configured the AppKey and AppSecret in AndroidManifest.xml, you can still use PushServiceFactory.init(pushInitConfig). If you also configure the AppKey and AppSecret in PushInitConfig, the configuration in PushInitConfig takes precedence.

2.2 Logic that can be executed with a delay

This stage establishes the persistent push connection. You can delay its execution based on your business and compliance requirements.

val pushService = PushServiceFactory.getCloudPushService()
pushService.register(this, object : com.alibaba.sdk.android.push.CommonCallback {
    override fun onSuccess(success: String) {}
    override fun onFailed(errorCode: String, errorMessage: String) {}
})
CloudPushService pushService = PushServiceFactory.getCloudPushService();
pushService.register(this, new com.alibaba.sdk.android.push.CommonCallback() {
    @Override
    public void onSuccess(String success) {

    }

    @Override
    public void onFailed(String errorCode, String errorMessage) {
        
    }
});
Important

PushServiceFactory.init must be called in the main thread of the Application. Do not call it in an Activity or initialize it asynchronously. During initialization, Mobile Push starts a background process named channel. Make sure that both the application process and the channel process execute PushServiceFactory.init.

3. Create a notification channel

For apps targeting Android 8.0 and later, you must create a NotificationChannel on the client. The following code provides an example.

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
    // The ID of the notification channel.
    val channelId = "vibration_sound" // This ID must be provided to backend developers and O&M engineers. It corresponds to the AndroidNotificationChannel parameter for pushes.
    // The name of the notification channel that is visible to users.
    val name: CharSequence = "My Test Channel"
    // The description of the notification channel that is visible to users.
    val description = "My Test Channel"
    val importance = NotificationManager.IMPORTANCE_HIGH
    val channel = NotificationChannel(channelId, name, importance)
    
    // Configure the properties of the notification channel.
    channel.description = description
    // Enable notification lights if the Android device supports them.
    channel.enableLights(true)
    channel.lightColor = Color.RED
    // Enable vibration for notifications if the Android device supports it.
    channel.enableVibration(true)
    // Custom ringtone.
    channel.setSound(
        Uri.parse("android.resource://${packageName}/${R.raw.push_hongbao}"),
        Notification.AUDIO_ATTRIBUTES_DEFAULT
    )
    channel.vibrationPattern = longArrayOf(100, 200, 300, 400, 500, 400, 300, 200, 400)
    // Create the notification channel in the notification manager.
    notificationManager.createNotificationChannel(channel)
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    // The ID of the notification channel.
    String channelId = "vibration_sound"; // This ID must be provided to backend developers and O&M engineers. It corresponds to the AndroidNotificationChannel parameter for pushes.
    // The name of the notification channel that is visible to users.
    CharSequence name = "My Test Channel";
    // The description of the notification channel that is visible to users.
    String description = "My Test Channel";
    int importance = NotificationManager.IMPORTANCE_HIGH;
    NotificationChannel mChannel = new NotificationChannel(channelId, name, importance);
    // Configure the properties of the notification channel.
    mChannel.setDescription(description);
    // Enable notification lights if the Android device supports them.
    mChannel.enableLights(true);
    mChannel.setLightColor(Color.RED);
    // Enable vibration for notifications if the Android device supports it.
    mChannel.enableVibration(true);
    //  Custom ringtone.
    mChannel.setSound(Uri.parse("android.resource://"
            + this.getPackageName() + "/" + R.raw.push_hongbao), Notification.AUDIO_ATTRIBUTES_DEFAULT);
    mChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});
    // Create the notification channel in the notification manager.
    mNotificationManager.createNotificationChannel(mChannel);
}

When you send a push, the AndroidNotificationChannel parameter in the advanced push API call must match the channelId of the notification channel created on the client. If no notification channel is created or the parameters do not match, the notification will not appear.

Note

For vivo devices, before creating a notification channel on the client, you must apply for a channel on the vivo Open Platform by filling in the required information. The notification channel ID must be consistent with the client's notification channel channelId. For more information, see Add a channel.

4. Configure message receiving

At this point, you have initialized the SDK and established the persistent push connection. However, you still need to perform some configurations to receive push messages.

We provide MessageReceiver and AliyunMessageIntentService to help you intercept notifications, receive messages, and get the extended fields from pushes. You can also perform subsequent processing when a notification is opened or deleted.

You can choose either method to process push messages. For more information, see Message and notification handling interfaces.

Important
  • After you complete this step, your app should be able to receive push messages.

  • If you cannot receive push notifications on some phones, it may be due to system version differences. For more information, see Notes.

  • You only need to register your custom default implementation of MessageReceiver or AliyunMessageIntentService to receive notifications with the default style. To customize styles, intercept notifications in the foreground, or process pass-through messages, you need to extend the corresponding APIs.

5. Configure NDK

In your module-level (app-level) Gradle file (usually <project>/<app-module>/build.gradle), add the NDK configuration to the defaultConfig node within the android block.

android {
    defaultConfig {
        ndk {
            // Select the .so libraries for the corresponding CPU types. This is for demonstration only. Push supports all mainstream types. Select as needed.
            abiFilters 'arm64-v8a', 'armeabi-v7a', 'x86', 'x86_64'
        }
    }
}

6. Customize push notification styles (optional)

To customize the style of notifications, see Custom notification style interfaces.

7. Intercept push notifications (optional)

To intercept and process push notifications, extend the showNotificationNow and onNotificationReceivedInApp methods of MessageReceiver or AliyunMessageIntentService. The following example shows how to extend MessageReceiver.

class MyMessageReceiver: MessageReceiver(){

    override fun onNotificationReceivedInApp(
        context: Context?,
        title: String?,
        summary: String?,
        map: MutableMap<String, String>?,
        openType: Int,
        openActivity: String?,
        openUrl: String?
    ) {
        // Process the received push notification here.
    }

    override fun showNotificationNow(p0: Context?, p1: MutableMap<String, String>?): Boolean {
        // false indicates that the notification is intercepted. true indicates that it is not. After a notification is intercepted, onNotificationReceivedInApp is executed.
        return false
    }
}
public class MyMessageReceiver extends MessageReceiver {
    @Override
    protected void onNotificationReceivedInApp(Context context, String title, String summary, Map<String, String> map, int openType, String openActivity, String openUrl) {
        // Process the received push notification here.
    }

    @Override
    public boolean showNotificationNow(Context context, Map<String, String> map) {
        // false indicates that the notification is intercepted. true indicates that it is not. After a notification is intercepted, onNotificationReceivedInApp is executed.
        return false;
    }
}

For intercepted push notifications, you must report click and cancel events yourself. For information about the reporting interfaces, see Self-built notification statistics reporting interfaces.

8. Handle push messages (recommended)

Push supports two types of messages. For push notifications, the SDK provides a default implementation where the message is displayed in the notification bar upon arrival. For push messages, you need to extend the API to implement them. Extend the onMessage interface of MessageReceiver or AliyunMessageIntentService. The following example shows how to extend MessageReceiver.

class Kk: MessageReceiver() {
    override fun onMessage(context: Context?, cPushMessage: CPushMessage?) {
        val title = cPushMessage?.title
        val content = cPushMessage?.content

        if (isForeground) {
            // The app is in the foreground. Display as a pop-up.
        } else {
            // The app is in the background. Display as a notification.
        }
    }
}
public class MyMessageReceiver extends MessageReceiver {
    @Override
    protected void onMessage(Context context, CPushMessage cPushMessage) {
        String title = cPushMessage.getTitle();
        String content = cPushMessage.getContent();

        if (isForeground) {
            // The app is in the foreground. Display as a pop-up.
        } else {
            // The app is in the background. Display as a notification.
        }
    }
}

For push messages, you must report click and cancel events yourself. For information about the reporting interfaces, see Self-built notification statistics reporting interfaces.

9. Use tags for pushes (optional)

In addition to broadcasting pushes to all devices, we also support batch pushes using tags. Before you can push by tag, you must bind tags to devices on the SDK side. For information about the relevant interfaces, see Tag management interfaces. The following code provides an example:

PushServiceFactory.getCloudPushService()
    .bindTag(CloudPushService.DEVICE_TARGET, arrayOf(tag), null, object : CommonCallback {
        override fun onSuccess(s: String) {}
        override fun onFailed(errorCode: String, errorMsg: String) {}
    })
PushServiceFactory.getCloudPushService().bindTag(CloudPushService.DEVICE_TARGET, new String[]{tag}, null, new CommonCallback() {
    @Override
    public void onSuccess(String s) {

    }

    @Override
    public void onFailed(String errorCode, String errorMsg) {

    }
});

In addition to using tags for pushes, we also support:

10. Configure obfuscation

If your project uses code obfuscation tools such as Proguard, keep the following configuration:

-keepclasseswithmembernames class ** {
    native <methods>;
}
-keepattributes Signature
-keep class sun.misc.Unsafe { *; }
-keep class com.taobao.** {*;}
-keep class com.alibaba.** {*;}
-keep class com.alipay.** {*;}
-keep class com.ut.** {*;}
-keep class com.ta.** {*;}
-keep class anet.**{*;}
-keep class anetwork.**{*;}
-keep class org.android.spdy.**{*;}
-keep class org.android.agoo.**{*;}
-keep class android.os.**{*;}
-keep class org.json.**{*;}
-dontwarn com.taobao.**
-dontwarn com.alibaba.**
-dontwarn com.alipay.**
-dontwarn anet.**
-dontwarn org.android.spdy.**
-dontwarn org.android.agoo.**
-dontwarn anetwork.**
-dontwarn com.ut.**
-dontwarn com.ta.**

Step 3: Integrate third-party channels

To improve the delivery rate of pushes when your app is offline, we recommend integrating third-party channels. For more information, see Third-party channel integration.

Important

The versions of third-party channels and the Push SDK have a mapping relationship. For more information, see Third-party channel SDK version relationships.

Step 4: Verify the integration

1. Enable SDK logs

val pushService = PushServiceFactory.getCloudPushService()
// This line is only for debug packages and is not needed for release packages.
pushService.setLogLevel(CloudPushService.LOG_DEBUG)
CloudPushService pushService = PushServiceFactory.getCloudPushService();
// This line is only for debug packages and is not needed for release packages.
pushService.setLogLevel(CloudPushService.LOG_DEBUG);      

2. Confirm normal startup

  • The callback.onSuccess() method is called. In the logcat logs, enter the tag MPS:

2024-07-03 10:34:48.630 14509-9747  [MPS]                   com.aliyun.emas.pocdemo              I  agoo init success.
2024-07-03 10:34:48.631 14509-9749  [MPS]                   com.aliyun.emas.pocdemo              D  register agoo result Error code: PUSH_00000, Error: success
2024-07-03 10:34:48.631 14509-9749  MPS:AppRegister         com.aliyun.emas.pocdemo              I  connState=2;estimatedTime=384;response{msg: success, code: PUSH_00000}
2024-07-03 10:34:48.631 14509-9749  MPS:AppRegister         com.aliyun.emas.pocdemo              D  Looping handleMessage: 1
2024-07-03 10:34:48.631 14509-14509 [MPS]                   com.aliyun.emas.pocdemo              I  errorCode:Error code: PUSH_00000, Error: success
  • Confirm that the cloud channel is initialized correctly. In the logcat logs, enter the keyword awcn:

2024-07-03 10:36:57.464  8890-10129 EMASNAccs_NetworkSdk    com.aliyun.emas.pocdemo              I  [awcn.TnetSpdySession]  statusCode:200
2024-07-03 10:36:57.465  8890-10129 EMASNAccs_NetworkSdk    com.aliyun.emas.pocdemo              I  [awcn.TnetSpdySession]  response headers:{date=[Wed, 03 Jul 2024 02:36:57 GMT], content-length=[0], server=[Tengine/Aserver/3.0.413_20221027005707], s-accs-retcode=[SUCCESS], :status=[200], x-workerid=[360290169770599862], x-at=[ZoS4k5ejQckDADGQGBlEBBUB3347866231719988617]}
2024-07-03 10:36:57.467  8890-10129 EMASNAccs_NetworkSdk    com.aliyun.emas.pocdemo              E  [awcn.Session]|[seq:334786623.AWCN1_1] notifyStatus status:AUTH_SUCC
  • Confirm that the deviceId is obtained correctly: After successful initialization, you can successfully get the deviceId using cloudPushService.getDeviceId().

  • If the connection to the registration server fails, the callback.onFailed() method is called, and the SDK automatically retries registration until onSuccess is called. Retries are automatically triggered by events such as network transitions. The onFailed() method returns a corresponding error code. For more information, see Error handling.

Note

Some phones on the market have restrictions on log display. For example, Huawei phones block Debug and Verbose level logs. We recommend using Info level logs during development. For information on setting the log level, see "Set the log level" in Basic configuration interfaces.

Notes

1. Android 8+ compatibility

For more information, see Cannot receive push notifications on devices running Android 8.0 or later.

2. Android 13 compatibility

Android 13 adds the POST_NOTIFICATIONS permission. Push SDK 3.8.4 has added this permission. If your app's targetSdk is lower than 33, you only need to upgrade to version 3.8.4. The system will automatically display an authorization dialog when the app starts. If the targetSdk is 33, your app needs to request the POST_NOTIFICATIONS permission at runtime.

Notes for non-phone scenarios

On some specific devices, the usage scenarios differ from typical phone scenarios, and special configurations can be made. There are two main types: one is for phone-like applications that run only when the user is using them and may be reclaimed by the system when not in use. The other is for system-level applications that run for a long time.

Configuration for phone-like applications

In this scenario, you can enable the channel process heartbeat to improve the stability of the channel.

val pushInitConfig = PushInitConfig.Builder()
    .application(application)
    // Enable the channel process.
    .disableChannelProcess(false)
    // Enable the channel process heartbeat.
    .disableChannelProcessHeartbeat(false)
    .build()

PushServiceFactory.init(pushInitConfig)

val pushService = PushServiceFactory.getCloudPushService()
pushService.register(this, object : com.alibaba.sdk.android.push.CommonCallback {
    override fun onSuccess(success: String) {}
    override fun onFailed(errorCode: String, errorMessage: String) {}
})
PushInitConfig pushInitConfig = new PushInitConfig.Builder()
        .application(application)
        // Enable the channel process.
        .disableChannelProcess(false)
        // Enable the channel process heartbeat.
        .disableChannelProcessheartbeat(false)
        .build()

PushServiceFactory.init(pushInitConfig);

CloudPushService pushService = PushServiceFactory.getCloudPushService();
pushService.register(applicationContext, new CommonCallback() {
    @Override
    public void onSuccess(String response) {
        
    }
    @Override
    public void onFailed(String errorCode, String errorMessage) {
        
    }
});

If the system does not support JobService (Android API level is lower than 21), you also need to add the WAKE_LOCK permission.

<!-- Add the WAKE_LOCK permission if the device's Android API level is lower than 21. -->
<uses-permission android:name="android.permission.WAKE_LOCK"/>

Long-running system applications

Because these applications run continuously, you can consider not using the channel process push channel and instead use only the in-app push channel, depending on system performance requirements.

val pushInitConfig = PushInitConfig.Builder()
    .application(application)
    // Disable the channel process as needed.
    .disableChannelProcess(false)
    // Disable the channel process heartbeat.
    .disableChannelProcessHeartbeat(false)
    .build()

PushServiceFactory.init(pushInitConfig)

val pushService = PushServiceFactory.getCloudPushService()
pushService.register(this, object : com.alibaba.sdk.android.push.CommonCallback {
    override fun onSuccess(success: String) {}
    override fun onFailed(errorCode: String, errorMessage: String) {}
})
PushInitConfig pushsInitConfig = new PushInitConfig.Builder()
        .application(application)
        // Disable the channel process as needed.
        .disableChannelProcess(true)
        // Disable the channel process heartbeat.
        .disableChannelProcessheartbeat(true)
        .build();
PushServiceFactory.init(pushsInitConfig);

CloudPushService pushService = PushServiceFactory.getCloudPushService();
pushService.register(applicationContext, new CommonCallback() {
    @Override
    public void onSuccess(String response) {

    }
    @Override
    public void onFailed(String errorCode, String errorMessage) {

    }
});

For long-running applications, you need to check whether the connection is always maintained. You can register your own listener interface and implement certain checks.

val handler = Handler()
val controlService = PushServiceFactory.getPushControlService()
controlService.setConnectionChangeListener(object : ConnectionChangeListener {
    override fun onConnect() {}
    override fun onDisconnect(code: String, msg: String) {
        val isNetworkIssue = !isNetworkConnected()
        // Check again after a period, for example, 30 seconds.
        handler.postDelayed(Runnable {
            if (isNetworkConnected() && !controlService.isConnected()) {
                // If there is no network issue and the connection has not been restored.
                // At this point, record the instrumentation data for the code and msg. Be sure to record the msg information.
                recordDisconnectEvent(code, msg)
                if (isNetworkIssue) {
                    // There was no network just now. Try to reconnect.
                    controlService.reconnect()
                } else {
                    // There is no network issue, or reconnection fails. Reset and re-initialize.
                    controlService.reset()
                    initCloudChannel(getContext())
                }
            }
        }, 30 * 1000)
    }
})
// This is sample code. Do not use it directly. Use the API according to your specific business needs.
final Handler handler = new Handler();
PushControlService controlService = PushServiceFactory.getPushControlService();
controlService.setConnectionChangeListener(new PushControlService.ConnectionChangeListener() {
    @Override
    public void onConnect() {

    }

    @Override
    public void onDisconnect(final String code, final String msg) {
        final boolean isNetworkIssue = !isNetworkConnected();
        // Check again after a period, for example, 30 seconds.
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                if(isNetworkConnected() && !controlService.isConnected()) {
                    // If there is no network issue and the connection has not been restored.
                    // At this point, record the instrumentation data for the code and msg. Be sure to record the msg information.
                    recordDisconnectEvent(code, msg);
                    if (isNetworkIssue) {
                        // There was no network just now. Try to reconnect.
                        controlService.reconnect();
                    } else {
                        // There is no network issue, or reconnection fails. Reset and re-initialize.
                        controlService.reset();
                        initCloudChannel(getContext());
                    }

                }
            }
        }, 30 * 1000);
    }
});

How to manually shut down and resume the persistent connection

After the Mobile Push SDK is registered, a persistent connection is established and maintained unless manually handled. In certain scenarios, such as for performance optimization, you may need to manually control the disconnection and resumption of the persistent connection. The following sections describe how to shut down and resume the persistent connection.

Shut down the persistent connection

The following code shows how to shut down the persistent connection:

PushServiceFactory.getPushControlService().disconnect();
PushServiceFactory.getPushControlService().reset();
PushServiceFactory.getPushControlService().disconnect()
PushServiceFactory.getPushControlService().reset()

Resume the persistent connection

To manually resume the persistent connection, simply register again. The following code shows how to do this:

CloudPushService pushService = PushServiceFactory.getCloudPushService();
pushService.register(this, new com.alibaba.sdk.android.push.CommonCallback() {
    @Override
    public void onSuccess(String success) {

    }

    @Override
    public void onFailed(String errorCode, String errorMessage) {
        
    }
});
 PushServiceFactory.getCloudPushService().register(context , object: CommonCallback{
    override fun onSuccess(success: String?) {}

    override fun onFailed(errorCode: String?, errorMessage: String?) {}

})

Common integration issues

  1. UTDID conflict. For more information, see Solutions to UTDID conflicts for Alibaba Cloud product SDKs.

  2. How do I resolve the java.lang.NoClassDefFoundError error that occurs after integrating the Android SDK and running the app?

  3. Troubleshooting documentation for Mobile Push Android integration failures

  4. An error occurred during Push SDK initialization

  5. How do I resolve the 1105 and 10207 errors that occur during Android SDK initialization?

  6. Cannot receive push notifications after initializing the Push SDK in an Activity