繁体   English   中英

Android应用内结算 - 如何知道哪些用户购买了产品

[英]Android in app billing - How to know which users have bought a product

我有一个带有捐赠系统的Android应用程序,这些捐赠是自动消费的集成产品,让用户不止一次捐款。

我需要知道是否有某种方法可以找出哪些用户至少捐赠过一次。

我感谢任何帮助。

编辑:

除了Dima Kozhevin的答案之外......我在onServiceConnected() startSetup()方法中的onServiceConnected()事件中使用了这段代码IabHelper.

Bundle purchaseHistoryBundle = mService.getPurchaseHistory(6,BuildConfig.APPLICATION_ID, "inapp", null, new Bundle());
ArrayList<String> mListItems = purchaseHistoryBundle.getStringArrayList("INAPP_PURCHASE_ITEM_LIST");
if (mListItems != null){
    if (mListItems.size()>0){
        //User have donated at least once
    }else{
        //User never donated
    }
}

你应该使用getPurchaseHistory()方法。 签名方法:

Bundle getPurchaseHistory(int apiVersion,
                          String packageName,
                          String type,
                          String continuationToken,
                          Bundle extraParams);

您的代码将如下所示:

Bundle purchaseHistoryBundle = service.getPurchaseHistory(6, BuildConfig.APPLICATION_ID, "subs", null, new Bundle());

此外, 来自Google的人建议在该示例中使用queryPurchaseHistoryAsync方法:

该库还允许获取购买历史记录,即使它未在示例中展示。 请使用此方法获取所有购买历史记录(每个SKU最多1条记录)。

我假设您已经为IabHelper等集成了AIDL文件和应用程序结算代码文件..遵循Android说明进行基本计费处理。

一旦您处理完账单,您只需查询库存以查看他们是否已购买。 我倾向于在名为PurchaseManager的单例类中执行此操作。

我将在下面与您分享该课程。 但是,我只有一个包,所以我在我的支票购买中硬编码了这个包,为了更加动态,你可能想要在调用类或循环中进行这些检查。

/**
 * 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);
    }

}

关于我的共享代码还有三点需要注意。

  1. 我正在使用试用版我的专业包,所以这是我的异步任务,以确认他们没有在任何包的试验,你不会做那件事。
  2. 我没有经过身份验证的用户,我依靠设备广告客户ID来了解他们是否有试用,这对您来说无关紧要。 此外,广告客户ID可以由用户在Google设置中重置,如果他们足够狡猾,他们可以弄清楚如何获得另一个免费试用,但我并不担心权力用户为了节省一美元哈哈而走得那么远。
  3. 我在checkfor购买方法中做了我的启动,因为它只在应用启动时被调用一次,这是第一次调用。 如果helper为null,则可以在第一个getInstance中执行更通用的方法。

祝好运。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM