Android SDK 4.x upgrade guide

更新时间:
复制 MD 格式

This topic describes the changes required in your application to upgrade the Mobile Push Android software development kit (SDK) from version 3.x to 4.x or later.

Introduction

The Mobile Push Android SDK 4.x includes upgraded underlying persistent connection capabilities. These upgrades change some client-side interfaces and notification callback behaviors. If your application uses the 3.x SDK, you must follow this guide to complete the upgrade.

Upgrade changes

After you upgrade to version 4.x, take note of the following changes:

  • Callbacks for notification clicks and arrivals on the Alibaba Cloud proprietary channel are adjusted.

  • The notification click callback for third-party channels no longer uses onSysNoticeOpened of the auxiliary pop-up window. It is migrated to onNotificationOpened of MessageReceiver or AliyunMessageIntentService.

  • The tag interfaces support only device tags. Account tags and alias tags are no longer supported.

  • The configuration interfaces related to the channel process are removed.

  • The persistent connection control interfaces related to PushControlService are removed.

Step 1: Upgrade the SDK dependency

In the build.gradle file of your application module, upgrade the main Mobile Push SDK to version 4.0.0 or later.

dependencies {
    implementation 'com.aliyun.ams:alicloud-android-push:4.0.0'
}

If your application integrates third-party channels, you must also upgrade the dependencies for those channels.

dependencies {
    implementation 'com.aliyun.ams:alicloud-android-third-push:4.0.0'

    // Integrate the required third-party channels.
    implementation 'com.aliyun.ams:alicloud-android-third-push-xiaomi:4.0.0'
    implementation 'com.aliyun.ams:alicloud-android-third-push-huawei:4.0.0'
    implementation 'com.aliyun.ams:alicloud-android-third-push-honor:4.0.0'
    implementation 'com.aliyun.ams:alicloud-android-third-push-oppo:4.0.0'
    implementation 'com.aliyun.ams:alicloud-android-third-push-vivo:4.0.0'
    implementation 'com.aliyun.ams:alicloud-android-third-push-meizu:4.0.0'
    implementation 'com.aliyun.ams:alicloud-android-third-push-fcm:4.0.0'
}

Note

  • Use a fixed version number for the integration. Do not use dynamic versions, such as 4.+.

Step 2: Adjust message and notification callbacks

The new SDK adjusts some notification callback interfaces. Check whether your existing code uses these callbacks and modify your code to use the new interfaces.

Old callback

New method

onNotificationOpened(Context, String, String, String)

Change to onNotificationOpened(Context, String, String, Map<String, String>).

onNotificationClickedWithNoAction(...)

Removed. Clicks on notifications without a redirect action now uniformly trigger the onNotificationOpened callback.

onNotificationReceivedInApp(...)

Removed. Notification arrivals now uniformly trigger the onNotification callback.

If your previous code uses the extraMap string, change it to directly use Map<String, String>.

@Override
public void onNotificationOpened(Context context, String title, String summary, Map<String, String> extraMap) {
    String value = extraMap == null ? null : extraMap.get("key");
}
override fun onNotificationOpened(
    context: Context,
    title: String,
    summary: String,
    extraMap: Map<String, String>
) {
    val value = extraMap["key"]
}

Method 1: Use MessageReceiver to receive messages and notifications

The new SDK still supports receiving messages and notifications through MessageReceiver. The following code provides an example.

public class MyMessageReceiver extends MessageReceiver {
    // Callback for message arrivals on the Alibaba Cloud proprietary channel
    @Override
    public void onMessage(Context context, CPushMessage message) {
    }

    // Callback for notification arrivals on the Alibaba Cloud proprietary channel
    @Override
    public void onNotification(Context context, String title, String summary, Map<String, String> extraMap) {
    }

    // Callback for notification clicks on the Alibaba Cloud proprietary channel and third-party channels
    @Override
    public void onNotificationOpened(Context context, String title, String summary, Map<String, String> extraMap) {
    }

