基本的な請求処理のAndroidの指示に従って、IABHelperなどのAIDLファイルとアプリ内課金コードファイルを統合したと仮定します。
すでにお支払いを処理したら、在庫を照会して購入済みかどうかを確認するだけです。私はPurchaseManagerというシングルトンクラスでこれを行う傾向があります。
私はこのクラスを以下のように共有します。しかし、私は1つのパッケージしか持っていないので、購入した商品の小切手でそのパッケージを徹底的にコーディングし、よりダイナミックにするために、コールクラスやループで小切手をしたいかもしれません。
/**
* Created by App Studio 35 on 9/28/17.
*/
public class PurchaseManager {
/*///////////////////////////////////////////////////////////////
// MEMBERS
*////////////////////////////////////////////////////////////////
private static PurchaseManager mInstance;
private static final String TAG = Globals.SEARCH_STRING + PurchaseManager.class.getSimpleName();
private static String PUBLIC_LICENSING_KEY = "<YOUR PUBLIC KEY HERE>";
private static final String PRO_PACKAGE_SKU = "pro_package_level_1";
public static final int RESULT_KEY_PURCHASE = 9876;
private IabHelper mHelper;
private Boolean mIABServiceIsAvailable = false;
private static String mAndroidId;
/*///////////////////////////////////////////////////////////////
// CONSTRUCTOR
*////////////////////////////////////////////////////////////////
private PurchaseManager(){}
public static synchronized PurchaseManager getInstance(){
if(mInstance == null){
mInstance = new PurchaseManager();
}
return mInstance;
}
/*///////////////////////////////////////////////////////////////
// EXTERNAL METHODS
*////////////////////////////////////////////////////////////////
public boolean getIsIABServiceAvailable(){
return mIABServiceIsAvailable;
}
public void checkForPurchasesOrTrials(final Context context, final IPurchaseSyncListener listener) {
mHelper = new IabHelper(context, PUBLIC_LICENSING_KEY);
if(!BuildConfig.DEBUG) {
mHelper.enableDebugLogging(true, TAG);
}
//Setup Purchase Processor
mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
@Override
public void onIabSetupFinished(IabResult result) {
mIABServiceIsAvailable = result.isSuccess();
if (!result.isSuccess()) {
String error = "Problem setting up In-app Billing: " + result;
A35Log.d(TAG, error);
notifyUserOfError(listener, error);
return;
}
ArrayList<String> skus = new ArrayList<String>();
skus.add(PRO_PACKAGE_SKU);
checkExistingPurchasesForSkus(context, listener, skus);
}
});
}
public void attemptPurchaseOfPro(Activity activity, final IPurchaseConsumeListener listener){
mHelper.launchPurchaseFlow(activity, PRO_PACKAGE_SKU, RESULT_KEY_PURCHASE, new IabHelper.OnIabPurchaseFinishedListener() {
@Override
public void onIabPurchaseFinished(IabResult result, Purchase info) {
if (result.isSuccess()) {
mHelper.consumeAsync(info, new IabHelper.OnConsumeFinishedListener() {
@Override
public void onConsumeFinished(Purchase purchase, IabResult result) {
if (result.isSuccess()) {
Log.d(TAG, "Successfully synced purchases" + result);
notifyUserOfPurchaseSuccess(listener, purchase, result, PRO_PACKAGE_SKU);
} else {
String error = "Could not sync purchases. Error: " + result;
Log.d(TAG, error);
notifyUserOfPurchaseError(listener, error, result, PRO_PACKAGE_SKU);
}
}
});
}else{
notifyUserOfPurchaseError(listener, "Purchase Incomplete", result, PRO_PACKAGE_SKU);
}
}
});
}
/*///////////////////////////////////////////////////////////////
// INTERNAL METHODS
*////////////////////////////////////////////////////////////////
private void checkExistingPurchasesForSkus(final Context context, final IPurchaseSyncListener listener, final ArrayList<String> skus) {
mHelper.queryInventoryAsync(true, skus, new IabHelper.QueryInventoryFinishedListener() {
@Override
public void onQueryInventoryFinished(IabResult result, Inventory inv) {
if (!result.isSuccess()) {
String error = "Unable to query inventory. Error: " + result;
A35Log.d(TAG, error);
notifyUserOfError(listener, error);
return;
}
ArrayList<Purchase> purchaseList = new ArrayList<Purchase>();
if (inv.getPurchase(PRO_PACKAGE_SKU) != null) {
purchaseList.add(inv.getPurchase(PRO_PACKAGE_SKU));
}
if (!purchaseList.isEmpty()) {
A35Log.d(TAG, "Attempting to sync purchases" + result);
attemptToSyncPurchases(context, listener, purchaseList);
} else {
A35Log.d(TAG, "We didn't see any purchases, attempting to check for Trials");
if(mAndroidId == null) {
getAdvertiserIDThenCheckTrialsForDevice(context, listener, skus);
}else{
checkTrialsForDeviceID(context, listener, skus);
}
}
}
});
}
private void attemptToSyncPurchases(final Context context, final IPurchaseSyncListener listener, final ArrayList<Purchase> purchaseList) {
for(Purchase purchase : purchaseList) {
mHelper.consumeAsync(purchase, new IabHelper.OnConsumeFinishedListener() {
@Override
public void onConsumeFinished(Purchase purchase, IabResult result) {
if (result.isSuccess()) {
Log.d(TAG, "Successfully synced purchases" + result);
notifyUserOfPurchasedPackages(listener, purchaseList);
} else {
String error = "Could not sync purchases. Error: " + result;
Log.d(TAG, error);
notifyUserOfError(listener, error);
}
}
});
}
}
private void getAdvertiserIDThenCheckTrialsForDevice(final Context context, final IPurchaseSyncListener listener, final ArrayList<String> skus){
//If no purchases then check for trial times for skus get Advertiser ID for identifying device
new GetAdvertiserIDAsyncTask(context){
@Override
protected void onPostExecute(String advertisementID) {
mAndroidId = (advertisementID == null ? "unknownID" : advertisementID);
checkTrialsForDeviceID(context, listener, skus);
}
}.execute();
}
private void checkTrialsForDeviceID(final Context context, final IPurchaseSyncListener listener, final ArrayList<String> skus){
//Use device ID to check for Trials
new GetTrialTimeAsyncTask(context, mAndroidId){
@Override
protected void onPostExecute(ActiveTrialsListResponseModel activeTrialsListResponseModel) {
super.onPostExecute(activeTrialsListResponseModel);
A35Log.v(TAG, "onPostExecute");
if(activeTrialsListResponseModel.getErrorMessage() != null) {
String error = "Error getting trial time: " + activeTrialsListResponseModel.getErrorMessage();
A35Log.e(TAG, error);
notifyUserOfError(listener, error);
return;
}
notifyUserOfTrialCheckCompleteForPackages(listener, activeTrialsListResponseModel);
}
}.execute();
}
/*///////////////////////////////////////////////////////////////
// NOTIFY USER CALLBACKS
*////////////////////////////////////////////////////////////////
private void notifyUserOfError(IPurchaseSyncListener listener, String message){
if(listener != null){
listener.onPurchaseManagerError(message);
}
}
private void notifyUserOfPurchasedPackages(IPurchaseSyncListener listener, ArrayList<Purchase> purchasedSkus){
if(listener != null){
listener.onPackagePurchased(purchasedSkus);
}
}
private void notifyUserOfTrialCheckCompleteForPackages(IPurchaseSyncListener listener, ActiveTrialsListResponseModel activeTrialsListResponseModel){
if(listener != null){
listener.onTrialRetrievalComplete(activeTrialsListResponseModel);
}
}
private void notifyUserOfPurchaseSuccess(IPurchaseConsumeListener listener, Purchase purchase, IabResult result, String sku){
if(listener != null){
listener.onPurchaseSuccessful(purchase, result, sku);
}
}
private void notifyUserOfPurchaseError(IPurchaseConsumeListener listener, String message, IabResult result, String sku){
if(listener != null){
listener.onPurchaseFailure(message, result, sku);
}
}
/*///////////////////////////////////////////////////////////////
// INTERFACE
*////////////////////////////////////////////////////////////////
public interface IPurchaseSyncListener {
void onPackagePurchased(ArrayList<Purchase> sku);
void onTrialRetrievalComplete(ActiveTrialsListResponseModel activeTrialsListResponseModel);
void onPurchaseManagerError(String message);
}
public interface IPurchaseConsumeListener {
void onPurchaseSuccessful(Purchase purchase, IabResult result, String sku);
void onPurchaseFailure(String message, IabResult result, String sku);
}
}
私の共有コードについても3つの注意点があります。
- 自分のプロパッケージの試用版を使用しているため、試用版ではないことを確認するための非同期作業です。
- 私は認証されたユーザーがいません。試用版があるかどうかを知るためにデバイスの広告主IDに依存していますが、これは問題ではありません。また、Googleの設定で広告主IDをリセットすることもできます。十分な手間があれば、別の無料試用版を手に入れる方法がわかりますが、パワーユーザーがドルハハを救うためにはそれほど心配していません。
- 私は、アプリの起動時に1回しか呼び出されず、最初の呼び出しであるため、checkfor購入メソッド内でスタートアップを行いました。 helperがnullの場合、より一般的な方法は、最初のgetInstanceで行うことです。
グッドラック。