Menu

Resume Installation

Introduction

Prerequisite: Android SDK v6.2.85 and above, only supported for China-region SDK.

Supported Ad Platforms: Currently only supports the Topon ADX platform.

Resume Installation Introduction: After users click on app-type ads, they download the APK from the ad. Since the current Android installation chain is relatively long, there may be some APKs that have been downloaded but not yet installed. Through the Resume Installation reminder API, developers can obtain valid APKs for prompting, allowing users to choose whether to continue the installation, thereby improving the app installation rate.

Activation Popup Reminder Introduction: During user interaction with ads, there may be situations where the app has been downloaded but not installed, or installed but not opened. At this point, users can be prompted via a popup to maximize ad revenue. This feature is an upgrade of the Resume Installation reminder feature. Developers do not need to handle specific logic for app parsing and popups. Just calling the API allows popups to remind users to complete installation or activation at specified times.

Applicable Scenarios: The Resume Installation method and Activation Popup Reminder are recommended to be used when the user exits the app, or while the user is browsing or using the app, without affecting the user experience.

API Instructions

ATChinaSDKHandler

Used to obtain the ATApkManager object. Must be called after SDK Initialization.

Method Name Method Description
getATApkManager(Context context) context refers to the context. The developer's Activity must be passed here. This method can only be called after SDK Initialization, otherwise it will return null.

ATApkManager

ATAPK data management class, used to obtain APK data and then perform installation.

Method Name Method Description
showOpenOrInstallAppDialog(ATApkDialogClickListener dialogClickListener) Through this API, you can check for apps that have been downloaded via the ad SDK but not installed, or installed but not activated. A popup prompts the user to install or open/activate. Repeatedly calling this API will cyclically return apps not installed or installed but not activated in chronological order.
setApkListener(ATApkListener apkListener) Set the callback for loading ATApk.
loadApk() Load ATApk data. Only one ATApk can be obtained per call. Repeatedly calling this API will cyclically return apps not installed in chronological order.
startInstall(ATApk apk) Pass the ATApk data obtained from loadApk() to call the system installer for installation.

ATApkDialogClickListener

Activation Popup Reminder: The listener passed when calling the showOpenOrInstallAppDialog method. Developers need to implement the corresponding interface.

Method Name Method Description
onShowResult(int resultType) When this method is called back, the returned parameter values are: ATApkDialogClickListener.NO_DLG: No apps available to install or activate.

ATApkDialogClickListener.INSTALL_APP_DLG: Popup prompts the user to install the app.

ATApkDialogClickListener.OPEN_APP_DLG: Popup prompts the user to open and activate the app.
onButtonClick(int clickType) When this method is called back, the returned parameter values are: ATApkDialogClickListener.CONFIRM_BUTTON: After the popup, the user clicked confirm.

ATApkDialogClickListener.CANCEL_BUTTON: After the popup, the user clicked cancel.

ATApkListener

Resume Installation: Before calling the loadApk method to obtain GDTAPK data, call the setApkListener method and pass this listener to listen for ATApk data retrieval.

Method Name Method Description
onApkLoad(ATApk apk) When this method is called back, ATApk data is returned.
onError(String code, String msg, String networkFirmId) When this method is called back, it provides some error messages related to obtaining ATApk data. code: Error code. 60001 indicates that there are currently no APKs pending installation. 60002 indicates that an exception occurred while obtaining the installation list. msg: Error message. networkFirmId: Ad platform ID.

ATApk

Resume Installation: The data class returned by the ATApkListener interface, ATApk.

Method Name Method Description
getPackageName() Get the package name of the app ad.
getTitle() Get the title of the app ad.
getDesc() Get the description info of the app ad.
getAppName() Get the name of the app ad.
getLogoUrl() Get the icon address of the app ad.

Integration Notes

  1. The method callbacks for both the ATApkDialogClickListener and ATApkListener interfaces are executed on the main thread.
  2. For the showOpenOrInstallAppDialog method, it is recommended for developers to prompt when the user exits the app. It can also be called in any scenario.

Integration Code Sample

