首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >InAppBilling在AndroidManifest中注册BroadcastReceiver

InAppBilling在AndroidManifest中注册BroadcastReceiver
EN

Stack Overflow用户
提问于 2017-08-15 03:42:57
回答 2查看 917关注 0票数 1

我正在我的安卓应用程序中实现InApp计费。但是,一切都很好,但是,我正在尝试将广播接收器从活动中分离到清单中。特别是在Android的琐事驱动示例中有这样的建议:

代码语言:javascript
运行
复制
// Important: Dynamically register for broadcast messages about updated purchases.
// We register the receiver here instead of as a <receiver> in the Manifest
// because we always call getPurchases() at startup, so therefore we can ignore
// any broadcasts sent while the app isn't running.
// Note: registering this listener in an Activity is a bad idea, but is done here
// because this is a SAMPLE. Regardless, the receiver must be registered after
// IabHelper is setup, but before first call to getPurchases().

目前有一个扩展BroadcastReceiver的类

代码语言:javascript
运行
复制
public class IabBroadcastReceiver extends BroadcastReceiver {
/**
 * The Intent action that this Receiver should filter for.
 */
public static final String ACTION = "com.android.vending.billing.PURCHASES_UPDATED";
private final IabBroadcastListener mListener;

public IabBroadcastReceiver(IabBroadcastListener listener) {
    mListener = listener;
}

@Override
public void onReceive(Context context, Intent intent) {
    if (mListener != null) {
        mListener.receivedBroadcast();
    }
}

/**
 * Listener interface for received broadcast messages.
 */
public interface IabBroadcastListener {
    void receivedBroadcast();
}
}

以及实现IabBroadcastReceiver.IabBroadcastListener的类。

代码语言:javascript
运行
复制
public class Subscription extends AppCompatActivity implements 
IabBroadcastReceiver.IabBroadcastListener {

IabHelper mHelper;

// Provides purchase notification while this app is running
IabBroadcastReceiver mBroadcastReceiver;

...


// Listener that's called when we finish querying the items and subscriptions we own
IabHelper.QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener() {
    public void onQueryInventoryFinished(IabResult result, Inventory inventory) {
        Log.d("IAB", "Query inventory finished.");

        if (mHelper == null) return;

        if (result.isFailure()) {
            Log.d("IAB", "Failed to query inventory: " + result);
            return;
        }

        if (inventory.getSkuDetails(SKU_MONTHLY_TTS) != null
                && inventory.getSkuDetails(SKU_YEARLY_TTS) != null) {
            ...
          }


        Log.d("IAB", "Query inventory was successful.");

        /*
         * Check for items we own. Notice that for each purchase, we check
         * the developer payload to see if it's correct! See
         * verifyDeveloperPayload().
         */

        ...

        Log.d("IAB", "Initial inventory query finished; enabling main UI.");
    }
};
// Callback for when a purchase is finished
IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() {
    public void onIabPurchaseFinished(IabResult result, Purchase purchase) {
        Log.d("IAB", "Purchase finished: " + result + ", purchase: " + purchase);

        // if we were disposed of in the meantime, quit.
        if (mHelper == null) return;

        if (result.isFailure()) {
            Log.d("IAB", "Error purchasing: " + result);
            return;
        }
        if (!verifyDeveloperPayload(purchase)) {
            Log.d("IAB", "Error purchasing. Authenticity verification failed.");
            return;
        }

        Log.d("IAB", "Purchase successful.");

        ...
    }
};


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_subscription);


    mHelper = new IabHelper(this, compiledKy);

    mHelper.enableDebugLogging(true);

    mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
        @Override
        public void onIabSetupFinished(IabResult result) {
            Log.d("Subscription", "InSetUpFinished: " + result);
            if (!result.isSuccess()) {
                Log.d("Subscription", "Problem setting up In-app Billing: " + result);
                return;
            }

            if (mHelper == null) return;

            // Important: Dynamically register for broadcast messages about updated purchases.
            // We register the receiver here instead of as a <receiver> in the Manifest
            // because we always call getPurchases() at startup, so therefore we can ignore
            // any broadcasts sent while the app isn't running.
            // Note: registering this listener in an Activity is a bad idea, but is done here
            // because this is a SAMPLE. Regardless, the receiver must be registered after
            // IabHelper is setup, but before first call to getPurchases().
            mBroadcastReceiver = new IabBroadcastReceiver(Subscription.this);
            IntentFilter broadcastFilter = new IntentFilter(IabBroadcastReceiver.ACTION);
            registerReceiver(mBroadcastReceiver, broadcastFilter);

            // IAB is fully set up. Now, let's get an inventory of stuff we own.
            Log.d("IAB", "Setup successful. Querying inventory.");
            try {
                List<String> additionalSkuList = new ArrayList<String>();
                ...
                mHelper.queryInventoryAsync(true, null, additionalSkuList, mGotInventoryListener);
            } catch (IabHelper.IabAsyncInProgressException e) {
                Log.d("IAB", "Error querying inventory. Another async operation in progress.");
            }
        }
    });

    Button monthlySubButton = (Button) findViewById(R.id.monthlySubButton);
    monthlySubButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            if (!mHelper.subscriptionsSupported()) {
                Log.d("IAB","Subscriptions not supported on your device yet. Sorry!");
                return;
            }
            try {
                ...
                mHelper.launchPurchaseFlow(Subscription.this, ..., IabHelper.ITEM_TYPE_SUBS,
                        oldSku, 10001, mPurchaseFinishedListener, "");
            } catch (IabHelper.IabAsyncInProgressException e) {
                Log.d("IAB", e.getMessage());
            }
        }
    });

    ...
}

