Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/227.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 使用OpenIAB提交到Amazon Appstore_Android_In App Purchase_Amazon - Fatal编程技术网

Android 使用OpenIAB提交到Amazon Appstore

Android 使用OpenIAB提交到Amazon Appstore,android,in-app-purchase,amazon,Android,In App Purchase,Amazon,我们在第一个Android应用程序中使用OpenIAB进行应用内购买。我们设置了所有内容,并能够使用Amazon App Tester在设备上成功测试,并使用终端中的./adb install-i com.Amazon.venezia appname.apk命令安装应用程序 然而,当我们提交给亚马逊应用商店时,他们的测试人员拒绝了我们,因为该应用不会下载应用内购买/价格。我要说的是,它在使用OpenIAB的GooglePlay中也运行得非常好 我已经包含了我们在下面编写的代码。我们还按照网站的建

我们在第一个Android应用程序中使用OpenIAB进行应用内购买。我们设置了所有内容,并能够使用Amazon App Tester在设备上成功测试,并使用终端中的./adb install-i com.Amazon.venezia appname.apk命令安装应用程序

然而,当我们提交给亚马逊应用商店时,他们的测试人员拒绝了我们,因为该应用不会下载应用内购买/价格。我要说的是,它在使用OpenIAB的GooglePlay中也运行得非常好

我已经包含了我们在下面编写的代码。我们还按照网站的建议设置了manifest和proguard-rules.pro。我们将非常感谢您的任何帮助,因为我们没有得到亚马逊的支持:

public class InAppBilling {
private static final String TAG = "InAppBilling";
private static InAppBilling mInstance = null;

// (arbitrary) request code for the purchase flow
static final int RC_REQUEST = <number goes here>;

private OpenIabHelper mHelper;
private NoteListFragment mFragment;
private Context mContext;

private InAppBilling() {}

public static InAppBilling get() {
    if (mInstance == null) {
        InAppConfig.init();
        mInstance = new InAppBilling();
    }
    return mInstance;
}

public OpenIabHelper getHelper() {
    return mHelper;
}

// Initialize OpenIAB library and when completed automatically kick off full product info download
public void init(Context context, NoteListFragment fragment) {
    mContext = context;

    // If library was already initialized, go straight to info download, don't init twice
    if (mHelper != null) {
        InAppBilling.get().queryPricesAndPurchases(fragment);
        return;
    }

    // Create the helper, passing it our context and the public keys to verify signatures with
    //Log.d(TAG, "Creating IAB helper.");
    OpenIabHelper.Options.Builder builder = new OpenIabHelper.Options.Builder()
            .setStoreSearchStrategy(OpenIabHelper.Options.SEARCH_STRATEGY_INSTALLER_THEN_BEST_FIT)
            .setVerifyMode(OpenIabHelper.Options.VERIFY_EVERYTHING)
            .addStoreKeys(InAppConfig.STORE_KEYS_MAP);
    mHelper = new OpenIabHelper(context, builder.build());

    // enable debug logging (for a production application, you should comment this out)
    //OpenIabHelper.enableDebugLogging(true);

    // Start setup. This is asynchronous and the embedded listener
    // will be called once setup completes.
    //Log.d(TAG, "Starting IAB setup.");
    mFragment = fragment;   // cache for use by callback
    mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
        public void onIabSetupFinished(IabResult result) {
            //Log.d(TAG, "IAB Setup finished.");

            if (!result.isSuccess()) {
                //Log.d(TAG, "Problem setting up in-app billing: " + result);
                mHelper = null;
                return;
            }

            //Log.d(TAG, "IAB Setup successful.");
            InAppBilling.get().queryPricesAndPurchases(null);   // use cached mFragment
        }
    });
}

// Launches a background download of info for all products
public void queryPricesAndPurchases(NoteListFragment fragment) {
    if (fragment != null)
        mFragment = fragment;
    //Log.d(TAG, "Launching product info query");
    mHelper.queryInventoryAsync(true, InAppConfig.ALL_SKUS, mGotInventoryListener);
}

