android-jetpack-composein-app-purchaseonactivityresultstartactivityforresulthuawei-iap

How to handle HUAWEI In-App Purchase in Jetpack Compose with Legacy SDK?


I'm currently migrating a mobile application from the traditional Activity/XML approach to Jetpack Compose. As part of this migration, I'm facing a challenge with integrating HUAWEI In-App Purchase services.

The HUAWEI In-App Purchase SDK (which hasn't been updated since 2023) requires using Status.startResolutionForResult(Activity activity, int requestCode) to initiate an in-app purchase and handling the result in the Activity's onActivityResult method.

Given that Jetpack Compose promotes a single-activity architecture, I'm exploring ways to handle the result directly within a Composable function. I've attempted to use rememberLauncherForActivityResult with the ActivityResultContracts.StartActivityForResult contract:

val iapStatusForResult = rememberLauncherForActivityResult(ActivityResultContracts.StartActivityForResult()) {

}

However, the iapStatusForResult.launch method expects an Intent as input. Unfortunately, the Status.startResolutionForResult method doesn't return an Intent and directly launches the startActivityForResult or startIntentSenderForResult method internally using the provided Activity instance.

Note the intent used internally by this class is a private field.

The only solution I have in mind now is to use reflection to modifty the visibility of the Intent field in the Status class to access it directly and use it in my composable.

This is a less-than-ideal solution due to its potential fragility and reliance on internal implementation details.

I'm open to suggestions and alternative approaches that might be more suitable for handling this specific scenario. Any insights or workarounds would be greatly appreciated.


Solution

  • Exploring the Status class from the SDK, I found that two methods are exposed in order to retrieve the intent and the pendingIntent fields used internally in order to launch in in-app purchase.

    So using it, I just need to re-implement the logic of the startResolutionForResultmethod of the SDK by using the rememberLauncherForActivityResult function with the ActivityResultContracts.StartActivityForResult() contract or the ActivityResultContracts.StartIntentSenderForResult() according to the situation.