Android Google 支付账单 - 响应 4:ITEM_UNAVAILABLE
Android Google Pay Billing - Response 4 : ITEM_UNAVAILABLE
我正在尝试集成 Google Play Billing。
这是我的 onCreate :
private final static String TAG = "MainActivity" ;
private final static String ITEM_SKU_SUBSCRIBE = "sub_example" ;
private final static String PREF_FILE = "shared_prefs" ;
private final static String SUBSCRIBE_KEY = "subscribe" ;
private BillingClient billingClient ;
private TextView premiumContent ;
private TextView subscriptionStatus ;
private Button purchaseButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
premiumContent = findViewById(R.id.premium_content) ;
subscriptionStatus = findViewById(R.id.subscription_status) ;
purchaseButton = findViewById(R.id.button) ;
billingClient = BillingClient.newBuilder(this)
.enablePendingPurchases()
.setListener(this)
.build() ;
billingClient.startConnection(new BillingClientStateListener() {
@Override
public void onBillingSetupFinished(BillingResult billingResult) {
Log.i(TAG, "onBillingSetupFinished ; billing response code == " + billingResult.getResponseCode());
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
Purchase.PurchasesResult queryPurchase = billingClient.queryPurchases(SUBS);
List<Purchase> queryPurchases = queryPurchase.getPurchasesList();
if (queryPurchases != null && queryPurchases.size() > 0) {
handlePurchases(queryPurchases);
} else {
saveSubscribeValueToPref(false);
}
} else {
Log.e(TAG, "ELSE : " + billingResult.getDebugMessage()) ;
}
}
@Override
public void onBillingServiceDisconnected() {
Toast.makeText(getApplicationContext(), "Service disconnected",
Toast.LENGTH_SHORT).show() ;
}
});
if (getSubscribeValueFromPref()) {
purchaseButton.setVisibility(View.GONE);
premiumContent.setVisibility(View.VISIBLE);
subscriptionStatus.setText("Subscription Status : Subscribed");
} else {
premiumContent.setVisibility(View.GONE);
purchaseButton.setVisibility(View.VISIBLE);
subscriptionStatus.setText("Subscription Status : Not Subscribed");
}
purchaseButton.setText("Load products");
purchaseButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
subscribe();
}
});
}
当我点击 purchaseButton
时,我调用 subscribe
函数。
如果billingClient.isReady()
returns true
,基本上它只是调用一个函数initiatePurchase
,在其他情况下初始化billingClient
。
这是我的 initiatePurchase
函数:
private void initiatePurchase() {
List<String> skuList = new ArrayList<>() ;
SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder() ;
skuList.add(ITEM_SKU_SUBSCRIBE);
params.setSkusList(skuList).setType(SUBS);
BillingResult billingResult = billingClient.isFeatureSupported(BillingClient.FeatureType.SUBSCRIPTIONS) ;
Log.i(TAG, "Billing response code == " + billingResult.getResponseCode()) ;
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
Log.i(TAG, "Billing response code is OK");
billingClient.querySkuDetailsAsync(params.build(),
new SkuDetailsResponseListener() {
@Override
public void onSkuDetailsResponse(BillingResult billingResult, List<SkuDetails> skuDetailsList) {
Log.i(TAG, "onSkuDetailsResponse ; billing result response code == " + billingResult.getResponseCode());
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
Log.i(TAG, "Billing response code OK") ;
if (skuDetailsList != null) {
for (int i = 0 ; i < skuDetailsList.size() ; i++) {
Log.i(TAG, "Loop INDEX " + i + " ; SkuDetails == " + skuDetailsList.get(i).getTitle()) ;
}
}
if (skuDetailsList != null && skuDetailsList.size() > 0) {
Log.i(TAG, "skuDetailsList is not null or empty");
BillingFlowParams flowParams = BillingFlowParams.newBuilder()
.setSkuDetails(skuDetailsList.get(0))
.build();
Log.i(TAG, "Flow Params = " + flowParams.getAccountId() + " | " + flowParams.getSku());
BillingResult billingFlowResult = billingClient
.launchBillingFlow(MainActivity.this, flowParams);
Log.i(TAG, "billingFlowResult == " + billingFlowResult.getResponseCode() + " | " + billingFlowResult.getDebugMessage()) ;
} else {
Toast.makeText(getApplicationContext(),
"Item not found", Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(getApplicationContext(),
"Error - " + billingResult.getDebugMessage(),
Toast.LENGTH_SHORT).show();
}
}
});
} else {
Toast.makeText(getApplicationContext(),
"Sorry, subscription not supported. Please update Play Store",
Toast.LENGTH_SHORT).show();
}
}
似乎转到 onSkuDetailsResponse
,结算响应代码正常。
我在 skuDetailsList
中循环并得到 sub_example
,这是我的 ITEM_SKU_SUBSCRIBE
(以及我的 Play 商店控制台上的那个);所以我的 skuDetailsList
不是 null 或空的。
但是,这是我的日志输出:
I/MainActivity: Billing response code == 0
Billing response code is OK
I/MainActivity: onSkuDetailsResponse ; billing result response code == 0
Billing response code OK
Loop INDEX 0 ; SkuDetails == Monthly sub (Test Billing)
skuDetailsList is not null or empty
I/MainActivity: Flow Params = null | sub_example
I/MainActivity: billingFlowResult == 0 | null
W/ActivityThread: handleWindowVisibility: no activity for token android.os.BinderProxy@cb159f0
当我点击 "OK" 按钮时,会出现有趣的日志:
W/ProxyBillingActivity: Activity finished with resultCode 0 and billing's responseCode: 4
W/BillingHelper: Couldn't find purchase lists, trying to find single data.
W/BillingHelper: Received a bad purchase data.
Couldn't find single purchase data as well.
我在 BillingClient.class
中查找并在 interface BillingResponseCode
中找到了 int ITEM_UNAVAILABLE = 4;
- 我正在以签名发布配置编译和启动此应用程序
- 该应用程序的旧版本在 Google Play 上以 alpha 发布(但具有相同的版本代码和版本名称)
- 我的 google play 帐户在测试人员列表中,它是我今天为此创建的 @gmail 地址(我的另一个 google 帐户没有 @gmail 地址 - 嗯,没有要么工作)
- 我昨天在 Google Play 管理中心
创建了这个订阅
- 我的应用程序从昨天开始在 alpha 版中发布(未在审核中)。
- 我遵循了这个教程:https://programtown.com/how-to-make-in-app-purchase-subscription-in-android-using-google-play-billing-library/
谢谢
看来只能等了...
今天早上成功了。
计算 2 天后您的应用内付款将在应用上可用。
我正在尝试集成 Google Play Billing。
这是我的 onCreate :
private final static String TAG = "MainActivity" ;
private final static String ITEM_SKU_SUBSCRIBE = "sub_example" ;
private final static String PREF_FILE = "shared_prefs" ;
private final static String SUBSCRIBE_KEY = "subscribe" ;
private BillingClient billingClient ;
private TextView premiumContent ;
private TextView subscriptionStatus ;
private Button purchaseButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
premiumContent = findViewById(R.id.premium_content) ;
subscriptionStatus = findViewById(R.id.subscription_status) ;
purchaseButton = findViewById(R.id.button) ;
billingClient = BillingClient.newBuilder(this)
.enablePendingPurchases()
.setListener(this)
.build() ;
billingClient.startConnection(new BillingClientStateListener() {
@Override
public void onBillingSetupFinished(BillingResult billingResult) {
Log.i(TAG, "onBillingSetupFinished ; billing response code == " + billingResult.getResponseCode());
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
Purchase.PurchasesResult queryPurchase = billingClient.queryPurchases(SUBS);
List<Purchase> queryPurchases = queryPurchase.getPurchasesList();
if (queryPurchases != null && queryPurchases.size() > 0) {
handlePurchases(queryPurchases);
} else {
saveSubscribeValueToPref(false);
}
} else {
Log.e(TAG, "ELSE : " + billingResult.getDebugMessage()) ;
}
}
@Override
public void onBillingServiceDisconnected() {
Toast.makeText(getApplicationContext(), "Service disconnected",
Toast.LENGTH_SHORT).show() ;
}
});
if (getSubscribeValueFromPref()) {
purchaseButton.setVisibility(View.GONE);
premiumContent.setVisibility(View.VISIBLE);
subscriptionStatus.setText("Subscription Status : Subscribed");
} else {
premiumContent.setVisibility(View.GONE);
purchaseButton.setVisibility(View.VISIBLE);
subscriptionStatus.setText("Subscription Status : Not Subscribed");
}
purchaseButton.setText("Load products");
purchaseButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
subscribe();
}
});
}
当我点击 purchaseButton
时,我调用 subscribe
函数。
如果billingClient.isReady()
returns true
,基本上它只是调用一个函数initiatePurchase
,在其他情况下初始化billingClient
。
这是我的 initiatePurchase
函数:
private void initiatePurchase() {
List<String> skuList = new ArrayList<>() ;
SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder() ;
skuList.add(ITEM_SKU_SUBSCRIBE);
params.setSkusList(skuList).setType(SUBS);
BillingResult billingResult = billingClient.isFeatureSupported(BillingClient.FeatureType.SUBSCRIPTIONS) ;
Log.i(TAG, "Billing response code == " + billingResult.getResponseCode()) ;
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
Log.i(TAG, "Billing response code is OK");
billingClient.querySkuDetailsAsync(params.build(),
new SkuDetailsResponseListener() {
@Override
public void onSkuDetailsResponse(BillingResult billingResult, List<SkuDetails> skuDetailsList) {
Log.i(TAG, "onSkuDetailsResponse ; billing result response code == " + billingResult.getResponseCode());
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
Log.i(TAG, "Billing response code OK") ;
if (skuDetailsList != null) {
for (int i = 0 ; i < skuDetailsList.size() ; i++) {
Log.i(TAG, "Loop INDEX " + i + " ; SkuDetails == " + skuDetailsList.get(i).getTitle()) ;
}
}
if (skuDetailsList != null && skuDetailsList.size() > 0) {
Log.i(TAG, "skuDetailsList is not null or empty");
BillingFlowParams flowParams = BillingFlowParams.newBuilder()
.setSkuDetails(skuDetailsList.get(0))
.build();
Log.i(TAG, "Flow Params = " + flowParams.getAccountId() + " | " + flowParams.getSku());
BillingResult billingFlowResult = billingClient
.launchBillingFlow(MainActivity.this, flowParams);
Log.i(TAG, "billingFlowResult == " + billingFlowResult.getResponseCode() + " | " + billingFlowResult.getDebugMessage()) ;
} else {
Toast.makeText(getApplicationContext(),
"Item not found", Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(getApplicationContext(),
"Error - " + billingResult.getDebugMessage(),
Toast.LENGTH_SHORT).show();
}
}
});
} else {
Toast.makeText(getApplicationContext(),
"Sorry, subscription not supported. Please update Play Store",
Toast.LENGTH_SHORT).show();
}
}
似乎转到 onSkuDetailsResponse
,结算响应代码正常。
我在 skuDetailsList
中循环并得到 sub_example
,这是我的 ITEM_SKU_SUBSCRIBE
(以及我的 Play 商店控制台上的那个);所以我的 skuDetailsList
不是 null 或空的。
但是,这是我的日志输出:
I/MainActivity: Billing response code == 0
Billing response code is OK
I/MainActivity: onSkuDetailsResponse ; billing result response code == 0
Billing response code OK
Loop INDEX 0 ; SkuDetails == Monthly sub (Test Billing)
skuDetailsList is not null or empty
I/MainActivity: Flow Params = null | sub_example
I/MainActivity: billingFlowResult == 0 | null
W/ActivityThread: handleWindowVisibility: no activity for token android.os.BinderProxy@cb159f0
当我点击 "OK" 按钮时,会出现有趣的日志:
W/ProxyBillingActivity: Activity finished with resultCode 0 and billing's responseCode: 4
W/BillingHelper: Couldn't find purchase lists, trying to find single data.
W/BillingHelper: Received a bad purchase data.
Couldn't find single purchase data as well.
我在 BillingClient.class
中查找并在 interface BillingResponseCode
int ITEM_UNAVAILABLE = 4;
- 我正在以签名发布配置编译和启动此应用程序
- 该应用程序的旧版本在 Google Play 上以 alpha 发布(但具有相同的版本代码和版本名称)
- 我的 google play 帐户在测试人员列表中,它是我今天为此创建的 @gmail 地址(我的另一个 google 帐户没有 @gmail 地址 - 嗯,没有要么工作)
- 我昨天在 Google Play 管理中心 创建了这个订阅
- 我的应用程序从昨天开始在 alpha 版中发布(未在审核中)。
- 我遵循了这个教程:https://programtown.com/how-to-make-in-app-purchase-subscription-in-android-using-google-play-billing-library/
谢谢
看来只能等了...
今天早上成功了。
计算 2 天后您的应用内付款将在应用上可用。