    // Callback for notification removals on the Alibaba Cloud proprietary channel
    @Override
    public void onNotificationRemoved(Context context, String messageId) {
    }
}
class MyMessageReceiver : MessageReceiver() {
    // Callback for message arrivals on the Alibaba Cloud proprietary channel
    override fun onMessage(context: Context, message: CPushMessage) {
    }
    
    // Callback for notification arrivals on the Alibaba Cloud proprietary channel
    override fun onNotification(
        context: Context,
        title: String,
        summary: String,
        extraMap: Map<String, String>
    ) {
    }

    // Callback for notification clicks on the Alibaba Cloud proprietary channel and third-party channels
    override fun onNotificationOpened(
        context: Context,
        title: String,
        summary: String,
        extraMap: Map<String, String>
    ) {
    }

    // Callback for notification removals on the Alibaba Cloud proprietary channel
    override fun onNotificationRemoved(context: Context, messageId: String) {
    }
}

Register it in AndroidManifest.xml:

<receiver
    android:name="The fully qualified class name of your MessageReceiver"
    android:exported="false">
    <intent-filter>
        <action android:name="com.alibaba.push2.action.NOTIFICATION_OPENED" />
    </intent-filter>
    <intent-filter>
        <action android:name="com.alibaba.push2.action.NOTIFICATION_REMOVED" />
    </intent-filter>
    <intent-filter>
        <action android:name="com.alibaba.sdk.android.push.RECEIVE" />
    </intent-filter>
</receiver>

Method 2: Use AliyunMessageIntentService to receive messages and notifications

public class MyMessageIntentService extends AliyunMessageIntentService {
    // Callback for message arrivals on the Alibaba Cloud proprietary channel
    @Override
    public void onMessage(Context context, CPushMessage message) {
    }

    // Callback for notification arrivals on the Alibaba Cloud proprietary channel
    @Override
    public void onNotification(Context context, String title, String summary, Map<String, String> extraMap) {
    }

    // Callback for notification clicks on the Alibaba Cloud proprietary channel and third-party channels
    @Override
    public void onNotificationOpened(Context context, String title, String summary, Map<String, String> extraMap) {
    }

    // Callback for notification removals on the Alibaba Cloud proprietary channel
    @Override
    public void onNotificationRemoved(Context context, String messageId) {
    }
}
class MyMessageIntentService : AliyunMessageIntentService() {
    // Callback for message arrivals on the Alibaba Cloud proprietary channel
    override fun onMessage(context: Context, message: CPushMessage) {
    }
    
    // Callback for notification arrivals on the Alibaba Cloud proprietary channel
    override fun onNotification(
        context: Context,
        title: String,
        summary: String,
        extraMap: Map<String, String>
    ) {
    }

    // Callback for notification clicks on the Alibaba Cloud proprietary channel and third-party channels
    override fun onNotificationOpened(
        context: Context,
        title: String,
        summary: String,
        extraMap: Map<String, String>
    ) {
    }

    // Callback for notification removals on the Alibaba Cloud proprietary channel
    override fun onNotificationRemoved(context: Context, messageId: String) {
    }
}

Register it in AndroidManifest.xml:

<service
    android:name="The fully qualified class name of your MessageIntentService"
    android:exported="false">
    <intent-filter>
        <action android:name="com.alibaba.push2.action.NOTIFICATION_OPENED" />
    </intent-filter>
    <intent-filter>
        <action android:name="com.alibaba.push2.action.NOTIFICATION_REMOVED" />
    </intent-filter>
    <intent-filter>
        <action android:name="com.alibaba.sdk.android.push.RECEIVE" />
    </intent-filter>
</service>

Then, set it after initialization:

CloudPushService pushService = PushServiceFactory.getCloudPushService();
pushService.setPushIntentService(MyMessageIntentService.class);
val pushService = PushServiceFactory.getCloudPushService()
pushService.setPushIntentService(MyMessageIntentService::class.java)

Note

  • If setPushIntentService is set, message and notification callbacks are handled by AliyunMessageIntentService instead of MessageReceiver.

  • If setPushIntentService is not set, callbacks are handled by MessageReceiver by default.