// Listener that's called when we finish querying the product info
// Sets the price info for all packs, and clears and then re-sets the notes' purchased states
private IabHelper.QueryInventoryFinishedListener mGotInventoryListener =
        new IabHelper.QueryInventoryFinishedListener() {
            @Override
            public void onQueryInventoryFinished(IabResult result, Inventory inventory) {
                //Log.d(TAG, "Query inventory finished: " + inventory.getAllPurchases() + inventory.getAllOwnedSkus());
                if (result.isFailure()) {
                    //Log.d(TAG, "Failed to query inventory: " + result);
                    return;
                }
                //Log.d(TAG, "Query inventory was successful.");

                // Note & pack data controller singletons already exist (created at startup)
                // so we don't need to pass a Context here (which we don't really have handy)
                PackDataController pdc = PackDataController.get(null);
                NoteDataController ndc = NoteDataController.get(null);
                ndc.returnAllNotes();

                for (String sku : InAppConfig.ALL_SKUS) {
                    Pack pack = pdc.findPackWithAppStoreId(sku);
                    if (pack != null) {
                        if (inventory.hasDetails(sku)) {
                            SkuDetails details = inventory.getSkuDetails(sku);
                            String price = details.getPrice();
                            pack.setPrice(price);   // supposedly localized according to user's account
                            //Log.d(TAG, "SKU " + sku + " = " + price);
                        } else {
                            //Log.d(TAG, "SKU " + sku + " details not found");
                        }

                        if (inventory.hasPurchase(sku)) {
                            Purchase purchase = inventory.getPurchase(sku);
                            if (verifyDeveloperPayload(purchase)) {
                                //Log.d(TAG, "Purchased SKU " + sku);
                                ndc.purchaseNotesWithPackId(pack.getId(), true);
                            } else {
                                //Log.d(TAG, "Payload verification failed SKU " + sku);
                            }
                        }
                    }
                }

                ndc.updateNoteList();
                mFragment.updateNoteAdapter();
            }
        };

/**
 * Verifies the developer payload of a purchase.
 */
boolean verifyDeveloperPayload(Purchase p) {
    String store = mHelper.getConnectedAppstoreName();
    if (store != null && store.equals(OpenIabHelper.NAME_AMAZON))
        return true;    // Amazon doesn't support payload verification, so bypass it
    if (p == null || p.getSku() == null)
        return false;
    String payload = p.getDeveloperPayload();
    if (payload == null)
        return false;

    return payload.equals(p.getSku() + p.getSku().length() * 13);
}

// Launches a product purchase request in a background thread
public void purchase(Activity act, String sku) {
    if (!sku.contains("."))
        sku = InAppConfig.SKU_PREFIX + sku;
    String payload = sku + sku.length() * 13;
    mHelper.launchPurchaseFlow(act, sku, RC_REQUEST, mPurchaseFinishedListener, payload);
}

