Skip to main content
Version: v3

Updates Integration Guide

When you release a new version of your game and wish the existing players to upgrade to the new version, you may want to display a notification in the game. With TapTap’s Updates function, a pop-up can be triggered when the SDK detects a new version released on the TapTap store. The player can tap a button within the pop-up to quickly jump to the Taptap app to update the game.

Integrating the SDK

You can add the SDK either manually or with the Unity Package Manager.

If you choose to use the Unity Package Manager, you should add the following dependencies into Packages/manifest.json:

"dependencies":{
"com.taptap.tds.common":"https://github.com/TapTap/TapCommon-Unity.git#3.28.3",
"com.leancloud.storage": "https://github.com/leancloud/csharp-sdk-upm.git#storage-2.3.0",
}

If you choose to manually import the SDK, you should:

  • In the download page, click TapSDK Unity to download TapSDK-UnityPackage.zip.
  • Go to your Unity project, navigate to Assets > Import Package > Custom Package, select the TapTap_Common module from unzipped SDK.
  • Download LeanCloud-SDK-Storage-Unity.zip, unzip it as a Plugins folder, and drag and drop the folder into Unity.

Open the TapTap App to Check for Updates

tip

Starting from TapSDK 3.3.0, the logic for updating the game has been optimized. You can have the game open a custom webpage if it fails to open the TapTap app. TapSDK 3.3.0 is still compatible with the APIs introduced in the earlier versions. With TapSDK 3.3.0, you won’t need to check if the TapTap app has been installed before you use the following APIs. We recommend you to use the new APIs if you are using TapSDK 3.3.0 and later.

Open the TapTap app to check for updates. If failed, open the game’s page on the web app:

// For Mainland China
bool isSuccess = await TapCommon.UpdateGameAndFailToWebInTapTap(string appId);

// For other countries/regions
bool isSuccess = await TapCommon.UpdateGameAndFailToWebInTapGlobal(string appId);

Open a custom webpage if failed to open the TapTap app:

// For Mainland China
bool isSuccess = await TapCommon.UpdateGameAndFailToWebInTapTap(string appId, string webUrl);

// For other countries/regions
bool isSuccess = await TapCommon.UpdateGameAndFailToWebInTapGlobal(string appId, string webUrl);
If you are not using TapSDK 3.3.0 or later

This section is not applicable for TapSDK 3.3.0 and later. If you are using TapSDK 3.3.0 and later, please use the APIs mentioned earlier on this page.

Check if TapTap is installed:

// For Mainland China
TapCommon.IsTapTapInstalled(installed =>
{
if (installed) {
Debug.Log("TapTap is installed");
}
});

// For other countries/regions
TapCommon.IsTapTapGlobalInstalled(installed =>
{
if (installed) {
Debug.Log("TapTap is installed");
}
});

Open TapTap to update the game

TapCommon.UpdateGameInTapTap("appid", callSuccess =>
{
if (callSuccess) {
Debug.Log("TapTap opened");
}
});

Open Game Reviews

// For Mainland China
TapCommon.OpenReviewInTapTap(appId, openSuccess =>
{
if (openSuccess) {
Debug.Log("Game reviews opened");
}
});

// For other countries/regions
TapCommon.OpenReviewInTapGlobal(appId, openSuccess =>
{
if (openSuccess) {
Debug.Log("Game reviews opened");
}
});

appid is a game’s unique identifier in the TapTap store. For example, in https://www.taptap.cn/app/187168, 187168 is the appid.

FAQ

The TapTap app cannot be launched from the game on Android 11. Why?

Android 11 (API level 30) has ramped up its privacy protection policies resulting in a series of changes and restrictions, one of the key changes being Package Visibility, which prevents third-party apps from launching the TapTap app. This has affected related TapTap services from functioning properly, including but not limited to accessing TapTap for updates and purchase verification.

Solution 1

Compile the game with targetSdkVersion set to 29 (setting this to 30 or above will lead to the problem).

Solution 2

  1. Change gradle build tools to 4.1.0+:

    classpath 'com.android.tools.build:gradle:4.1.0'
  2. Add the following lines to AndroidManifest.xml:

    <queries>
    <package android:name="com.taptap" />
    <package android:name="com.taptap.pad" />
    <package android:name="com.taptap.global" />
    </queries>

If I’m not using the TapSDK, how can I open the TapTap app to update the game?