/** Verifies the developer payload of a purchase. */
boolean verifyDeveloperPayload(Purchase p) {
    String payload = p.getDeveloperPayload();

    ...
    return true;
}

@Override
protected void onDestroy() {
    super.onDestroy();

    if (mBroadcastReceiver != null) {
        unregisterReceiver(mBroadcastReceiver);
    }

    Log.d("IAB", "Destroying helper.");
    if (mHelper != null) {
        mHelper.disposeWhenFinished();
        mHelper = null;
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    Log.d("IAB", "onActivityResult(" + requestCode + "," + resultCode + "," + data);
    if (mHelper == null) return;

    if (!mHelper.handleActivityResult(requestCode, resultCode, data)) {
        super.onActivityResult(requestCode, resultCode, data);
    }
    else {
        Log.d("IAB", "onActivityResult handled by IABUtil.");
    }
}

@Override
public void receivedBroadcast() {
    // Received a broadcast notification that the inventory of items has changed
    Log.d("IAB", "Received broadcast notification. Querying inventory.");
    try {
        mHelper.queryInventoryAsync(mGotInventoryListener);
    } catch (IabHelper.IabAsyncInProgressException e) {
        Log.d("IAB", "Error querying inventory. Another async operation in progress.");
    }
}
}

我试图在清单中添加一个接收器,但是它给了我一个错误:

代码语言:javascript
运行
复制
</application>
...
<activity
        android:name=".controller.Subscription"
        android:label="Subscription"
        android:parentActivityName=".controller.MainActivity">
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value=".controller.MainActivity" />
    </activity>

    <receiver android:name=".controller.Subscription"  android:exported="true">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED"/>
            <action android:name="android.intent.action.INPUT_METHOD_CHANGED" />
        </intent-filter>
    </receiver>
</application>

Error Message:.controller.Subscription is not assignable to 'android.content.BroadcastReceiver'

Subscription类位于正确的目录中(在控制器包下)。我的Subscription类是否必须扩展IabBroadcastReceiver类而不是实现IabBroadcastReceiver.IabBroadcastListener?我仍然想扩展AppCompactActivity,我想知道是否有任何方法解决这个问题。似乎没有在线示例显示如何使用在清单中注册的广播接收器来实现inApp计费api。谢谢你提前提供帮助!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-08-20 15:40:59

controller.Subscription不能分配给“android.content.BroadcastReceiver”

这意味着,Subscription不是BroadcastReceiver的后代。您已经将清单中的Subscription注册为receiver,但实际上它不是BroadcastReceiver的子类。

我的Subscription类是否必须扩展IabBroadcastReceiver类而不是实现IabBroadcastReceiver.IabBroadcastListener

为了将类注册为清单中的receiver,类应该是BroadcastReceiver的后代(直接或间接)。因此,Subscription应该是extends BroadcastReceiver还是extends IabBroadcastReceiver

我仍然想扩展AppCompactActivity.

您不能使一个类同时进行活动和接收(Java中不支持多重继承)。

您仍然可以通过清单将IabBroadcastReceiver注册为<receiver>。但我不知道这背后的理由是什么?显然,当应用程序处于不活动状态时,您永远不会收到任何广播,因为您应该在应用程序中启动购买流程,这就是为什么动态注册和取消注册BroadcastReceiver更有意义。请注意,通过清单注册接收者将使您接收从其他应用程序购买的广播,这是您最可能不感兴趣的。

请参阅文档

不要在应用程序清单中注册这个广播接收器。在清单中声明接收者可能会导致系统启动应用程序,以处理在应用程序未运行时用户进行购买的意图。这种行为是不必要的,可能会使用户感到厌烦。要了解用户在应用程序未运行时所做的任何购买,请在用户启动应用程序时打电话给getPurchases()。

票数 1
EN

Stack Overflow用户

发布于 2017-08-15 03:58:12

这通常是因为您在\控制器\包下没有订阅类。在您的代码中,一切看起来都很好(假设您在清单中添加了相应的intentfilter)。因此,请确保您的订阅类位于正确的包(或文件夹)中。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45686172

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档