|
15 | 15 |
|
16 | 16 | package com.alexdisler.inapppurchases; |
17 | 17 |
|
| 18 | +import java.util.ArrayList; |
| 19 | +import java.util.List; |
| 20 | +import java.util.Set; |
| 21 | +import java.util.TreeSet; |
| 22 | + |
| 23 | +import android.content.pm.ResolveInfo; |
| 24 | + |
| 25 | +import org.json.JSONException; |
18 | 26 | import android.app.Activity; |
19 | 27 | import android.app.PendingIntent; |
20 | 28 | import android.content.ComponentName; |
|
71 | 79 | * |
72 | 80 | */ |
73 | 81 | public class IabHelper { |
| 82 | + |
| 83 | + public static final int QUERY_SKU_DETAILS_BATCH_SIZE = 20; |
| 84 | + |
74 | 85 | // Is debug logging enabled? |
75 | 86 | boolean mDebugLog = false; |
76 | 87 | String mDebugTag = "IabHelper"; |
@@ -1087,46 +1098,66 @@ int queryPurchases(Inventory inv, String itemType) throws JSONException, RemoteE |
1087 | 1098 | int querySkuDetails(String itemType, Inventory inv, List<String> moreSkus) |
1088 | 1099 | throws RemoteException, JSONException { |
1089 | 1100 | logDebug("Querying SKU details."); |
1090 | | - ArrayList<String> skuList = new ArrayList<String>(); |
1091 | | - skuList.addAll(inv.getAllOwnedSkus(itemType)); |
| 1101 | + Set<String> storeSkus = new TreeSet<String>(); |
| 1102 | + final List<String> allOwnedSkus = inv.getAllOwnedSkus(itemType); |
| 1103 | + storeSkus.addAll(inv.getAllOwnedSkus(itemType)); |
1092 | 1104 | if (moreSkus != null) { |
1093 | 1105 | for (String sku : moreSkus) { |
1094 | | - if (!skuList.contains(sku)) { |
1095 | | - skuList.add(sku); |
| 1106 | + if (!storeSkus.contains(sku)) { |
| 1107 | + storeSkus.add(sku); |
1096 | 1108 | } |
1097 | 1109 | } |
1098 | 1110 | } |
1099 | 1111 |
|
1100 | | - if (skuList.size() == 0) { |
1101 | | - logDebug("queryPrices: nothing to do because there are no SKUs."); |
| 1112 | + if (storeSkus.size() == 0) { |
| 1113 | + logDebug("querySkuDetails(): nothing to do because there are no SKUs."); |
1102 | 1114 | return BILLING_RESPONSE_RESULT_OK; |
1103 | 1115 | } |
1104 | 1116 |
|
1105 | | - Bundle querySkus = new Bundle(); |
1106 | | - querySkus.putStringArrayList(GET_SKU_DETAILS_ITEM_LIST, skuList); |
1107 | | - Bundle skuDetails = mService.getSkuDetails(3, mContext.getPackageName(), |
1108 | | - itemType, querySkus); |
1109 | | - |
1110 | | - if (!skuDetails.containsKey(RESPONSE_GET_SKU_DETAILS_LIST)) { |
1111 | | - int response = getResponseCodeFromBundle(skuDetails); |
1112 | | - if (response != BILLING_RESPONSE_RESULT_OK) { |
1113 | | - logDebug("getSkuDetails() failed: " + getResponseDesc(response)); |
1114 | | - return response; |
| 1117 | + // Split the sku list in blocks of no more than QUERY_SKU_DETAILS_BATCH_SIZE elements. |
| 1118 | + ArrayList<ArrayList<String>> batches = new ArrayList<ArrayList<String>>(); |
| 1119 | + ArrayList<String> tmpBatch = new ArrayList<String>(QUERY_SKU_DETAILS_BATCH_SIZE); |
| 1120 | + int iSku = 0; |
| 1121 | + for (String sku : storeSkus) { |
| 1122 | + tmpBatch.add(sku); |
| 1123 | + iSku++; |
| 1124 | + if (tmpBatch.size() == QUERY_SKU_DETAILS_BATCH_SIZE || iSku == storeSkus.size()) { |
| 1125 | + batches.add(tmpBatch); |
| 1126 | + tmpBatch = new ArrayList<String>(QUERY_SKU_DETAILS_BATCH_SIZE); |
1115 | 1127 | } |
1116 | | - else { |
1117 | | - logError("getSkuDetails() returned a bundle with neither an error nor a detail list."); |
| 1128 | + } |
| 1129 | + |
| 1130 | + logDebug("querySkuDetails() batches: " + batches.size() + ", " + batches); |
| 1131 | + |
| 1132 | + for (ArrayList<String> batch : batches) { |
| 1133 | + Bundle querySkus = new Bundle(); |
| 1134 | + querySkus.putStringArrayList(GET_SKU_DETAILS_ITEM_LIST, batch); |
| 1135 | + if (mService == null) { |
| 1136 | + logError("unable to get sku details: service is not connected."); |
1118 | 1137 | return IABHELPER_BAD_RESPONSE; |
1119 | 1138 | } |
1120 | | - } |
| 1139 | + Bundle skuDetails = mService.getSkuDetails(3, mContext.getPackageName(), itemType, querySkus); |
| 1140 | + |
| 1141 | + if (!skuDetails.containsKey(RESPONSE_GET_SKU_DETAILS_LIST)) { |
| 1142 | + int response = getResponseCodeFromBundle(skuDetails); |
| 1143 | + if (response != BILLING_RESPONSE_RESULT_OK) { |
| 1144 | + logDebug("getSkuDetails() failed: " + getResponseDesc(response)); |
| 1145 | + return response; |
| 1146 | + } else { |
| 1147 | + logError("getSkuDetails() returned a bundle with neither an error nor a detail list."); |
| 1148 | + return IABHELPER_BAD_RESPONSE; |
| 1149 | + } |
| 1150 | + } |
1121 | 1151 |
|
1122 | | - ArrayList<String> responseList = skuDetails.getStringArrayList( |
1123 | | - RESPONSE_GET_SKU_DETAILS_LIST); |
| 1152 | + ArrayList<String> responseList = skuDetails.getStringArrayList(RESPONSE_GET_SKU_DETAILS_LIST); |
1124 | 1153 |
|
1125 | | - for (String thisResponse : responseList) { |
1126 | | - SkuDetails d = new SkuDetails(itemType, thisResponse); |
1127 | | - logDebug("Got sku details: " + d); |
1128 | | - inv.addSkuDetails(d); |
| 1154 | + for (String thisResponse : responseList) { |
| 1155 | + SkuDetails d = new SkuDetails(itemType, thisResponse); |
| 1156 | + logDebug("Got sku details: " + d); |
| 1157 | + inv.addSkuDetails(d); |
| 1158 | + } |
1129 | 1159 | } |
| 1160 | + |
1130 | 1161 | return BILLING_RESPONSE_RESULT_OK; |
1131 | 1162 | } |
1132 | 1163 |
|
|
0 commit comments