Due to Apple’s restrictions, TapTap for iOS doesn’t support the Updates function. The following instructions are for Android only.

If you are not using the TapSDK or using older versions of the TapSDK, you can follow the instructions below to manually open the TapTap app to update the game.

Open the corresponding URL according to whether TapTap is installed on the device:

  • If TapTap is installed, open the TapTap app and jump to the game’s page.
  • If not, open the game’s page in a web browser. The player will follow the instructions on the page to install the TapTap app, open the app, and update the game within the app.

URL for devices without TapTap:

  • For Mainland China: https://l.taptap.cn/5d1NGyET?subc1=AppID
  • For other countries/regions: https://l.taptap.io/GNYwFaZr?subc1=AppID

URL for devices with TapTap:

  • For Mainland China: taptap://taptap.cn/app?app_id=AppID&source=outer|update
  • For other countries/regions: tapglobal://taptap.tw/app?app_id=AppID&source=outer|update

Make sure to replace the AppID in the URL. AppID is a game’s unique identifier in the TapTap store. For example, in https://www.taptap.cn/app/187168, 187168 is the AppID.

Keep in mind that you have to write the logic not only to open the URL but also to check whether TapTap is installed, as well as handle errors.

Take a look at the code example below.

Code example

For Mainland China:

package com.tds.common.utils;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;
import java.util.Locale;

public class TapGameUtil {

private static final String TAG = TapGameUtil.class.getName();

public static final String PACKAGE_NAME_TAPTAP = "com.taptap";

public static final String CLIENT_URI_TAPTAP = "taptap://taptap.cn";

public static final String DEFAULT_CLIENT_DOWNLOAD_URL_TAPTAP = "https://l.taptap.cn/5d1NGyET";

public static boolean updateGameAndFailToWebInTapTap(Activity activity, String appId) {
return updateGameInTapTap(activity, appId) || openWebDownloadUrlOfTapTap(activity, appId);
}

public static boolean updateGameAndFailToWebInTapTap(Activity activity, String appId, String webUrl) {
if (TextUtils.isEmpty(webUrl)) {
return updateGameAndFailToWebInTapTap(activity, appId);
}
return updateGameInTapTap(activity, appId) || openWebDownloadUrl(activity, webUrl);
}

public static boolean isTapTapInstalled(Context context) {
return isTapClientInstalled(context, PACKAGE_NAME_TAPTAP);
}

public static boolean isTapClientInstalled(Context context, String clientPackageName) {
if (context != null && !TextUtils.isEmpty(clientPackageName)) {
boolean TapTapInstalled = false;
try {
PackageInfo packageInfo = context.getPackageManager().getPackageInfo(clientPackageName, 0);
if (null != packageInfo) {
TapTapInstalled = true;
}
} catch (Exception e) {
Log.e(TAG, clientPackageName + " isInstalled=false");
}
return TapTapInstalled;
}
return false;
}

public static boolean updateGameInTapTap(Activity activity, String appId) {
return updateGameInTapClient(activity, appId, CLIENT_URI_TAPTAP);
}

public static boolean updateGameInTapClient(Activity activity, String appId, String clientUri) {
if (activity != null && !TextUtils.isEmpty(appId) && !TextUtils.isEmpty(clientUri)) {
try {
Uri uri = Uri.parse(String.format(Locale.US,
"%s/app?app_id=%s&source=outer|update", clientUri, appId));
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
activity.startActivity(intent);
} catch (Exception e) {
Log.e(TAG, clientUri + "updateGameInTapTap failed");
return false;
}
return true;
}
Log.e(TAG, clientUri + "updateGameInTapTap failed");
return false;
}

public static boolean openReviewInTapTap(Activity activity, String appId) {
return openReviewInTapClient(activity, appId, CLIENT_URI_TAPTAP);
}

public static boolean openReviewInTapClient(Activity activity, String appId, String clientUri) {
if (activity != null && !TextUtils.isEmpty(appId) && !TextUtils.isEmpty(clientUri)) {
try {
Uri uri = Uri.parse(String.format(Locale.US,
"%s/app?tab_name=review&app_id=%s", clientUri, appId));
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
activity.startActivity(intent);
} catch (Exception e) {
Log.e(TAG, clientUri + "openTapTapReview failed");
return false;
}
return true;
}
Log.e(TAG, clientUri + "openTapTapReview failed");
return false;
}

public static boolean openWebDownloadUrlOfTapTap(Activity activity, String appId) {
return openWebDownloadUrl(activity, String.format(Locale.US, DEFAULT_CLIENT_DOWNLOAD_URL_TAPTAP + "?subc1=%s", appId));
}

public static boolean openWebDownloadUrl(Activity activity, String url) {
if (activity != null && !TextUtils.isEmpty(url)) {
try {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setData(Uri.parse(url));
activity.startActivity(intent);
} catch (Exception e) {
Log.e(TAG, "openWebUrl fail");
return false;
}
return true;
}
return false;
}

}

