如何在Android应用内获取用户的Google Play所属国家?
Hey there! This is a super common pain point for Google Play developers, especially when it comes to staying compliant with Play Store policies. Your issue—showing a guessed region-based price that doesn't align with what Google displays during checkout—definitely risks policy flags, but there's an official, foolproof solution now that replaces those old, unreliable workarounds from 8 years ago.
Core Idea: Skip Guessing—Get the Exact Price Google Will Use
Instead of maintaining your own region-to-price mapping and guessing the user's location, let the Google Play Billing Library directly return the price tailored to the user's Play Store account. This is exactly the price Google will show during the payment flow, so you eliminate the mismatch entirely.
Step-by-Step Implementation (Using Billing Library 6.x, the Latest Stable Version)
Integrate the Latest Billing Library
First, add the latest library to your project dependencies (6.x is recommended for full policy compliance):dependencies { implementation "com.android.billingclient:billing:6.1.0" }Set Up and Connect the BillingClient
Establish a connection to Google's billing service—this is required to fetch user-specific pricing data:val billingClient = BillingClient.newBuilder(context) .setListener { billingResult, purchases -> // Handle purchase callbacks here (optional for pricing fetch) } .enablePendingPurchases() .build() billingClient.startConnection(object : BillingClientStateListener { override fun onBillingSetupFinished(billingResult: BillingResult) { if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) { // Connection successful—now fetch product details fetchUserSpecificPricing() } } override fun onBillingServiceDisconnected() { // Handle disconnection (e.g., retry connection) } })Fetch Product Details for User-Specific Pricing
UsequeryProductDetailsAsyncto get the exact price Google will display for the user. The returnedProductDetailsobject includes the formatted price and currency code tied to their Play Store account:private fun fetchUserSpecificPricing() { val productParams = listOf( QueryProductDetailsParams.Product.newBuilder() .setProductId("your_inapp_product_id") .setProductType(BillingClient.ProductType.INAPP) // Use SUBS for subscriptions .build() ) val queryParams = QueryProductDetailsParams.newBuilder() .setProductList(productParams) .build() billingClient.queryProductDetailsAsync(queryParams) { billingResult, productDetailsList -> if (billingResult.responseCode == BillingClient.BillingResponseCode.OK && productDetailsList.isNotEmpty()) { val targetProduct = productDetailsList.first() // Get the ready-to-display price (includes currency symbol, e.g., "$9.99") val checkoutPrice = targetProduct.oneTimePurchaseOption?.priceInfo?.formattedPrice // Get the currency code (e.g., "USD", "EUR") if you need region context val currencyCode = targetProduct.oneTimePurchaseOption?.priceInfo?.priceCurrencyCode // Display checkoutPrice directly to the user—this matches what Google will show! } } }
If You Need the Exact Billing Region
While using the direct price is the most reliable approach, if you need explicit region data:
- Use the
priceCurrencyCodefromPriceInfoto map to regions (note: some currencies apply to multiple regions, so adjust logic accordingly). - For subscriptions, the same logic applies—check
SubscriptionOfferDetailsfor the user-specific price and currency.
What About Those Old 8-Year-Old Workarounds?
Back then, developers relied on IP geolocation or device locale guesses, but those are unreliable because Google's billing region is based on the user's Play Store account settings, not their IP or device language. The Billing Library is the only official method that guarantees alignment with Google's region determination, so it's the only way to stay compliant.
内容的提问来源于stack exchange,提问作者dgarg