Step 3: Adjust the third-party channel click callback

The new SDK merges the click callback for third-party channels into the onNotificationOpened callback. The auxiliary pop-up Activity is still used as an entry point for third-party channel notification clicks, but the business logic is no longer processed through the onSysNoticeOpened, onNotPushData, or onParseFailed callbacks.

Old method

New method

Inherit from AndroidPopupActivity and handle third-party channel notification clicks in onSysNoticeOpened.

Continue to inherit from AndroidPopupActivity as a transit Activity, but migrate the click callback to MessageReceiver.onNotificationOpened or AliyunMessageIntentService.onNotificationOpened.

Implement PopupNotifyClickListener and handle third-party channel notification clicks in onSysNoticeOpened.

Continue to use PopupNotifyClick in an existing Activity to handle the third-party click Intent, but no longer implement the PopupNotifyClickListener callbacks. You must migrate the click callback to onNotificationOpened.

After the upgrade, you must migrate the business logic for third-party channel notification clicks to onNotificationOpened in MessageReceiver or AliyunMessageIntentService.

Method 1: Create a custom Activity that inherits from AndroidPopupActivity

public class MyPopupActivity extends AndroidPopupActivity {
}
class MyPopupActivity : AndroidPopupActivity()

Method 2: Implement the auxiliary pop-up in an existing Activity

public class MyPopupActivity extends Activity {
    private final PopupNotifyClick popupNotifyClick = new PopupNotifyClick();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        popupNotifyClick.onCreate(this, getIntent());
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        popupNotifyClick.onNewIntent(intent);
    }
}
class MyPopupActivity : Activity() {
    private val popupNotifyClick = PopupNotifyClick()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        popupNotifyClick.onCreate(this, intent)
    }

    override fun onNewIntent(intent: Intent) {
        super.onNewIntent(intent)
        popupNotifyClick.onNewIntent(intent)
    }
}

Register your custom auxiliary pop-up Activity in the AndroidManifest.xml file. You must add it under the application node.

<activity
    android:name="The fully qualified class name of the auxiliary pop-up Activity"
    android:exported="true">
    
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />

        <data
            android:host="${applicationId}"
            android:path="/thirdpush"
            android:scheme="agoo" />
    </intent-filter>
    
</activity>

The following example shows how to handle click events in the new version using MessageReceiver:

public class MyMessageReceiver extends MessageReceiver {
    // Callback for notification clicks on the Alibaba Cloud proprietary channel and third-party channels
    @Override
    public void onNotificationOpened(Context context, String title, String summary, Map<String, String> extraMap) {
        // Uniformly handle notification clicks from the proprietary channel and third-party channels.
    }
}
class MyMessageReceiver : MessageReceiver() {
    // Callback for notification clicks on the Alibaba Cloud proprietary channel and third-party channels
    override fun onNotificationOpened(
        context: Context,
        title: String,
        summary: String,
        extraMap: Map<String, String>
    ) {
        // Uniformly handle notification clicks from the proprietary channel and third-party channels.
    }
}

Note

  • You must still configure the auxiliary pop-up Activity on the server side. It is used as a transit point for clicks on third-party channel notifications.

  • After the click data is successfully parsed, the SDK sends the notification click event to the onNotificationOpened callback in MessageReceiver or AliyunMessageIntentService.

  • The application no longer needs to implement onSysNoticeOpened, onNotPushData, or onParseFailed to handle third-party channel click events.

Step 4: Adjust the tag interfaces

The new SDK supports only device tags. Account tags and alias tags are no longer supported. The interface input parameters include only tags and callback.

Old interface

New interface

bindTag(int target, String[] tags, String alias, CommonCallback callback)

bindTag(String[] tags, CommonCallback callback)

unbindTag(int target, String[] tags, String alias, CommonCallback callback)

unbindTag(String[] tags, CommonCallback callback)

listTags(int target, CommonCallback callback)

listTags(CommonCallback callback)