For other countries/regions:

package com.tds.common.utils;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;
import java.util.Locale;

public class TapGameUtil {

private static final String TAG = TapGameUtil.class.getName();

public static final String PACKAGE_NAME_TAPTAP_GLOBAL = "com.taptap.global";

public static final String CLIENT_URI_TAPTAP_GLOBAL = "tapglobal://taptap.tw";

public static final String DEFAULT_CLIENT_DOWNLOAD_URL_TAPTAP_GLOBAL = "https://l.taptap.io/GNYwFaZr";

public static boolean updateGameAndFailToWebInTapGlobal(Activity activity, String appId) {
return updateGameInTapGlobal(activity, appId) || openWebDownloadUrlOfTapGlobal(activity, appId);
}

public static boolean updateGameAndFailToWebInTapGlobal(Activity activity, String appId, String webUrl) {
if (TextUtils.isEmpty(webUrl)) {
return updateGameAndFailToWebInTapGlobal(activity, appId);
}
return updateGameInTapGlobal(activity, appId) || openWebDownloadUrl(activity, webUrl);
}

public static boolean isTapGlobalInstalled(Context context) {
return isTapClientInstalled(context, PACKAGE_NAME_TAPTAP_GLOBAL);
}

public static boolean isTapClientInstalled(Context context, String clientPackageName) {
if (context != null && !TextUtils.isEmpty(clientPackageName)) {
boolean TapTapInstalled = false;
try {
PackageInfo packageInfo = context.getPackageManager().getPackageInfo(clientPackageName, 0);
if (null != packageInfo) {
TapTapInstalled = true;
}
} catch (Exception e) {
Log.e(TAG, clientPackageName + " isInstalled=false");
}
return TapTapInstalled;
}
return false;
}

public static boolean updateGameInTapGlobal(Activity activity, String appId) {
return updateGameInTapClient(activity, appId, CLIENT_URI_TAPTAP_GLOBAL);
}

public static boolean updateGameInTapClient(Activity activity, String appId, String clientUri) {
if (activity != null && !TextUtils.isEmpty(appId) && !TextUtils.isEmpty(clientUri)) {
try {
Uri uri = Uri.parse(String.format(Locale.US,
"%s/app?app_id=%s&source=outer|update", clientUri, appId));
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
activity.startActivity(intent);
} catch (Exception e) {
Log.e(TAG, clientUri + "updateGameInTapTap failed");
return false;
}
return true;
}
Log.e(TAG, clientUri + "updateGameInTapTap failed");
return false;
}

public static boolean openReviewInTapGlobal(Activity activity, String appId) {
return openReviewInTapClient(activity, appId, CLIENT_URI_TAPTAP_GLOBAL);
}

public static boolean openReviewInTapClient(Activity activity, String appId, String clientUri) {
if (activity != null && !TextUtils.isEmpty(appId) && !TextUtils.isEmpty(clientUri)) {
try {
Uri uri = Uri.parse(String.format(Locale.US,
"%s/app?tab_name=review&app_id=%s", clientUri, appId));
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
activity.startActivity(intent);
} catch (Exception e) {
Log.e(TAG, clientUri + "openTapTapReview failed");
return false;
}
return true;
}
Log.e(TAG, clientUri + "openTapTapReview failed");
return false;
}

public static boolean openWebDownloadUrlOfTapGlobal(Activity activity, String appId) {
return openWebDownloadUrl(activity, String.format(Locale.US, DEFAULT_CLIENT_DOWNLOAD_URL_TAPTAP_GLOBAL + "?subc1=%s", appId));
}

public static boolean openWebDownloadUrl(Activity activity, String url) {
if (activity != null && !TextUtils.isEmpty(url)) {
try {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setData(Uri.parse(url));
activity.startActivity(intent);
} catch (Exception e) {
Log.e(TAG, "openWebUrl fail");
return false;
}
return true;
}
return false;
}

}