Я пытаюсь настроить простую покупку в приложении, но по какой-то причине я всегда получаю нулевой указатель, когда пытаюсь запросить доступные элементы. Я попытался использовать Handler, чтобы узнать, не проблема ли это с ожиданием, но это тоже не сработало, это просто помешало запуску кода.
public class AdOnsActivity extends AppCompatActivity {
private IInAppBillingService mService;
private ServiceConnection mServiceConn = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
mService = null;
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mService = IInAppBillingService.Stub.asInterface(service);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ad_ons);
Intent serviceIntent = new Intent("com.android.vending.billing.InAppBillingService.BIND");
serviceIntent.setPackage("com.android.vending");
bindService(serviceIntent, mServiceConn, Context.BIND_AUTO_CREATE);
ArrayList<String> skuList = new ArrayList<String>();
skuList.add(PRODUCT_ID_MORE_REPTILES);
final Bundle querySkus = new Bundle();
querySkus.putStringArrayList("ITEM_ID_LIST", skuList);
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
if (mService != null) {
//Query items here
} else {
handler.postDelayed(this, 10);
}
}
}, 10);
buttonBuy = (Button) findViewById(R.id.buttonBuy);
buttonBuy.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
Bundle buyIntentBundle = mService.getBuyIntent(3, getPackageName(), PRODUCT_ID_MORE_REPTILES, "inapp", "bGoa+V7g/yqDXvKRqq+JTFn4uQZbPiQJo4pf9RzJ");
PendingIntent pendingIntent = buyIntentBundle.getParcelable("BUY_INTENT");
startIntentSenderForResult(pendingIntent.getIntentSender(), 1001, new Intent(), 0, 0, 0);
} catch (RemoteException|IntentSender.SendIntentException e) {
e.printStackTrace();
}
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1001) {
int responseCode = data.getIntExtra("RESPONSE_CODE", 0);
String purchaseData = data.getStringExtra("INAPP_PURCHASE_DATA");
String dataSignature = data.getStringExtra("INAPP_DATA_SIGNATURE");
if (resultCode == RESULT_OK) {
try {
JSONObject json = new JSONObject(purchaseData);
String sku = json.getString("productId");
Toast.makeText(this, "Congratulations on your purchase!", Toast.LENGTH_SHORT).show();
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}
@Override
public void onDestroy() {
super.onDestroy();
if (mService != null) {
unbindService(mServiceConn);
}
}
Трассировка стека, чтобы точно показать код, вызывающий NPE, была бы удобна. Но я собираюсь предположить, что вы имеете в виду, что mService всегда равен нулю в вашем вызове onCreate.
По сути, вы плохо разрабатываете программу. Доступность продуктов для продажи через приложение - это сетевой вызов. И вам не следует выполнять Aysnchronous network call в вашем методе onCreate.
Вместо этого заполните место для IAP. Затем, когда вы получите onServiceConnected (), пусть это вызовет вызов listProducts(). Затем, когда queryProducts() получит результат, заполните ListView или все, что вы создали. В противном случае у вас будет ужасный опыт для пользователя, который всегда не в сети.