// Callback for when a purchase is finished
IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() {
    public void onIabPurchaseFinished(IabResult result, Purchase purchase) {
        //Log.d(TAG, "Purchase finished: " + result + ", purchase: " + purchase);
        if (result.isFailure()) {
            //Log.d(TAG, "Error purchasing: " + result);
            return;
        }
        if (!verifyDeveloperPayload(purchase)) {
            //Log.d(TAG, "Error purchasing. Authenticity verification failed.");
            return;
        }

        //Log.d(TAG, "Purchase successful: " + purchase.getAppstoreName() + ", SKU: " + purchase.getSku());
        PackDataController pdc = PackDataController.get(null);
        Pack pack = pdc.findPackWithAppStoreId(purchase.getSku());
        NoteDataController ndc = NoteDataController.get(null);
        ndc.purchaseNotesWithPackId(pack.getId(), true);
        ndc.updateNoteList();
        if (mFragment != null)
            mFragment.updateNoteAdapter();

        Intent intent = new Intent("purchase-completed");
        // You can also include some extra data.
        intent.putExtra("message", "Purchase completed, reload template");
        LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent);
    }
};
}
应用计费中的公共类{
私有静态最终字符串TAG=“InAppBilling”;
私有静态不适用实例=null;
//(任意)采购流程的请求代码
静态最终int RC_请求=;
私人开放式酒店;
私人票据碎片;
私有上下文;
私有InAppBilling(){}
公共静态InAppGet(){
if(minInstance==null){
InAppConfig.init();
MinInstance=新的不适用计费();
}
回报率;
}
公共OpenHelper getHelper(){
返回mHelper;
}
//初始化OpenIAB库,完成后自动启动完整的产品信息下载
公共void init(上下文,NoteListFragment片段){
mContext=上下文;
//若库已经初始化,直接转到信息下载,不要初始化两次
如果(mHelper!=null){
InAppBilling.get().queryPricesAndPurchases(片段);
回来
}
//创建助手,将上下文和公钥传递给它以验证签名
//Log.d(标记“创建IAB助手”);
OpenIabHelper.Options.Builder=new OpenIabHelper.Options.Builder()
.setStoreSearchStrategy(OpenIabHelper.Options.SEARCH\u STRATEGY\u INSTALLER\u然后\u BEST\u FIT)
.setVerifyMode(OpenIabHelper.Options.VERIFY\u所有内容)
.addStoreKeys(InAppConfig.STORE\u KEYS\u MAP);
mHelper=newOpenIbaHelper(上下文,builder.build());
//启用调试日志记录(对于生产应用程序,您应该对此进行注释)
//OpenIbaHelper.enableDebugLogging(true);
//启动安装程序。这是异步的,并且是嵌入式侦听器
//安装程序完成后将调用。
//Log.d(标签“启动IAB设置”);
mffragment=fragment;//用于回调的缓存
mHelper.startSetup(新的IabHelper.OnIabSetupFinishedListener(){
已完成公共void ONIBS设置(IAB结果){
//Log.d(标记“IAB设置完成”);
如果(!result.issucess()){
//Log.d(标签,“应用内计费设置问题:+结果”);
mHelper=null;
回来
}
//Log.d(标记“IAB设置成功”);
InAppBilling.get().queryPricesAndPurchases(null);//使用缓存的MFFragment
}
});
}
//启动所有产品的后台信息下载
公共无效查询价格和购买(NoteListFragment片段){
if(片段!=null)
mFragment=片段;
//Log.d(标签“启动产品信息查询”);
mHelper.queryInventoryAsync(true,在appconfig.ALL_SKU中,mGotInventoryListener);
}
//完成查询产品信息时调用的侦听器
//设置所有包装的价格信息,清除并重新设置票据的购买状态
私有IabHelper.QueryInventoryFinishedListener管理InventoryListener=
新建IabHelper.QueryInventoryFinishedListener(){
@凌驾
QueryInventoryFinished上的公共无效(IABREACT结果,库存){
//Log.d(标记“查询库存完成:”+inventory.getAllPurchases()+inventory.getAllowedskus());
if(result.isFailure()){
//Log.d(标记“无法查询库存:+结果”);
回来
}
//Log.d(标记“查询库存成功”);
//注意&包数据控制器单例已存在(在启动时创建)
//因此,我们不需要在这里传递上下文(实际上我们手头没有上下文)
PackDataController pdc=PackDataController.get(null);
NoteDataController ndc=NoteDataController.get(null);
ndc.returnAllNotes();
用于(字符串sku:InAppConfig.ALL_sku){
Pack Pack=pdc.findPackWithAppStoreId(sku);
if(pack!=null){
if(库存详细信息(sku)){
SkuDetails details=存货。获取sku详细信息(sku);
字符串price=details.getPrice();
pack.setPrice(price);//应该根据用户的帐户进行本地化
//Log.d(标签,“SKU”+SKU+“=”+价格);
}否则{
//Log.d(标记“SKU”+SKU+“未找到详细信息”);
}
if(库存、采购(sku)){
采购=存货.getPurchase(sku);
if(验证developerPayLoad(购买)){
//日志d(标签“购买的SKU”+SKU);
ndc.purchaseNotesWithPackId(pack.getId(),true);
}否则{
//Log.d(标签“有效负载验证失败的SKU”+SKU);
}
}
}
}
ndc.updateNotList();
mFragment.UpdateNodeAdapter();
}
};
/**
*验证购买的开发人员有效负载。
*/
布尔验证developerPayLoad(购买p){
字符串存储=mHelper.getConnecte