我只想在我的应用中实施应用内购买。这是一个具有不同规则集的纸牌游戏。所以现在想要实现2个新的规则集,它们应该作为我的产品和应用程序内购买。 我有这个:
`go = (Button)findViewById(R.id.go);
go.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
ArrayList skuList = new ArrayList();
skuList.add(inappid);
Bundle querySkus = new Bundle();
querySkus.putStringArrayList("ITEM_ID_LIST", skuList);
Bundle skuDetails;
try {
skuDetails = mservice.getSkuDetails(3, getPackageName(),
"inapp", querySkus);
int response = skuDetails.getInt("RESPONSE_CODE");
if (response == 0) {
ArrayList<String> responseList =
skuDetails.getStringArrayList("DETAILS_LIST");
for (String thisResponse : responseList) {
JSONObject object = new JSONObject(thisResponse);
String sku = object.getString("productId");
String price = object.getString("price");
if (sku.equals(inappid)) {
System.out.println("price " + price);
Bundle buyIntentBundle =
mservice.getBuyIntent(3, getPackageName(), sku,
"inapp",
"blablabla");
PendingIntent pendingIntent =
buyIntentBundle.getParcelable("BUY_INTENT");
startIntentSenderForResult(
pendingIntent.getIntentSender(), 1001,
new Intent(), Integer.valueOf(0),
Integer.valueOf(0), Integer.valueOf(0));
}
}
}
} catch (RemoteException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
} catch (IntentSender.SendIntentException e ) {
e.printStackTrace();
}
}
});`
首先点击我的规则集工作正常。第二次单击会触发应用程序崩溃,并显示以下错误: java.lang.NullPointerException:尝试调用虚拟方法&#39; android.content.IntentSender android.app.PendingIntent.getIntentSender()&#39;在空对象引用上
你有一些很好的应用内教程或tipp吗?
提前致谢 JD
答案 0 :(得分:1)
这是我在我需要的任何地方使用的BaseClass。只需按此BaseInAppPurchaseActivity
本课程的奖金。
您可以获取可供购买的商品,因此如果商品不可用,则用户无法获得将来的例外情况,例如
checkAvailablePurchases(skuList, new OnResultInApp() {
@Override
public void onResult(ArrayList<AvailablePurchase> availablePurchaseArrayList) {
.. logic for showing view with available purchaseItem
}
});
购买商品
purchaseItem(googleInAppId, new OnResultPurchase() {
@Override
public void onSuccess(PurchaseResponseBean purchaseResponseBean, String inAppPurchaseData) {
// your stuff
}
@Override
public void onError() {
showToast(R.string.something_went_wrong);
}
});
这看起来很干净漂亮。
BaseInAppPurchaseActivity.class
package in.kpis.nearyou.base;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
import android.content.ServiceConnection;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import com.android.vending.billing.IInAppBillingService;
import com.google.gson.Gson;
import org.json.JSONException;
import org.json.JSONObject;
import java.math.BigInteger;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import in.kpis.nearyou.entity.AvailablePurchase;
import in.kpis.nearyou.entity.Helper;
import in.kpis.nearyou.entity.PurchaseResponseBean;
import in.kpis.nearyou.entity.UserPurchaseItemsBean;
import in.kpis.nearyou.utilities.AppPreference;
import static in.kpis.nearyou.base.BaseInAppPurchaseActivity.ConsuptionResponseType.SUCCESS;
import static in.kpis.nearyou.base.BaseInAppPurchaseActivity.PurchaseStateTypes.PURCHASED;
public class BaseInAppPurchaseActivity extends BaseAppCompatActivity {
private static final String TAG = BaseInAppPurchaseActivity.class.getSimpleName();
private IInAppBillingService mService;
private static final char[] symbols = new char[36];
static {
for (int idx = 0; idx < 10; ++idx)
symbols[idx] = (char) ('0' + idx);
for (int idx = 10; idx < 36; ++idx)
symbols[idx] = (char) ('a' + idx - 10);
}
public void startInAppPurchaseServices() {
Intent serviceIntent = new Intent("com.android.vending.billing.InAppBillingService.BIND");
serviceIntent.setPackage("com.android.vending");
bindService(serviceIntent, mServiceConn, Context.BIND_AUTO_CREATE);
}
private String appPackageName;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
appPackageName = this.getPackageName();
startInAppPurchaseServices();
}
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);
startAsyncForCheckingAvailablePurchase();
}
};
private void startAsyncForCheckingAvailablePurchase() {
if (skuListByNearyouServer != null && skuListByNearyouServer.size() > 0 & onResultInApp != null) {
AvailablePurchaseAsyncTask mAsyncTask = new AvailablePurchaseAsyncTask(appPackageName, skuListByNearyouServer, onResultInApp);
mAsyncTask.execute();
}
}
private ArrayList<String> skuListByNearyouServer = new ArrayList<>();
OnResultInApp onResultInApp;
public void checkAvailablePurchases(ArrayList<String> skuList, OnResultInApp onResultInApp) {
skuListByNearyouServer = skuList;
this.onResultInApp = onResultInApp;
if (mService == null) startInAppPurchaseServices();
else startAsyncForCheckingAvailablePurchase();
}
public interface OnResultPurchase {
void onSuccess(PurchaseResponseBean purchaseResponseBean, String inAppPurchaseData);
void onError();
}
private OnResultPurchase onResultPurchase;
private String itemToPurchaseSku;
public void purchaseItem(String sku, OnResultPurchase onResultPurchase) {
this.onResultPurchase = onResultPurchase;
itemToPurchaseSku = sku;
if (isBillingSupported()) {
String generatedPayload = getPayLoad();
AppPreference.getInstance(BaseInAppPurchaseActivity.this).setDeveloperPayload(generatedPayload);
try {
Bundle buyIntentBundle = mService.getBuyIntent(3, getPackageName(), sku, "inapp", generatedPayload);
PendingIntent pendingIntent = buyIntentBundle.getParcelable("BUY_INTENT");
try {
startIntentSenderForResult(pendingIntent.getIntentSender(), Helper.RESPONSE_CODE, new Intent(), Integer.valueOf(0), Integer.valueOf(0), Integer.valueOf(0));
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
}
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == Helper.RESPONSE_CODE) {
if (data != null && data.getExtras() != null && data.getStringExtra("INAPP_DATA_SIGNATURE") != null & data.getStringExtra("INAPP_PURCHASE_DATA") != null) {
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 && responseCode == 0) {
try {
PurchaseResponseBean purchaseResponseBean = new Gson().fromJson(purchaseData, PurchaseResponseBean.class);
String sku = purchaseResponseBean.getProductId();
String developerPayload = purchaseResponseBean.getDeveloperPayload();
int responseCodeConsuption = consumePurchaseItem(purchaseResponseBean.getPurchaseToken());
if (responseCodeConsuption == SUCCESS) {
if (purchaseResponseBean.getPurchaseState() == PURCHASED && itemToPurchaseSku.equals(sku) && developerPayload.equals(AppPreference.getInstance(BaseInAppPurchaseActivity.this).getDeveloperPayload())) {
if (onResultPurchase != null)
onResultPurchase.onSuccess(purchaseResponseBean, purchaseData);
} else onErrorOfPurchase();
} else onResultPurchase.onSuccess(purchaseResponseBean, purchaseData);
} catch (Exception e) {
e.printStackTrace();
onErrorOfPurchase();
}
} else onErrorOfPurchase();
}
} else onErrorOfPurchase();
}
private void onErrorOfPurchase() {
if (onResultPurchase != null) onResultPurchase.onError();
}
interface PurchaseStateTypes {
int PURCHASED = 0;
int CANCELED = 1;
int REFUNDED = 2;
}
interface ConsuptionResponseType {
int SUCCESS = 0;
}
private String getPayLoad() {
RandomString randomString = new RandomString(36);
String payload = randomString.nextString();
return payload;
}
private class RandomString {
private final Random random = new Random();
private final char[] buf;
RandomString(int length) {
if (length < 1)
throw new IllegalArgumentException("length < 1: " + length);
buf = new char[length];
}
String nextString() {
for (int idx = 0; idx < buf.length; ++idx)
buf[idx] = symbols[random.nextInt(symbols.length)];
return new String(buf);
}
}
public final class SessionIdentifierGenerator {
private SecureRandom random = new SecureRandom();
public String nextSessionId() {
return new BigInteger(130, random).toString(32);
}
}
public interface OnResultInApp {
void onResult(ArrayList<AvailablePurchase> canPurchaseList);
}
private class AvailablePurchaseAsyncTask extends AsyncTask<Void, Void, Bundle> {
String packageName;
ArrayList<String> skuList;
OnResultInApp OnResultInApp;
AvailablePurchaseAsyncTask(String packageName, ArrayList<String> skuList, OnResultInApp OnResultInApp) {
this.packageName = packageName;
this.skuList = skuList;
this.OnResultInApp = OnResultInApp;
}
@Override
protected Bundle doInBackground(Void... voids) {
Bundle query = new Bundle();
query.putStringArrayList(Helper.ITEM_ID_LIST, skuList);
Bundle skuDetails = null;
try {
skuDetails = mService.getSkuDetails(3, packageName, "inapp", query);
} catch (RemoteException e) {
e.printStackTrace();
}
return skuDetails;
}
@Override
protected void onPostExecute(Bundle skuDetails) {
ArrayList<AvailablePurchase> availablePurchaseArrayList = new ArrayList<>();
if (skuDetails != null) {
int response = skuDetails.getInt("RESPONSE_CODE");
if (response == 0) {
ArrayList<String> responseList = skuDetails.getStringArrayList("DETAILS_LIST");
if (responseList != null) {
for (String thisResponse : responseList) {
JSONObject object = null;
try {
object = new JSONObject(thisResponse);
String sku = object.getString("productId");
String price = object.getString("price");
availablePurchaseArrayList.add(new AvailablePurchase(sku, price, false));
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}
}
for (AvailablePurchase availablePurchase : availablePurchaseArrayList) {
for (String sku : skuList) {
if (sku.equals(availablePurchase.getSku())) {
availablePurchase.setActive(true);
}
}
}
if (OnResultInApp != null) {
OnResultInApp.onResult(availablePurchaseArrayList);
}
}
}
public boolean isBillingSupported() {
int response = 1;
try {
response = mService.isBillingSupported(3, getPackageName(), "inapp");
} catch (RemoteException e) {
e.printStackTrace();
}
if (response > 0) {
return false;
}
return true;
}
public int consumePurchaseItem(String purchaseToken) {
if (isBillingSupported()) {
try {
int response = mService.consumePurchase(3, getPackageName(), purchaseToken);
return response;
} catch (RemoteException e) {
e.printStackTrace();
return -1;
}
} else return -1;
}
public Bundle getAllUserPurchase() {
Bundle ownedItems = null;
try {
ownedItems = mService.getPurchases(3, getPackageName(), "inapp", null);
} catch (RemoteException e) {
e.printStackTrace();
}
return ownedItems;
}
public List<UserPurchaseItemsBean> extractAllUserPurchase(Bundle ownedItems) {
List<UserPurchaseItemsBean> mUserItems = new ArrayList<UserPurchaseItemsBean>();
int response = ownedItems.getInt("RESPONSE_CODE");
if (response == 0) {
ArrayList<String> ownedSkus = ownedItems.getStringArrayList("INAPP_PURCHASE_ITEM_LIST");
ArrayList<String> purchaseDataList = ownedItems.getStringArrayList("INAPP_PURCHASE_DATA_LIST");
ArrayList<String> signatureList = ownedItems.getStringArrayList("INAPP_DATA_SIGNATURE_LIST");
String continuationToken = ownedItems.getString("INAPP_CONTINUATION_TOKEN");
if (purchaseDataList != null) {
for (int i = 0; i < purchaseDataList.size(); ++i) {
String purchaseData = purchaseDataList.get(i);
assert signatureList != null;
String signature = signatureList.get(i);
assert ownedSkus != null;
String sku = ownedSkus.get(i);
UserPurchaseItemsBean allItems = new UserPurchaseItemsBean(sku, purchaseData, signature);
mUserItems.add(allItems);
}
}
}
return mUserItems;
}
@Override
public void onDestroy() {
super.onDestroy();
stopInAppPurchaseService();
}
private void stopInAppPurchaseService() {
if (mService != null) {
unbindService(mServiceConn);
}
}
}
AvailablePurchase.class
/**
* Created by KHEMRAJ on 7/13/2017.
*/
public class AvailablePurchase {
private String sku;
private String price;
private boolean isActive;
public AvailablePurchase(String sku, String price, boolean isActive) {
this.sku = sku;
this.price = price;
this.isActive = isActive;
}
public String getSku() {
return sku;
}
public String getPrice() {
return price;
}
public boolean isActive() {
return isActive;
}
public void setActive(boolean active) {
isActive = active;
}
}
Helper.class
/**
* Created by KHEMRAJ on 7/13/2017.
*/
import android.content.Context;
import android.widget.Toast;
public class Helper {
public static final String ITEM_ID_LIST = "ITEM_ID_LIST";
public static final String ITEM_ONE_ID = "android.test.purchased";
public static final String ITEM_TWO_ID = "2";
public static final String ITEM_THREE_ID = "3";
public static final String ITEM_FIVE_ID= "4";
public static final String ITEM_SIX_ID = "5";
public static final int RESPONSE_CODE = 1001;
public static void displayMessage(Context context, String message){
Toast.makeText(context.getApplicationContext(), message, Toast.LENGTH_LONG).show();
}
}
PurchaseResponseBean.class
/**
* Created by KHEMRAJ on 7/15/2017.
*/
public class PurchaseResponseBean {
private String productId;
private String developerPayload;
private String purchaseToken;
private String orderId;
private String purchaseTime;
private int purchaseState;
public String getProductId() {
return productId;
}
public void setProductId(String productId) {
this.productId = productId;
}
public String getDeveloperPayload() {
return developerPayload;
}
public void setDeveloperPayload(String developerPayload) {
this.developerPayload = developerPayload;
}
public String getPurchaseToken() {
return purchaseToken;
}
public void setPurchaseToken(String purchaseToken) {
this.purchaseToken = purchaseToken;
}
public String getOrderId() {
return orderId;
}
public void setOrderId(String orderId) {
this.orderId = orderId;
}
public String getPurchaseTime() {
return purchaseTime;
}
public void setPurchaseTime(String purchaseTime) {
this.purchaseTime = purchaseTime;
}
public int getPurchaseState() {
return purchaseState;
}
public void setPurchaseState(int purchaseState) {
this.purchaseState = purchaseState;
}
}
UserPurchaseItemsBean.class
public class UserPurchaseItemsBean {
private String sku;
private String purchasedata;
private String signature;
public UserPurchaseItemsBean(String sku, String purchasedata, String signature) {
this.sku = sku;
this.purchasedata = purchasedata;
this.signature = signature;
}
public String getSku() {
return sku;
}
public String getPurchasedata() {
return purchasedata;
}
public String getSignature() {
return signature;
}
}
AppPreference.java
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
public class AppPreference {
String DEVELOPERPAYLOAD = "DEVELOPERPAYLOAD";
String PURCHASETOKEN = "PURCHASETOKEN";
//Configuration Variable
private static AppPreference singletonPreference = null;
private SharedPreferences sp;
private Context context;
private AppPreference(Context context) {
if (context == null)
return;
this.context = context;
sp = context.getSharedPreferences(Constants.sharedPreference.PREFERENCE, 0);
}
public static AppPreference getInstance(Context context) {
if (singletonPreference == null)
singletonPreference = new AppPreference(context);
return singletonPreference;
}
public void clearOnlogout() {
Editor prefsEditor = sp.edit();
prefsEditor.clear();
prefsEditor.apply();
}
void removeData(String key) {
SharedPreferences.Editor editor = sp.edit();
editor.remove(key);
editor.apply();
}
public void setStringData(String pKey, String pData) {
SharedPreferences.Editor editor = sp.edit();
editor.putString(pKey, pData);
editor.apply();
}
public void setBooleanData(String pKey, boolean pData) {
SharedPreferences.Editor editor = sp.edit();
editor.putBoolean(pKey, pData);
editor.apply();
}
void setIntegerData(String pKey, int pData) {
SharedPreferences.Editor editor = sp.edit();
editor.putInt(pKey, pData);
editor.apply();
}
public String getStringData(String pKey) {
return sp.getString(pKey, "");
}
public boolean getBooleanData(String pKey) {
return sp.getBoolean(pKey, false);
}
public int getIntegerData(String pKey) {
return sp.getInt(pKey, 0);
}
public String getDeveloperPayload() {
return sp.getString(DEVELOPERPAYLOAD, "");
}
public void setDeveloperPayload(String developerPayload) {
SharedPreferences.Editor editor = sp.edit();
editor.putString(DEVELOPERPAYLOAD, developerPayload);
editor.apply();
}
}
快乐编码:)