Last active
March 15, 2021 22:21
-
-
Save adammagana/916b38e1e8c9081caccc7bea9d441e73 to your computer and use it in GitHub Desktop.
An Android SkuDetails property extension that calculates price-per-month.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import com.android.billingclient.api.SkuDetails | |
import java.lang.Exception | |
import java.text.NumberFormat | |
import java.util.* | |
/** | |
* Currency code for the U.S. dollar | |
*/ | |
private const val USD = "USD" | |
/** | |
* Uses [SkuDetails.getSubscriptionPeriod], [SkuDetails.getOriginalPriceAmountMicros], | |
* [SkuDetails.getPriceCurrencyCode], and the device's default locale to calculate and format the | |
* price per month from the given subscription's "original" price. | |
* | |
* "Original" price is defined in the SDK as "before any applicable sales have been applied." | |
* | |
* @return Null if [SkuDetails.getSubscriptionPeriod] does not match a supported ISO 8601 formatted | |
* string (i.e. the value is absent/null). | |
* @see SkuDetails | |
*/ | |
val SkuDetails.pricePerMonth: String? | |
get() { | |
// Bail early if we know that we can't derive a subscription from the SkuDetails. This value | |
// is expected to be absent for non-subscription products. | |
if (this.subscriptionPeriod.isNullOrBlank()) { | |
return null | |
} | |
val originalPriceAmountMicros: Float = this.originalPriceAmountMicros.toFloat() | |
// `subscriptionPeriod` produces an ISO 8601 formatted string. Only check against the | |
// relevant strings specified by the `BillingClient` API. | |
val rawPricePerMonth: Float = when (this.subscriptionPeriod) { | |
"P1Y" -> originalPriceAmountMicros / 12_000_000 // 12 month period | |
"P6M" -> originalPriceAmountMicros / 6_000_000 // 6 month period | |
"P3M" -> originalPriceAmountMicros / 3_000_000 // 3 month period | |
"P1M" -> originalPriceAmountMicros / 1_000_000 // 1 month period | |
else -> return null | |
} | |
// Use the device's locale and the SkuDetail's currency code to produce a string that | |
// represents the calculated monthly price. | |
val numberFormat = NumberFormat.getCurrencyInstance(Locale.getDefault()) | |
numberFormat.currency = try { | |
Currency.getInstance(this.priceCurrencyCode) | |
} catch (ex: Exception) { | |
// Protect against null currency codes as well as a codes that aren't a valid ISO 4217 | |
// string. Fallback to USD in this case. | |
Currency.getInstance(USD) | |
} | |
return numberFormat.format(rawPricePerMonth) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment