メインコンテンツまでスキップ

Sign in to Aptoide Services (Android SDK)

Signing in to Aptoide Services links the user's purchases to their Aptoide account. Once signed in, their pending and non-consumable purchases are retrievable via queryPurchasesAsync even after the host app's storage is cleared or the user switches devices - no backend is required on your side.

📘
Feature availability

Account sign-in is remotely toggled and is off by default. Verify it is available before exposing it with billingClient.isFeatureSupported(FeatureType.ACCOUNT_SIGN_IN) (a response code of OK means it is enabled; SERVICE_UNAVAILABLE means the configuration is still loading - retry).

Sign in

Use signInToAptoideServices to launch the Aptoide account sign-in flow. It is asynchronous: the outcome is delivered to the AptoideSignInResponseListener as a BillingResult. Call it after the SDK connection is established (for example from a "Sign in" button).

fun signIn(activity: Activity) {
billingClient.signInToAptoideServices(activity) { billingResult ->
runOnUiThread {
when (billingResult.responseCode) {
BillingResponseCode.OK -> restoreOwnedPurchases() // signed in (or already signed in)
BillingResponseCode.USER_CANCELED -> Log.i(TAG, "Sign-in dismissed by the user")
BillingResponseCode.FEATURE_NOT_SUPPORTED -> Log.i(TAG, "Sign-in is disabled")
BillingResponseCode.SERVICE_UNAVAILABLE -> Log.i(TAG, "Not ready yet - retry shortly")
else -> Log.e(TAG, "Sign-in error: ${billingResult.debugMessage}")
}
}
}
}

The response codes returned to the listener are:

Response codeMeaning
OKThe user signed in, or was already signed in. Proceed to query owned purchases.
USER_CANCELEDThe user dismissed the sign-in screen or chose "don't show again".
FEATURE_NOT_SUPPORTEDAccount sign-in is disabled (feature flag off).
SERVICE_UNAVAILABLEThe configuration is still loading (or failed to load) - retryable.
ERRORAn unexpected error occurred.

On OK, query the owned purchases to restore the entitlements (the result includes acknowledged non-consumables - see Acknowledge a non-consumable purchase):

private fun restoreOwnedPurchases() {
billingClient.queryPurchasesAsync(
QueryPurchasesParams.newBuilder()
.setProductType(ProductType.INAPP)
.build()
) { billingResult, purchases ->
if (billingResult.responseCode == BillingResponseCode.OK) {
purchases.forEach { grantEntitlement(it) }
}
}
}
📘
Note

The sign-in screen is shown sparingly by the SDK (it is rate-limited and offers the user a "don't show again" option), so calling signInToAptoideServices is safe - it simply returns without showing the screen when appropriate.

Check the current sign-in state

Use isSignedInToAptoideServices to read the current state synchronously - for example, to decide whether to show a "Sign in" or "Log out" button when a screen opens.

val signedIn = billingClient.isSignedInToAptoideServices()

Listen for sign-in state changes

Sign-in and sign-out can also happen inside the payment WebView. Register an AptoideAccountStateListener on the builder to be notified of any state change, so you can refresh your UI and re-query purchases without the user restarting the app. The state is one of AccountState: SIGNED_IN or SIGNED_OUT. It is only fired on an actual state transition.

billingClient = AptoideBillingClient.newBuilder(context)
.setListener(purchasesUpdatedListener)
.setAccountStateListener { state ->
runOnUiThread {
when (state) {
AccountState.SIGNED_IN -> restoreOwnedPurchases()
AccountState.SIGNED_OUT -> revokeAccountEntitlements()
}
}
}
.setPublicKey(publicKey)
.build()

Sign out

Use signOutFromAptoideServices to sign the user out. It clears the stored session and reverts all subsequent operations to the anonymous guest flow. Any registered AptoideAccountStateListener is notified with AccountState.SIGNED_OUT.

billingClient.signOutFromAptoideServices()