Copy
/**
 * When calling the system installer {@link com.anythink.china.api.ATApkManager#startInstall(com.anythink.china.api.ATApk)},
 * the interface will redirect to the installer interface. At this point, we do not provide a callback for whether the APK file installation has completed or failed.
 *
 * Therefore, developers can use the lifecycle callbacks of Activity or Fragment, combined with their own business logic, to make correct displays.
 *
 * For example, in an Activity, redirecting from the current app to the system installer interface will call back onPause() -> onStop();
 * Returning from the system installer interface to the app will call back onRestart() -> onStart() -> onResume().
 *
 * When the interface returns from the system installer, you can update the view by checking whether the APK has been installed {@link #isAPKInstalled(android.content.Context, java.lang.String)}.
 */
public class DownloadApkManagerActivity extends Activity implements View.OnClickListener {
    private static final String TAG = DownloadApkManagerActivity.class.getSimpleName();

    private ATApkManager mApkManager;
    private ATApk mApk;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_download_apk_manager);

        mApkManager = ATChinaSDKHandler.getATApkManager(this);
        initListener();
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.d(TAG, "onStart");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.d(TAG, "onResume");
        if (mApk != null && isAPKInstalled(this, mApk.getPackageName())) {
            // Update your view
            Log.i(TAG, "APK file has been installed, you can update your view.");
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.d(TAG, "onPause");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.d(TAG, "onStop");
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        Log.d(TAG, "onRestart");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy");
    }

    @Override
    public void onBackPressed() {
        showOpenOrInstallAppDialog(true);
    }

    private void initListener() {
        findViewById(R.id.bt_show_apk_dialog).setOnClickListener(this);
        findViewById(R.id.bt_load_apk).setOnClickListener(this);
        findViewById(R.id.bt_install_apk).setOnClickListener(this);

        if (mApkManager != null) {
            mApkManager.setApkListener(new ATApkListener() {
                @Override
                public void onApkLoad(ATApk apk) {
                    if (apk != null) {
                        DownloadApkManagerActivity.this.mApk = apk;
                        Log.d(TAG, "onApkLoad() >>> title: " + apk.getTitle() + " desc: " + apk.getDesc() + " appName: " + apk.getAppName() +
                                " packageName: " + apk.getPackageName() + " logoUrl: " + apk.getLogoUrl());
                    } else {
                        Log.d(TAG, "apk is null.");
                    }
                }

                @Override
                public void onError(String code, String msg, String networkFirmId) {
                    Log.e(TAG, "onError() >>> code: " + code + " msg: " + msg + " networkFirmId: " + networkFirmId);
                }
            });
        }
    }

    @Override
    public void onClick(View v) {
        if (mApkManager == null) {
            return;
        }
        int viewId = v.getId();
        if (viewId == R.id.bt_show_apk_dialog) {
            // Click button for activation popup reminder
            showOpenOrInstallAppDialog(false);
        } else if (viewId == R.id.bt_load_apk) {
            mApkManager.loadApk();
        } else {
            if (mApk != null) {
                mApkManager.startInstall(mApk);
            } else {
                Log.e(TAG, "apk is null, can not start install.");
            }
        }
    }

    private void showOpenOrInstallAppDialog(boolean isFromBackPress) {
        if (mApkManager != null) {
            mApkManager.showOpenOrInstallAppDialog(new ATApkDialogClickListener() {
                @Override
                public void onShowResult(int resultType) {
                    Log.d(TAG, "onShowResult() >>> resultType: " + resultType);
                    if (resultType == ATApkDialogClickListener.NO_DLG) {
                        if (isFromBackPress) {
                            finish();
                        } else {
                            Toast.makeText(DownloadApkManagerActivity.this, "No apps available to install or activate.", Toast.LENGTH_SHORT).show();
                        }
                    }
                }

                @Override
                public void onButtonClick(int clickType) {
                    Log.d(TAG, "onButtonClick() >>> clickType: " + clickType);
                    if (isFromBackPress) {
                        finish();
                    };
                }
            });
        }
    }

    /**
     * This method is used to determine whether an APK has been installed.
     * @param context
     * @param pkgName
     * @return
     */
    private boolean isAPKInstalled(Context context, String pkgName) {
        if (TextUtils.isEmpty(pkgName)) {
            return false;
        }
        PackageManager pm = context.getPackageManager();
        try {
            PackageInfo packageInfo = pm.getPackageInfo(pkgName, PackageManager.GET_GIDS);
            return packageInfo != null;
        } catch (Throwable e) {
            return false;
        }
    }
}
Previous
Splash Ad
Next
Multiple Loaded Callbacks
Last modified: 2026-07-08Powered by