// New version: Bind device tags.
CloudPushService pushService = PushServiceFactory.getCloudPushService();
pushService.bindTag(tags, callback);

// New version: Unbind device tags.
pushService.unbindTag(tags, callback);

// New version: Query device tags.
pushService.listTags(callback);
// New version: Bind device tags.
val pushService = PushServiceFactory.getCloudPushService()
pushService.bindTag(tags, callback)

// New version: Unbind device tags.
pushService.unbindTag(tags, callback)

// New version: Query device tags.
pushService.listTags(callback)

Step 5: Remove configurations related to the channel process

The previous SDK allowed you to configure the channel process and its heartbeat through PushInitConfig.Builder. The underlying persistent connection is upgraded in the new SDK, and the following interfaces are no longer provided:

Old interface

New method

disableChannelProcess(boolean)

Remove the call.

disableChannelProcessHeartbeat(boolean)

Remove the call.

loopStartChannel(boolean)

Remove the call.

loopInterval(long)

Remove the call.

Step 6: Remove logic related to PushControlService

The previous SDK provided PushControlService to query, listen for, reconnect, or reset persistent connections. The new SDK no longer provides this class or its related interfaces.

Old interface

New method

PushServiceFactory.getPushControlService()

Remove the call.

PushControlService.isConnected()

Remove the call.

PushControlService.setConnectionChangeListener(...)

Remove the call.

PushControlService.reconnect()

Remove the call.

PushControlService.reset()

Remove the call.

PushControlService.disconnect()

Remove the call.

If your previous code contains logic for manual reconnection, connection reset, or listening for connection status, you must remove the related calls.

Optional changes

Third-party token query interface

The new third-party channel adds a local token query interface. If your application needs to read the most recently stored third-party token, you can use the following interfaces.

String miToken = MiPushRegister.getToken(context);
String huaweiToken = HuaWeiRegister.getToken(context);
String honorToken = HonorRegister.getToken(context);
String oppoToken = OppoRegister.getToken(context);
String vivoToken = VivoRegister.getToken(context);
String meizuToken = MeizuRegister.getToken(context);
String fcmToken = GcmRegister.getToken(context);
val miToken = MiPushRegister.getToken(context)
val huaweiToken = HuaWeiRegister.getToken(context)
val honorToken = HonorRegister.getToken(context)
val oppoToken = OppoRegister.getToken(context)
val vivoToken = VivoRegister.getToken(context)
val meizuToken = MeizuRegister.getToken(context)
val fcmToken = GcmRegister.getToken(context)

Note

  • getToken returns the most recent third-party token that is stored locally.

  • If the third-party registration is not yet successful, the return value may be empty.

Notification sound setting interface

setNotificationSoundFilePath is deprecated in the new SDK. If your previous code uses this interface, you must migrate to configuring notification sounds through a Notification Channel.

Upgrade validation

After you complete the upgrade, you can validate it as follows:

  • Start the application and confirm that the register callback is successful.

  • Call getDeviceId and confirm that you can retrieve the device ID.

  • Send a notification from the console or using OpenAPI and confirm that the notification is displayed.

  • Click notifications from the proprietary channel and third-party channels, and confirm that onNotificationOpened is called back.

  • Delete a notification and confirm that onNotificationRemoved is called back.

  • Send a message and confirm that onMessage is called back.

  • If you use the tag feature, confirm that the calls to bind, unbind, and query device tags are successful.

FAQ

Why is the onSysNoticeOpened callback not triggered for clicks on third-party channel notifications?

The new SDK unifies the third-party channel click callback into onNotificationOpened. You must migrate your business logic to onNotificationOpened in MessageReceiver or AliyunMessageIntentService.

Do I still need to configure the channel process after the upgrade?

No. The underlying persistent connection in version 4.x and later is upgraded and no longer uses the previous channel process configuration.

Can I still manually control the persistent connection after the upgrade?

Interfaces such as PushControlService.reconnect and reset are no longer provided. The new SDK internally maintains the connection status. You do not need to manually control it from the application side.